(normals,
                 alphas,
                 pixel_positions,
                 light_positions,
                 light_intensities,
                 diffuse_colors=None,
                 camera_position=None,
                 specular_colors=None,
                 shininess_coefficients=None,
                 ambient_color=None)
return tf.reverse(tf.concat([rgb_images, alpha_images], axis=3), axis=[1])
Computes pixelwise lighting from rasterized buffers with the Phong model.

  Args:
    normals: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the world space XYZ normal for
        the corresponding pixel. Should be already normalized.
    alphas: a 3D float32 tensor with shape [batch_size, image_height,
        image_width]. The inner dimension is the alpha value (transparency)
        for the corresponding pixel.
    pixel_positions: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the world space XYZ position for
        the corresponding pixel.
    light_positions: a 3D tensor with shape [batch_size, light_count, 3]. The
        XYZ position of each light in the scene. In the same coordinate space as
        pixel_positions.
    light_intensities: a 3D tensor with shape [batch_size, light_count, 3]. The
        RGB intensity values for each light. Intensities may be above one.
    diffuse_colors: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the diffuse RGB coefficients at
        a pixel in the range [0, 1].
    camera_position: a 1D tensor with shape [batch_size, 3]. The XYZ camera
        position in the scene. If supplied, specular reflections will be
        computed. If not supplied, specular_colors and shininess_coefficients
        are expected to be None. In the same coordinate space as
        pixel_positions.
    specular_colors: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the specular RGB coefficients at
        a pixel in the range [0, 1]. If None, assumed to be tf.zeros()
    shininess_coefficients: A 3D float32 tensor that is broadcasted to shape
        [batch_size, image_height, image_width]. The inner dimension is the
        shininess coefficient for the object at a pixel. Dimensions that are
        constant can be given length 1, so [batch_size, 1, 1] and [1, 1, 1] are
        also valid input shapes.
    ambient_color: a 2D tensor with shape [batch_size, 3]. The RGB ambient
        color, which is added to each pixel before tone mapping. If None, it is
        assumed to be tf.zeros().
  Returns:
    A 4D float32 tensor of shape [batch_size, image_height, image_width, 4]
    containing the lit RGBA color values for each image at each pixel. Colors
    are in the range [0,1].

  Raises:
    ValueError: An invalid argument to the method is detected.
Computes pixelwise lighting from rasterized buffers with the Phong model.
Computes pixelwise lighting from rasterized buffers with the Phong model .
def phong_shader(normals,
                 alphas,
                 pixel_positions,
                 light_positions,
                 light_intensities,
                 diffuse_colors=None,
                 camera_position=None,
                 specular_colors=None,
                 shininess_coefficients=None,
                 ambient_color=None):
  """Computes pixelwise lighting from rasterized buffers with the Phong model.

  Args:
    normals: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the world space XYZ normal for
        the corresponding pixel. Should be already normalized.
    alphas: a 3D float32 tensor with shape [batch_size, image_height,
        image_width]. The inner dimension is the alpha value (transparency)
        for the corresponding pixel.
    pixel_positions: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the world space XYZ position for
        the corresponding pixel.
    light_positions: a 3D tensor with shape [batch_size, light_count, 3]. The
        XYZ position of each light in the scene. In the same coordinate space as
        pixel_positions.
    light_intensities: a 3D tensor with shape [batch_size, light_count, 3]. The
        RGB intensity values for each light. Intensities may be above one.
    diffuse_colors: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the diffuse RGB coefficients at
        a pixel in the range [0, 1].
    camera_position: a 1D tensor with shape [batch_size, 3]. The XYZ camera
        position in the scene. If supplied, specular reflections will be
        computed. If not supplied, specular_colors and shininess_coefficients
        are expected to be None. In the same coordinate space as
        pixel_positions.
    specular_colors: a 4D float32 tensor with shape [batch_size, image_height,
        image_width, 3]. The inner dimension is the specular RGB coefficients at
        a pixel in the range [0, 1]. If None, assumed to be tf.zeros()
    shininess_coefficients: A 3D float32 tensor that is broadcasted to shape
        [batch_size, image_height, image_width]. The inner dimension is the
        shininess coefficient for the object at a pixel. Dimensions that are
        constant can be given length 1, so [batch_size, 1, 1] and [1, 1, 1] are
        also valid input shapes.
    ambient_color: a 2D tensor with shape [batch_size, 3]. The RGB ambient
        color, which is added to each pixel before tone mapping. If None, it is
        assumed to be tf.zeros().
  Returns:
    A 4D float32 tensor of shape [batch_size, image_height, image_width, 4]
    containing the lit RGBA color values for each image at each pixel. Colors
    are in the range [0,1].

  Raises:
    ValueError: An invalid argument to the method is detected.
  """
  batch_size, image_height, image_width = [s.value for s in normals.shape[:-1]]
  light_count = light_positions.shape[1].value
  pixel_count = image_height * image_width
  # Reshape all values to easily do pixelwise computations:
  normals = tf.reshape(normals, [batch_size, -1, 3])
  alphas = tf.reshape(alphas, [batch_size, -1, 1])
  diffuse_colors = tf.reshape(diffuse_colors, [batch_size, -1, 3])
  if camera_position is not None:
    specular_colors = tf.reshape(specular_colors, [batch_size, -1, 3])

  # Ambient component
  output_colors = tf.zeros([batch_size, image_height * image_width, 3])
  if ambient_color is not None:
    ambient_reshaped = tf.expand_dims(ambient_color, axis=1)
    output_colors = tf.add(output_colors, ambient_reshaped * diffuse_colors)

  # Diffuse component
  pixel_positions = tf.reshape(pixel_positions, [batch_size, -1, 3])
  per_light_pixel_positions = tf.stack(
      [pixel_positions] * light_count,
      axis=1)  # [batch_size, light_count, pixel_count, 3]
  directions_to_lights = tf.nn.l2_normalize(
      tf.expand_dims(light_positions, axis=2) - per_light_pixel_positions,
      dim=3)  # [batch_size, light_count, pixel_count, 3]
  # The specular component should only contribute when the light and normal
  # face one another (i.e. the dot product is nonnegative):
  normals_dot_lights = tf.clip_by_value(
      tf.reduce_sum(
          tf.expand_dims(normals, axis=1) * directions_to_lights, axis=3), 0.0,
      1.0)  # [batch_size, light_count, pixel_count]
  diffuse_output = tf.expand_dims(
      diffuse_colors, axis=1) * tf.expand_dims(
          normals_dot_lights, axis=3) * tf.expand_dims(
              light_intensities, axis=2)
  diffuse_output = tf.reduce_sum(
      diffuse_output, axis=1)  # [batch_size, pixel_count, 3]
  output_colors = tf.add(output_colors, diffuse_output)

  # Specular component
  if camera_position is not None:
    camera_position = tf.reshape(camera_position, [batch_size, 1, 3])
    mirror_reflection_direction = tf.nn.l2_normalize(
        2.0 * tf.expand_dims(normals_dot_lights, axis=3) * tf.expand_dims(
            normals, axis=1) - directions_to_lights,
        dim=3)
    direction_to_camera = tf.nn.l2_normalize(
        camera_position - pixel_positions, dim=2)
    reflection_direction_dot_camera_direction = tf.reduce_sum(
        tf.expand_dims(direction_to_camera, axis=1) *
        mirror_reflection_direction,
        axis=3)
    # The specular component should only contribute when the reflection is
    # external:
    reflection_direction_dot_camera_direction = tf.clip_by_value(
        tf.nn.l2_normalize(reflection_direction_dot_camera_direction, dim=2),
        0.0, 1.0)
    # The specular component should also only contribute when the diffuse
    # component contributes:
    reflection_direction_dot_camera_direction = tf.where(
        normals_dot_lights != 0.0, reflection_direction_dot_camera_direction,
        tf.zeros_like(
            reflection_direction_dot_camera_direction, dtype=tf.float32))
    # Reshape to support broadcasting the shininess coefficient, which rarely
    # varies per-vertex:
    reflection_direction_dot_camera_direction = tf.reshape(
        reflection_direction_dot_camera_direction,
        [batch_size, light_count, image_height, image_width])
    shininess_coefficients = tf.expand_dims(shininess_coefficients, axis=1)
    specularity = tf.reshape(
        tf.pow(reflection_direction_dot_camera_direction,
               shininess_coefficients),
        [batch_size, light_count, pixel_count, 1])
    specular_output = tf.expand_dims(
        specular_colors, axis=1) * specularity * tf.expand_dims(
            light_intensities, axis=2)
    specular_output = tf.reduce_sum(specular_output, axis=1)
    output_colors = tf.add(output_colors, specular_output)
  rgb_images = tf.reshape(output_colors,
                          [batch_size, image_height, image_width, 3])
  alpha_images = tf.reshape(alphas, [batch_size, image_height, image_width, 1])
  valid_rgb_values = tf.concat(3 * [alpha_images > 0.5], axis=3)
  rgb_images = tf.where(valid_rgb_values, rgb_images,
                        tf.zeros_like(rgb_images, dtype=tf.float32))
  return tf.reverse(tf.concat([rgb_images, alpha_images], axis=3), axis=[1])
def phong_shader ( normals , alphas , pixel_positions , light_positions , light_intensities , diffuse_colors = None , camera_position = None , specular_colors = None , shininess_coefficients = None , ambient_color = None ) : batch_size , image_height , image_width = [ s . value for s in normals . shape [ : - 1 ] ] light_count = light_positions . shape [ 1 ] . value pixel_count = image_height * image_width # Reshape all values to easily do pixelwise computations: normals = tf . reshape ( normals , [ batch_size , - 1 , 3 ] ) alphas = tf . reshape ( alphas , [ batch_size , - 1 , 1 ] ) diffuse_colors = tf . reshape ( diffuse_colors , [ batch_size , - 1 , 3 ] ) if camera_position is not None : specular_colors = tf . reshape ( specular_colors , [ batch_size , - 1 , 3 ] ) # Ambient component output_colors = tf . zeros ( [ batch_size , image_height * image_width , 3 ] ) if ambient_color is not None : ambient_reshaped = tf . expand_dims ( ambient_color , axis = 1 ) output_colors = tf . add ( output_colors , ambient_reshaped * diffuse_colors ) # Diffuse component pixel_positions = tf . reshape ( pixel_positions , [ batch_size , - 1 , 3 ] ) per_light_pixel_positions = tf . stack ( [ pixel_positions ] * light_count , axis = 1 ) # [batch_size, light_count, pixel_count, 3] directions_to_lights = tf . nn . l2_normalize ( tf . expand_dims ( light_positions , axis = 2 ) - per_light_pixel_positions , dim = 3 ) # [batch_size, light_count, pixel_count, 3] # The specular component should only contribute when the light and normal # face one another (i.e. the dot product is nonnegative): normals_dot_lights = tf . clip_by_value ( tf . reduce_sum ( tf . expand_dims ( normals , axis = 1 ) * directions_to_lights , axis = 3 ) , 0.0 , 1.0 ) # [batch_size, light_count, pixel_count] diffuse_output = tf . expand_dims ( diffuse_colors , axis = 1 ) * tf . expand_dims ( normals_dot_lights , axis = 3 ) * tf . expand_dims ( light_intensities , axis = 2 ) diffuse_output = tf . reduce_sum ( diffuse_output , axis = 1 ) # [batch_size, pixel_count, 3] output_colors = tf . add ( output_colors , diffuse_output ) # Specular component if camera_position is not None : camera_position = tf . reshape ( camera_position , [ batch_size , 1 , 3 ] ) mirror_reflection_direction = tf . nn . l2_normalize ( 2.0 * tf . expand_dims ( normals_dot_lights , axis = 3 ) * tf . expand_dims ( normals , axis = 1 ) - directions_to_lights , dim = 3 ) direction_to_camera = tf . nn . l2_normalize ( camera_position - pixel_positions , dim = 2 ) reflection_direction_dot_camera_direction = tf . reduce_sum ( tf . expand_dims ( direction_to_camera , axis = 1 ) * mirror_reflection_direction , axis = 3 ) # The specular component should only contribute when the reflection is # external: reflection_direction_dot_camera_direction = tf . clip_by_value ( tf . nn . l2_normalize ( reflection_direction_dot_camera_direction , dim = 2 ) , 0.0 , 1.0 ) # The specular component should also only contribute when the diffuse # component contributes: reflection_direction_dot_camera_direction = tf . where ( normals_dot_lights != 0.0 , reflection_direction_dot_camera_direction , tf . zeros_like ( reflection_direction_dot_camera_direction , dtype = tf . float32 ) ) # Reshape to support broadcasting the shininess coefficient, which rarely # varies per-vertex: reflection_direction_dot_camera_direction = tf . reshape ( reflection_direction_dot_camera_direction , [ batch_size , light_count , image_height , image_width ] ) shininess_coefficients = tf . expand_dims ( shininess_coefficients , axis = 1 ) specularity = tf . reshape ( tf . pow ( reflection_direction_dot_camera_direction , shininess_coefficients ) , [ batch_size , light_count , pixel_count , 1 ] ) specular_output = tf . expand_dims ( specular_colors , axis = 1 ) * specularity * tf . expand_dims ( light_intensities , axis = 2 ) specular_output = tf . reduce_sum ( specular_output , axis = 1 ) output_colors = tf . add ( output_colors , specular_output ) rgb_images = tf . reshape ( output_colors , [ batch_size , image_height , image_width , 3 ] ) alpha_images = tf . reshape ( alphas , [ batch_size , image_height , image_width , 1 ] ) valid_rgb_values = tf . concat ( 3 * [ alpha_images > 0.5 ] , axis = 3 ) rgb_images = tf . where ( valid_rgb_values , rgb_images , tf . zeros_like ( rgb_images , dtype = tf . float32 ) ) return tf . reverse ( tf . concat ( [ rgb_images , alpha_images ] , axis = 3 ) , axis = [ 1 ] )