예제 #1
0
  def test_look_at_right_handed_preset(self):
    """Tests that look_at_right_handed generates expected results.."""
    camera_position = ((0.0, 0.0, 0.0), (0.1, 0.2, 0.3))
    look_at = ((0.0, 0.0, 1.0), (0.4, 0.5, 0.6))
    up_vector = ((0.0, 1.0, 0.0), (0.7, 0.8, 0.9))

    pred = glm.look_at_right_handed(camera_position, look_at, up_vector)

    gt = (((-1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, -1.0, 0.0),
           (0.0, 0.0, 0.0, 1.0)),
          ((4.08248186e-01, -8.16496551e-01, 4.08248395e-01, -2.98023224e-08),
           (-7.07106888e-01, 1.19209290e-07, 7.07106769e-01, -1.41421378e-01),
           (-5.77350318e-01, -5.77350318e-01, -5.77350318e-01,
            3.46410215e-01), (0.0, 0.0, 0.0, 1.0)))
    self.assertAllClose(pred, gt)
예제 #2
0
    def test_rasterize(self):
        height = 500
        width = 500
        camera_origin = (0.0, 0.0, 0.0)
        camera_up = (0.0, 1.0, 0.0)
        look_at = (0.0, 0.0, 1.0)
        fov = (60.0 * np.math.pi / 180, )
        near_plane = (1.0, )
        far_plane = (10.0, )

        world_to_camera = glm.look_at_right_handed(camera_origin, look_at,
                                                   camera_up)
        perspective_matrix = glm.perspective_right_handed(
            fov, (float(width) / float(height), ), near_plane, far_plane)
        view_projection_matrix = tf.matmul(perspective_matrix, world_to_camera)
        view_projection_matrix = tf.squeeze(view_projection_matrix)

        for depth in range(2, 5):
            tris = np.array([[-10.0, 10.0, depth], [10.0, 10.0, depth],
                             [0.0, -10.0, depth]],
                            dtype=np.float32)
            tris_tf = tf.reshape(tris, [-1])

            render_parameters = {
                "view_projection_matrix": ("mat", view_projection_matrix),
                "triangular_mesh": ("buffer", tris_tf)
            }

            render_parameters = list(six.iteritems(render_parameters))
            variable_names = [v[0] for v in render_parameters]
            variable_kinds = [v[1][0] for v in render_parameters]
            variable_values = [v[1][1] for v in render_parameters]

            result = rasterizer.rasterize(
                num_points=tris.shape[0],
                variable_names=variable_names,
                variable_kinds=variable_kinds,
                variable_values=variable_values,
                output_resolution=(width, height),
                vertex_shader=test_vertex_shader,
                geometry_shader=test_geometry_shader,
                fragment_shader=test_fragment_shader,
            )

            gt = np.tile((0, depth), (width, height, 1))
            self.assertAllClose(result[..., 2:4], gt)
  def test_rasterize(self):
    max_depth = 10
    min_depth = 2
    height = 480
    width = 640
    camera_origin = (0.0, 0.0, 0.0)
    camera_up = (0.0, 1.0, 0.0)
    look_at = (0.0, 0.0, 1.0)
    fov = (60.0 * np.math.pi / 180,)
    near_plane = (1.0,)
    far_plane = (10.0,)
    batch_shape = tf.convert_to_tensor(
        value=(2, (max_depth - min_depth) // 2), dtype=tf.int32)

    world_to_camera = glm.look_at_right_handed(camera_origin, look_at,
                                               camera_up)
    perspective_matrix = glm.perspective_right_handed(
        fov, (float(width) / float(height),), near_plane, far_plane)
    view_projection_matrix = tf.matmul(perspective_matrix, world_to_camera)
    view_projection_matrix = tf.squeeze(view_projection_matrix)

    # Generate triangles at different depths and associated ground truth.
    tris = np.zeros((max_depth - min_depth, 9), dtype=np.float32)
    gt = np.zeros((max_depth - min_depth, width, height, 2), dtype=np.float32)
    for idx in range(max_depth - min_depth):
      tris[idx, :] = (-100.0, 100.0, idx + min_depth, 100.0, 100.0,
                      idx + min_depth, 0.0, -100.0, idx + min_depth)
      gt[idx, :, :, :] = (0, idx + min_depth)

    # Broadcast the variables.
    render_parameters = {
        "view_projection_matrix":
            ("mat",
             tf.broadcast_to(
                 input=view_projection_matrix,
                 shape=tf.concat(
                     values=(batch_shape,
                             tf.shape(input=view_projection_matrix)[-2:]),
                     axis=0))),
        "triangular_mesh":
            ("buffer",
             tf.reshape(
                 tris, shape=tf.concat(values=(batch_shape, (9,)), axis=0)))
    }
    # Reshape the ground truth.
    gt = tf.reshape(
        gt, shape=tf.concat(values=(batch_shape, (height, width, 2)), axis=0))

    render_parameters = list(six.iteritems(render_parameters))
    variable_names = [v[0] for v in render_parameters]
    variable_kinds = [v[1][0] for v in render_parameters]
    variable_values = [v[1][1] for v in render_parameters]

    def rasterize():
      return rasterizer.rasterize(
          num_points=3,
          variable_names=variable_names,
          variable_kinds=variable_kinds,
          variable_values=variable_values,
          output_resolution=(width, height),
          vertex_shader=test_vertex_shader,
          geometry_shader=test_geometry_shader,
          fragment_shader=test_fragment_shader,
      )

    result = rasterize()
    self.assertAllClose(result[..., 2:4], gt)

    @tf.function
    def check_lazy_shape():
      # Within @tf.function, the tensor shape is determined by SetShapeFn
      # callback. Ensure that the shape of non-batch axes matches that of of
      # the actual tensor evaluated in eager mode above.
      lazy_shape = rasterize().shape
      self.assertEqual(lazy_shape[-3:], list(result.shape)[-3:])

    check_lazy_shape()
예제 #4
0
  def __init__(self,
               background_vertices,
               background_attributes,
               background_triangles,
               camera_origin,
               look_at,
               camera_up,
               field_of_view,
               image_size,
               near_plane,
               far_plane,
               bottom_left=(0.0, 0.0),
               name=None):
    """Initializes TriangleRasterizer with OpenGL parameters and the background.

    Note:
      In the following, A1 to An are optional batch dimensions.

    Args:
      background_vertices: A tensor of shape `[V, 3]` containing `V` 3D
        vertices. Note that these background vertices will be used in every
        rasterized image.
      background_attributes: A tensor of shape `[V, K]` containing `V` vertices
        associated with K-dimensional attributes. Pixels for which the first
        visible surface is in the background geometry will make use of
        `background_attribute` for estimating their own attribute. Note that
        these background attributes will be use in every rasterized image.
      background_triangles: An integer tensor of shape `[T, 3]` containing `T`
        triangles, each associated with 3 vertices from `background_vertices`.
        Note that these background triangles will be used in every rasterized
        image.
      camera_origin: A Tensor of shape `[A1, ..., An, 3]`, where the last axis
        represents the 3D position of the camera.
      look_at: A Tensor of shape `[A1, ..., An, 3]`, with the last axis storing
        the position where the camera is looking at.
      camera_up: A Tensor of shape `[A1, ..., An, 3]`, where the last axis
        defines the up vector of the camera.
      field_of_view:  A Tensor of shape `[A1, ..., An, 1]`, where the last axis
        represents the vertical field of view of the frustum expressed in
        radians. Note that values for `field_of_view` must be in the range (0,
        pi).
      image_size: A tuple (height, width) containing the dimensions in pixels of
        the rasterized image".
      near_plane: A Tensor of shape `[A1, ..., An, 1]`, where the last axis
        captures the distance between the viewer and the near clipping plane.
        Note that values for `near_plane` must be non-negative.
      far_plane: A Tensor of shape `[A1, ..., An, 1]`, where the last axis
        captures the distance between the viewer and the far clipping plane.
        Note that values for `far_plane` must be non-negative.
      bottom_left: A Tensor of shape `[A1, ..., An, 2]`, where the last axis
        captures the position (in pixels) of the lower left corner of the
        screen. Defaults to (0.0, 0.0).
        name: A name for this op. Defaults to 'triangle_rasterizer_init'.
    """
    with tf.compat.v1.name_scope(
        name, "triangle_rasterizer_init",
        (background_vertices, background_attributes, background_triangles,
         camera_origin, look_at, camera_up, field_of_view, near_plane,
         far_plane, bottom_left)):

      background_vertices = tf.convert_to_tensor(value=background_vertices)
      background_attributes = tf.convert_to_tensor(value=background_attributes)
      background_triangles = tf.convert_to_tensor(value=background_triangles)

      shape.check_static(
          tensor=background_vertices,
          tensor_name="background_vertices",
          has_rank=2,
          has_dim_equals=(-1, 3))
      shape.check_static(
          tensor=background_attributes,
          tensor_name="background_attributes",
          has_rank=2)
      shape.check_static(
          tensor=background_triangles,
          tensor_name="background_triangles",
          # has_rank=2,
          has_dim_equals=(-1, 3))
      shape.compare_batch_dimensions(
          tensors=(background_vertices, background_attributes),
          last_axes=-2,
          tensor_names=("background_geometry", "background_attribute"),
          broadcast_compatible=False)

      background_vertices = tf.expand_dims(background_vertices, axis=0)
      background_attributes = tf.expand_dims(background_attributes, axis=0)

      height = float(image_size[0])
      width = float(image_size[1])

      self._background_geometry = tf.gather(
          background_vertices, background_triangles, axis=-2)
      self._background_attribute = tf.gather(
          background_attributes, background_triangles, axis=-2)

      self._camera_origin = tf.convert_to_tensor(value=camera_origin)
      self._look_at = tf.convert_to_tensor(value=look_at)
      self._camera_up = tf.convert_to_tensor(value=camera_up)
      self._field_of_view = tf.convert_to_tensor(value=field_of_view)
      self._image_size_glm = tf.convert_to_tensor(value=(width, height))
      self._image_size_int = (int(width), int(height))
      self._near_plane = tf.convert_to_tensor(value=near_plane)
      self._far_plane = tf.convert_to_tensor(value=far_plane)
      self._bottom_left = tf.convert_to_tensor(value=bottom_left)

      # Construct the pixel grid. Note that OpenGL uses half-integer pixel
      # centers.
      px = tf.linspace(0.5, width - 0.5, num=int(width))
      py = tf.linspace(0.5, height - 0.5, num=int(height))
      xv, yv = tf.meshgrid(px, py)
      self._pixel_position = tf.stack((xv, yv), axis=-1)

      # Construct the view projection matrix.
      world_to_camera = glm.look_at_right_handed(camera_origin, look_at,
                                                 camera_up)
      perspective_matrix = glm.perspective_right_handed(field_of_view,
                                                        (width / height,),
                                                        near_plane, far_plane)
      perspective_matrix = tf.squeeze(perspective_matrix)
      self._view_projection_matrix = tf.linalg.matmul(perspective_matrix,
                                                      world_to_camera)