code: def rasterize(
      vertices: type_alias.TensorLike,
      triangles: type_alias.TensorLike,
      view_projection_matrices: type_alias.TensorLike,
      image_size: Tuple[int, int],
      enable_cull_face: bool,
      num_layers: int,
      name: str = "rasterization_backend_rasterize",
  ) -> fb.Framebuffer:
      """Rasterizes the scene.
  
        This rasterizer estimates which triangle is associated with each pixel using
        OpenGL.
  
      Note:
        In the following, A1 to An are optional batch dimensions which must be
        broadcast compatible for inputs `vertices` and `view_projection_matrices`.
  
      Args:
        vertices: A tensor of shape `[batch, num_vertices, 3]` containing batches
          vertices, each defined by a 3D point.
        triangles: A tensor of shape `[num_triangles, 3]` each associated with 3
          vertices from `scene_vertices`
        view_projection_matrices: A tensor of shape `[batch, 4, 4]` containing
          batches of view projection matrices
        image_size: An tuple of integers (width, height) containing the dimensions
          in pixels of the rasterized image.
        enable_cull_face: A boolean, which will enable BACK face culling when True
          and no face culling when False. Default is True.
        num_layers: Number of depth layers to render. Not supported by current
          backend yet, but exists for interface compatibility.
        name: A name for this op. Defaults to "rasterization_backend_rasterize".
  
      Returns:
        A Framebuffer containing the rasterized values: barycentrics, triangle_id,
        foreground_mask, vertex_ids. Returned Tensors have shape
        [batch, num_layers, height, width, channels]
        Note: triangle_id contains the triangle id value for each pixel in the
        output image. For pixels within the mesh, this is the integer value in the
        range [0, num_vertices] from triangles. For vertices outside the mesh this
        is 0; 0 can either indicate belonging to triangle 0, or being outside the
        mesh. This ensures all returned triangle ids will validly index into the
        vertex array, enabling the use of tf.gather with indices from this tensor.
        The barycentric coordinates can be used to determine pixel validity instead.
        See framebuffer.py for a description of the Framebuffer fields.
      """
      with tf.name_scope(name):
          if num_layers != 1:
              raise ValueError(
                  "OpenGL rasterizer only supports single layer."
              )
  
          vertices = tf.convert_to_tensor(value=vertices)
          triangles = tf.convert_to_tensor(value=triangles)
          view_projection_matrices = tf.convert_to_tensor(
              value=view_projection_matrices
          )
  
          shape.check_static(
              tensor=vertices,
              tensor_name="vertices",
              has_rank=3,
              has_dim_equals=((-1, 3)),
          )
          shape.check_static(
              tensor=triangles,
              tensor_name="triangles",
              has_rank=2,
              has_dim_equals=((-1, 3)),
          )
          shape.check_static(
              tensor=view_projection_matrices,
              tensor_name="view_projection_matrices",
              has_rank=3,
              has_dim_equals=((-1, 4), (-2, 4)),
          )
          shape.compare_batch_dimensions(
              tensors=(vertices, view_projection_matrices),
              tensor_names=("vertices", "view_projection_matrices"),
              last_axes=(-3, -3),
              broadcast_compatible=True,
          )
  
          geometry = tf.gather(vertices, triangles, axis=-2)
  
          # Extract batch size in order to make sure it is preserved after `gather`
          # operation.
          batch_size = _dim_value(vertices.shape[0])
  
          rasterized = render_ops.rasterize(
              num_points=geometry.shape[-3],
              alpha_clear=0.0,
              enable_cull_face=enable_cull_face,
              variable_names=(
                  "view_projection_matrix",
                  "triangular_mesh",
              ),
              variable_kinds=("mat", "buffer"),
              variable_values=(
                  view_projection_matrices,
                  tf.reshape(geometry, shape=[batch_size, -1]),
              ),
              output_resolution=image_size,
              vertex_shader=vertex_shader,
              geometry_shader=geometry_shader,
              fragment_shader=fragment_shader,
          )
  
          triangle_index = tf.cast(rasterized[..., 0], tf.int32)
          # Slicing of the tensor will result in all batch dimensions being
          # `None` for tensorflow graph mode, therefore we have to fix it in order to
          # have explicit shape.
          width, height = image_size
          triangle_index = tf.reshape(
              triangle_index, [batch_size, num_layers, height, width, 1]
          )
          barycentric_coordinates = rasterized[..., 1:3]
          barycentric_coordinates = tf.concat(
              (
                  barycentric_coordinates,
                  1.0
                  - barycentric_coordinates[..., 0:1]
                  - barycentric_coordinates[..., 1:2],
              ),
              axis=-1,
          )
          barycentric_coordinates = tf.reshape(
              barycentric_coordinates,
              [batch_size, num_layers, height, width, 3],
          )
          mask = rasterized[..., 3]
          mask = tf.reshape(
              mask, [batch_size, num_layers, height, width, 1]
          )
  
          barycentric_coordinates = mask * barycentric_coordinates
          vertex_ids = tf.gather(triangles, triangle_index[..., 0])
  
          # Stop gradient for tensors coming out of custom op in order to avoid
          # confusing Tensorflow that they are differentiable.
          barycentric_coordinates = tf.stop_gradient(
              barycentric_coordinates
          )
          mask = tf.stop_gradient(mask)
          return fb.Framebuffer(
              foreground_mask=mask,
              triangle_id=triangle_index,
              vertex_ids=vertex_ids,
              barycentrics=fb.RasterizedAttribute(
                  value=barycentric_coordinates, d_dx=None, d_dy=None
              ),
          )
  
imports: from typing import Optional, Tuple
  import tensorflow
  from tensorflow_graphics.rendering import framebuffer
  from tensorflow_graphics.util import export_api
  from tensorflow_graphics.util import shape
  from tensorflow_graphics.util import type_alias
label_desc: Use image node_id 2 for calling a global function with example usage: rasterize(vertices, triangles, view_projection_matrices, image_size, enable_cull_face, num_layers, name) and returns: fb