docstr: Checks that the position of a triangle can be optimized correctly.
  
  The optimization target is a translated version of the same triangle.
  Naive rasterization produces zero gradient in this case, but
  rasterize-then-splat produces a useful gradient.
docstr_tok: ["Checks","that","the","position","of","a","triangle","can","be","optimized","correctly",".","The","optimization","target","is","a","translated","version","of","the","same","triangle",".","Naive","rasterization","produces","zero","gradient","in","this","case",",","but","rasterize-then-splat","produces","a","useful","gradient","."]
code: def test_optimize_single_triangle(self):
      """Checks that the position of a triangle can be optimized correctly.
  
      The optimization target is a translated version of the same triangle.
      Naive rasterization produces zero gradient in this case, but
      rasterize-then-splat produces a useful gradient.
      """
      image_width = 32
      image_height = 32
  
      initial_vertices = tf.constant(
          [[[0, 0, 0], [0.5, 0, 0], [0.5, 0.5, 0]]], dtype=tf.float32
      )
      target_vertices = tf.constant(
          [[[-0.25, 0, 0], [0.25, 0, 0], [0.25, 0.5, 0]]],
          dtype=tf.float32,
      )
      triangles = [[0, 1, 2]]
      colors = tf.constant(
          [[[0, 0.8, 0, 1.0], [0, 0.8, 0, 1.0], [0, 0.8, 0, 1.0]]],
          dtype=tf.float32,
      )
      camera_matrix = (
          rasterization_test_utils.get_identity_view_projection_matrix()
      )
  
      @tf.function
      def render_splat(verts):
          return splat.rasterize_then_splat(
              verts,
              triangles,
              {"color": colors},
              camera_matrix,
              (image_height, image_width),
              lambda x: x["color"],
              num_layers=1,
              backend=self._backend,
          )
  
      # Perform a few iterations of gradient descent.
      num_iters = 15
      var_verts = tf.Variable(initial_vertices)
      splat_loss_initial = tf.convert_to_tensor(0.0)
      for i in range(num_iters):
          with tf.GradientTape(persistent=True) as g:
              target_image = rasterize_image(
                  target_vertices,
                  triangles,
                  colors,
                  camera_matrix,
                  image_width,
                  image_height,
                  self._backend,
              )[0, ...]
              rasterized_only_image = rasterize_image(
                  var_verts,
                  triangles,
                  colors,
                  camera_matrix,
                  image_width,
                  image_height,
                  self._backend,
              )[0, ...]
              splat_image = render_splat(var_verts)
  
              rasterized_loss = tf.reduce_mean(
                  (rasterized_only_image - target_image) ** 2
              )
              splat_loss = tf.reduce_mean(
                  (splat_image - target_image) ** 2
              )
  
          rasterized_grad = g.gradient(rasterized_loss, var_verts)
          splat_grad = g.gradient(splat_loss, var_verts)
  
          if i == 0:
              # Check that the rasterized-only gradient is zero, while the
              # rasterize-then-splat gradient is non-zero.
              self.assertAlmostEqual(
                  tf.norm(rasterized_grad).numpy(), 0.0
              )
              self.assertGreater(tf.norm(splat_grad).numpy(), 0.01)
              splat_loss_initial = splat_loss
  
          # Apply the gradient.
          var_verts.assign_sub(splat_grad)
  
      # Check that gradient descent reduces the loss by at least 50%.
      opt_image = render_splat(var_verts)
      opt_loss = tf.reduce_mean((opt_image - target_image) ** 2)
      self.assertLess(
          opt_loss.numpy(), splat_loss_initial.numpy() * 0.5
      )
  
file_path: graphics/tensorflow_graphics/rendering/tests/splat_test.py
imports: from absl.testing import parameterized
  import tensorflow
  from tensorflow_graphics.rendering import rasterization_backend
  from tensorflow_graphics.rendering import splat
  from tensorflow_graphics.rendering import triangle_rasterizer
  from tensorflow_graphics.rendering.tests import rasterization_test_utils
  from tensorflow_graphics.util import test_case
label_desc: Use image node_id 5 for calling the SplatTest obj's underlying member method code with example usage: obj.test_optimize_single_triangle() and returns: splat