class_docstr: A class for rendering a batch of points. The class should
  be initialized with a rasterizer and compositor class which each have a forward
  function.
  
  The points are rendered with with varying alpha (weights) values depending on
  the distance of the pixel center to the true point in the xy plane. The purpose
  of this is to soften the hard decision boundary, for differentiability.
  See Section 3.2 of "SynSin: End-to-end View Synthesis from a Single Image"
  (https://arxiv.org/pdf/1912.08804.pdf) for more details.
code: def forward(self, point_clouds, **kwargs) -> torch.Tensor:
      fragments = self.rasterizer(point_clouds, **kwargs)
  
      # Construct weights based on the distance of a point to the true point.
      # However, this could be done differently: e.g. predicted as opposed
      # to a function of the weights.
      r = self.rasterizer.raster_settings.radius
  
      dists2 = fragments.dists.permute(0, 3, 1, 2)
      weights = 1 - dists2 / (r * r)
      images = self.compositor(
          fragments.idx.long().permute(0, 3, 1, 2),
          weights,
          point_clouds.features_packed().permute(1, 0),
          **kwargs,
      )
  
      # permute so image comes at the end
      images = images.permute(0, 2, 3, 1)
  
      return images
  
imports: import torch
  import torch.nn
label_desc: Use image node_id 3 for calling the PointsRenderer obj's underlying member method code with example usage: obj.forward(point_clouds) and returns: images