code: def model_to_screen(
      point_model_space: type_alias.TensorLike,
      model_to_eye_matrix: type_alias.TensorLike,
      perspective_matrix: type_alias.TensorLike,
      screen_dimensions: type_alias.TensorLike,
      lower_left_corner: type_alias.TensorLike = (0.0, 0.0),
      name: str = "model_to_screen",
  ) -> Tuple[tf.Tensor, tf.Tensor]:
      """Transforms points from model to screen coordinates.
  
      Note:
        Please refer to http://www.songho.ca/opengl/gl_transform.html for an
        in-depth review of this pipeline.
  
      Note:
        In the following, A1 to An are optional batch dimensions which must be
        broadcast compatible.
  
      Args:
        point_model_space: A tensor of shape `[A1, ..., An, 3]`, where the last
          dimension represents the 3D points in model space.
        model_to_eye_matrix: A tensor of shape `[A1, ..., An, 4, 4]`, where the last
          two dimension represent matrices to transform points from model to eye
          coordinates.
        perspective_matrix: A tensor of shape `[A1, ..., An, 4, 4]`, where the last
          two dimension represent matrices to transform points from eye to clip
          coordinates.
        screen_dimensions: A tensor of shape `[A1, ..., An, 2]`, where the last
          dimension is expressed in pixels and captures the width and the height (in
          pixels) of the screen.
        lower_left_corner: A tensor of shape `[A1, ..., An, 2]`, where the last
          dimension captures the position (in pixels) of the lower left corner of
          the screen.
        name: A name for this op. Defaults to "model_to_screen".
  
      Raises:
        InvalidArgumentError: if any input contains data not in the specified range
          of valid values.
        ValueError: If any input is of an unsupported shape.
  
      Returns:
        A tuple of two tensors, respectively of shape `[A1, ..., An, 3]` and
        `[A1, ..., An, 1]`, where the first tensor containing the projection of
        `point_model_space` in screen coordinates, and the second represents the 'w'
        component of `point_model_space` in clip space.
      """
      with tf.name_scope(name):
          point_model_space = tf.convert_to_tensor(
              value=point_model_space
          )
          model_to_eye_matrix = tf.convert_to_tensor(
              value=model_to_eye_matrix
          )
          perspective_matrix = tf.convert_to_tensor(
              value=perspective_matrix
          )
  
          shape.check_static(
              tensor=point_model_space,
              tensor_name="point_model_space",
              has_dim_equals=(-1, 3),
          )
          shape.check_static(
              tensor=model_to_eye_matrix,
              tensor_name="model_to_eye_matrix",
              has_dim_equals=((-1, 4), (-2, 4)),
          )
          shape.check_static(
              tensor=perspective_matrix,
              tensor_name="perspective_matrix",
              has_dim_equals=((-1, 4), (-2, 4)),
          )
          shape.compare_batch_dimensions(
              tensors=(
                  point_model_space,
                  model_to_eye_matrix,
                  perspective_matrix,
              ),
              last_axes=(-2, -3, -3),
              tensor_names=(
                  "point_model_space",
                  "model_to_eye_matrix",
                  "perspective_matrix",
              ),
              broadcast_compatible=True,
          )
  
          batch_shape = tf.shape(input=point_model_space)[:-1]
          one = tf.ones(
              shape=tf.concat((batch_shape, (1,)), axis=-1),
              dtype=point_model_space.dtype,
          )
          point_model_space = tf.concat(
              (point_model_space, one), axis=-1
          )
          point_model_space = tf.expand_dims(point_model_space, axis=-1)
  
          view_projection_matrix = tf.linalg.matmul(
              perspective_matrix, model_to_eye_matrix
          )
  
          _, _, near, far = perspective.parameters_from_right_handed(
              perspective_matrix
          )
  
          point_clip_space = tf.squeeze(
              tf.matmul(view_projection_matrix, point_model_space),
              axis=-1,
          )
          point_ndc_space = clip_to_ndc(point_clip_space)
          point_screen_space = ndc_to_screen(
              point_ndc_space,
              lower_left_corner,
              screen_dimensions,
              near,
              far,
          )
          return point_screen_space, point_clip_space[..., 3:4]
  
file_path: graphics/tensorflow_graphics/rendering/opengl/math.py
imports: from typing import Tuple
  import tensorflow
  from tensorflow_graphics.geometry.transformation import look_at
  from tensorflow_graphics.math.interpolation import weighted
  from tensorflow_graphics.rendering.camera import perspective
  from tensorflow_graphics.util import asserts
  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 5 for calling a global function with example usage: model_to_screen(point_model_space, model_to_eye_matrix, perspective_matrix, screen_dimensions, lower_left_corner, name) and returns: point_screen_space,  point_clip_space