code: def add_light(
      vertices,
      triangles,
      colors,
      light_positions=0,
      light_intensities=0,
  ):
      """Gouraud shading. add point lights.
      In 3d face, usually assume:
      1. The surface of face is Lambertian(reflect only the low frequencies of lighting)
      2. Lighting can be an arbitrary combination of point sources
      3. No specular (unless skin is oil, 23333)
  
      Ref: https://cs184.eecs.berkeley.edu/lecture/pipeline
      Args:
          vertices: [nver, 3]
          triangles: [ntri, 3]
          light_positions: [nlight, 3]
          light_intensities: [nlight, 3]
      Returns:
          lit_colors: [nver, 3]
      """
      nver = vertices.shape[0]
      normals = get_normal(vertices, triangles)  # [nver, 3]
  
      # ambient
      # La = ka*Ia
  
      # diffuse
      # Ld = kd*(I/r^2)max(0, nxl)
      direction_to_lights = (
          vertices[np.newaxis, :, :] - light_positions[:, np.newaxis, :]
      )  # [nlight, nver, 3]
      direction_to_lights_n = np.sqrt(
          np.sum(direction_to_lights**2, axis=2)
      )  # [nlight, nver]
      direction_to_lights = (
          direction_to_lights / direction_to_lights_n[:, :, np.newaxis]
      )
      normals_dot_lights = (
          normals[np.newaxis, :, :] * direction_to_lights
      )  # [nlight, nver, 3]
      normals_dot_lights = np.sum(
          normals_dot_lights, axis=2
      )  # [nlight, nver]
      diffuse_output = (
          colors[np.newaxis, :, :]
          * normals_dot_lights[:, :, np.newaxis]
          * light_intensities[:, np.newaxis, :]
      )
      diffuse_output = np.sum(diffuse_output, axis=0)  # [nver, 3]
  
      # specular
      # h = (v + l)/(|v + l|) bisector
      # Ls = ks*(I/r^2)max(0, nxh)^p
      # increasing p narrows the reflectionlob
  
      lit_colors = diffuse_output  # only diffuse part here.
      lit_colors = np.minimum(np.maximum(lit_colors, 0), 1)
      return lit_colors
  
file_path: insightface/python-package/insightface/thirdparty/face3d/mesh/light.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import numpy
  from .cython import mesh_core_cython
label_desc: Use image node_id 3 for calling a global function with example usage: add_light(vertices, triangles, colors, light_positions, light_intensities) and returns: lit_colors