docstr: Replace directional lights with point lights and check the output
  is the same.
  
  Test an additional case where the angle between the light reflection
  direction and the view direction is 30 degrees.
docstr_tok: ["Replace","directional","lights","with","point","lights","and","check","the","output","is","the","same",".","Test","an","additional","case","where","the","angle","between","the","light","reflection","direction","and","the","view","direction","is","30","degrees","."]
code: def test_specular_point_lights(self):
      """
      Replace directional lights with point lights and check the output
      is the same.
  
      Test an additional case where the angle between the light reflection
      direction and the view direction is 30 degrees.
      """
      color = torch.tensor([1, 0, 1], dtype=torch.float32)
      location = torch.tensor([-1, 1, 0], dtype=torch.float32)
      camera_position = torch.tensor(
          [+1 / np.sqrt(2), 1 / np.sqrt(2), 0], dtype=torch.float32
      )
      points = torch.tensor([0, 0, 0], dtype=torch.float32)
      normals = torch.tensor([0, 1, 0], dtype=torch.float32)
      expected_output = torch.tensor(
          [1.0, 0.0, 1.0], dtype=torch.float32
      )
      expected_output = expected_output.view(-1, 1, 3)
      lights = PointLights(
          specular_color=color[None, :], location=location[None, :]
      )
      output_light = lights.specular(
          points=points[None, None, :],
          normals=normals[None, None, :],
          camera_position=camera_position[None, :],
          shininess=torch.tensor(10),
      )
      self.assertClose(output_light, expected_output)
  
      # Change camera position to be behind the point
      camera_position = torch.tensor(
          [+1 / np.sqrt(2), -1 / np.sqrt(2), 0], dtype=torch.float32
      )
      expected_output = torch.zeros_like(expected_output)
      output_light = lights.specular(
          points=points[None, None, :],
          normals=normals[None, None, :],
          camera_position=camera_position[None, :],
          shininess=torch.tensor(10),
      )
      self.assertClose(output_light, expected_output)
  
      # Change camera direction to be 30 degrees from the reflection direction
      camera_position = torch.tensor(
          [+1 / np.sqrt(2), 1 / np.sqrt(2), 0], dtype=torch.float32
      )
      rotate_30 = RotateAxisAngle(-30, axis="z")
      camera_position = rotate_30.transform_points(
          camera_position[None, :]
      )
      expected_output = torch.tensor(
          [np.cos(30.0 * np.pi / 180), 0.0, np.cos(30.0 * np.pi / 180)],
          dtype=torch.float32,
      )
      expected_output = expected_output.view(-1, 1, 3)
      output_light = lights.specular(
          points=points[None, None, :],
          normals=normals[None, None, :],
          camera_position=camera_position[None, :],
          shininess=torch.tensor(10),
      )
      self.assertClose(output_light, expected_output**10)
  
imports: import unittest
  import numpy
  import torch
  from pytorch3d.renderer.lighting import AmbientLights, DirectionalLights, PointLights
  from pytorch3d.transforms import RotateAxisAngle
  from .common_testing import TestCaseMixin
label_desc: Use image node_id 2 for calling the TestSpecularLighting obj's underlying member method code with example usage: obj.test_specular_point_lights() without return types