class_docstr: A simple scene model to demonstrate use of pulsar in PyTorch modules.
  
  The scene model is parameterized with sphere locations (vert_pos),
  channel content (vert_col), radiuses (vert_rad), camera position (cam_pos),
  camera rotation (cam_rot) and sensor focal length and width (cam_sensor).
  
  The forward method of the model renders this scene description. Any
  of these parameters could instead be passed as inputs to the forward
  method and come from a different model.
class_docstr_tok: ["A","simple","scene","model","to","demonstrate","use","of","pulsar","in","PyTorch","modules",".","The","scene","model","is","parameterized","with","sphere","locations","(","vert_pos",")",",","channel","content","(","vert_col",")",",","radiuses","(","vert_rad",")",",","camera","position","(","cam_pos",")",",","camera","rotation","(","cam_rot",")","and","sensor","focal","length","and","width","(","cam_sensor",")",".","The","forward","method","of","the","model","renders","this","scene","description",".","Any","of","these","parameters","could","instead","be","passed","as","inputs","to","the","forward","method","and","come","from","a","different","model","."]
code: def __init__(self):
      super(SceneModel, self).__init__()
      self.gamma = 0.1
      # Points.
      torch.manual_seed(1)
      vert_pos = torch.rand(N_POINTS, 3, dtype=torch.float32) * 10.0
      vert_pos[:, 2] += 25.0
      vert_pos[:, :2] -= 5.0
      self.register_parameter(
          "vert_pos", nn.Parameter(vert_pos, requires_grad=False)
      )
      self.register_parameter(
          "vert_col",
          nn.Parameter(
              torch.rand(N_POINTS, 3, dtype=torch.float32),
              requires_grad=False,
          ),
      )
      self.register_parameter(
          "vert_rad",
          nn.Parameter(
              torch.rand(N_POINTS, dtype=torch.float32),
              requires_grad=False,
          ),
      )
      self.register_parameter(
          "cam_pos",
          nn.Parameter(
              torch.tensor([0.1, 0.1, 0.0], dtype=torch.float32),
              requires_grad=True,
          ),
      )
      self.register_parameter(
          "cam_rot",
          # We're using the 6D rot. representation for better gradients.
          nn.Parameter(
              axis_angle_to_matrix(
                  torch.tensor(
                      [
                          [0.02, 0.02, 0.01],
                      ],
                      dtype=torch.float32,
                  )
              )[0],
              requires_grad=True,
          ),
      )
      self.register_parameter(
          "focal_length",
          nn.Parameter(
              torch.tensor(
                  [
                      4.8 * 2.0 / 2.0,
                  ],
                  dtype=torch.float32,
              ),
              requires_grad=True,
          ),
      )
      self.cameras = PerspectiveCameras(
          # The focal length must be double the size for PyTorch3D because of the NDC
          # coordinates spanning a range of two - and they must be normalized by the
          # sensor width (see the pulsar example). This means we need here
          # 5.0 * 2.0 / 2.0 to get the equivalent results as in pulsar.
          #
          # R, T and f are provided here, but will be provided again
          # at every call to the forward method. The reason are problems
          # with PyTorch which makes device placement for gradients problematic
          # for tensors which are themselves on a 'gradient path' but not
          # leafs in the calculation tree. This will be addressed by an architectural
          # change in PyTorch3D in the future. Until then, this workaround is
          # recommended.
          focal_length=self.focal_length,
          R=self.cam_rot[None, ...],
          T=self.cam_pos[None, ...],
          image_size=((HEIGHT, WIDTH),),
          device=DEVICE,
      )
      raster_settings = PointsRasterizationSettings(
          image_size=(HEIGHT, WIDTH),
          radius=self.vert_rad,
      )
      rasterizer = PointsRasterizer(
          cameras=self.cameras, raster_settings=raster_settings
      )
      self.renderer = PulsarPointsRenderer(rasterizer=rasterizer)
  
file_path: pytorch3d/docs/examples/pulsar_cam_unified.py
imports: import logging
  from os import path
  import cv2
  import imageio
  import numpy
  import torch
  from pytorch3d.renderer.cameras import PerspectiveCameras
  from pytorch3d.renderer.points import PointsRasterizationSettings, PointsRasterizer, PulsarPointsRenderer
  from pytorch3d.structures.pointclouds import Pointclouds
  from pytorch3d.transforms import axis_angle_to_matrix
  from torch import nn, optim
label_desc: Use image node_id 1 to create a new SceneModel object from inherited base classes: nn with example: obj = SceneModel()