code: def add_light_sh(vertices, triangles, colors, sh_coeff):
      """
      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
      --> can be expressed in terms of spherical harmonics(omit the lighting coefficients)
      I = albedo * (sh(n) x sh_coeff)
  
      albedo: n x 1
      sh_coeff: 9 x 1
      Y(n) = (1, n_x, n_y, n_z, n_xn_y, n_xn_z, n_yn_z, n_x^2 - n_y^2, 3n_z^2 - 1)': n x 9
      # Y(n) = (1, n_x, n_y, n_z)': n x 4
  
      Args:
          vertices: [nver, 3]
          triangles: [ntri, 3]
          colors: [nver, 3] albedo
          sh_coeff: [9, 1] spherical harmonics coefficients
  
      Returns:
          lit_colors: [nver, 3]
      """
      assert vertices.shape[0] == colors.shape[0]
      nver = vertices.shape[0]
      normal = get_normal(vertices, triangles)  # [nver, 3]
      sh = np.array(
          (
              np.ones(nver),
              n[:, 0],
              n[:, 1],
              n[:, 2],
              n[:, 0] * n[:, 1],
              n[:, 0] * n[:, 2],
              n[:, 1] * n[:, 2],
              n[:, 0] ** 2 - n[:, 1] ** 2,
              3 * (n[:, 2] ** 2) - 1,
          )
      )  # [nver, 9]
      ref = sh.dot(sh_coeff)  # [nver, 1]
      lit_colors = colors * ref
      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 2 for calling a global function with example usage: add_light_sh(vertices, triangles, colors, sh_coeff) and returns: lit_colors