球谐函数系数

在 3D 场景重建中,如果仅仅为每个点赋予一个固定的 RGB 颜色,那么渲染出的物体将黯淡无光,缺乏真实的材质感。真实的物理世界中,我们从不同角度观察同一个点,由于高光(Specular Reflection)和环境光的影响,它呈现的颜色是不同的。

那么,在 3D Gaussian Splatting 中,我们如何让这一百万个高斯球都拥有这种“随视角变化”的色彩呢?


神经网络或离散网格

一开始,我们可能会产生两个直观的想法:

1. 为每个高斯训练一个小巧的神经网络 (MLP):输入视角方向 (\theta, \phi)(x, y, z),输出颜色。

2. 空间离散化 (Binning):将 \theta\phi 分成 10 \times 10 的网格(Bins)。通过查表来决定颜色。

无论是上述哪种方法,都会导致严重的过度参数化(Overparameterization)。

假设我们采用 10 \times 10 的网格,意味着每个高斯球除了现有的位置 (3)、旋转 (4)、缩放 (3)、透明度 (1) 共 11 个参数外,还需要额外存储 100 个颜色参数。

试想一下,如果我们的场景有 100 万个高斯点(在实际场景中甚至可能上千万),为了优化这额外的上亿个参数,内存(VRAM)和计算开销将是极其庞大的。

这时候,我们需要一种既能连续表达空间方向,又不需要太多参数的数学工具。


球谐函数 (Spherical Harmonics)

球谐函数在图形学(如环境光遮蔽、光照模拟)以及量子物理学中被广泛使用。我们可以将它简单理解为定义在球面上的“傅里叶变换基底”。

就像傅里叶变换可以用一系列正弦和余弦波组合出任意一维信号一样,球谐函数可以通过组合一系列定义在球面上的“平滑图案(Smooth Patterns)”,来拟合出球面上任意的连续函数。

球谐函数的一般形式可以写为 Y_l^m(\theta, \phi)。为了拟合特定视角下的颜色,我们的模型真正要学习的是权重系数 (Coefficients) c_l^m

最终的颜色输出,就是这些固定图案与学习到的权重的线性组合:

\text{Color}(\theta, \phi) = \sum_{l=0}^{L} \sum_{m=-l}^{l} c_l^m Y_l^m(\theta, \phi)

  • l (Degree, 阶数):控制频率。l 越大,频率越高,能表达的高频细节(如锐利的镜面高光)就越丰富,但所需的计算量和参数也越多。
  • m (Order, 次数):对于给定的阶数 lm 的取值范围是 [-l, l]

让我们来盘点一下不同阶数下的参数量:

  • l=0 时:只有一个项 (m=0),这是一个常数。
  • l=1 时:有三个项 (m=-1, 0, 1)。
  • l=2 时:有五个项。
  • l=3 时:有七个项。

基底函数 Y_l^m

Y_l^m 这个固定基底长什么样呢?它由三个部分组成:

1. N_l^m (归一化项):由 \pi, l, m 和阶乘组成的常数。

2. 连带勒让德多项式 (Associated Legendre Polynomials):一个关于 \cos(\theta) 的多项式。

3. 三角函数项:当 m \ge 0 时为 \cos(m\phi),当 m < 0 时为 \sin(|m|\phi)

在实际的代码工程中,为了避免在着色器 (Shader) 或 CUDA 内核中进行昂贵的三角函数(\sin, \cos)计算,我们通常不会直接传入 (\theta, \phi)。相反,我们会利用几何关系,将这个公式改写为直接接收视线向量 (x, y, z) 的多项式。


代码实现:硬编码系数

让我们来看看最基础的 l=0, m=0 (零阶)是如何计算的。

根据数学推导,零阶基底是一个常数:

Y_0^0 = \frac{1}{2}\sqrt{\frac{1}{\pi}} \approx 0.28209

在代码实现中,我们的神经网络(或者说优化器)为零阶学习到的系数是 c_0^0。基础的“原始颜色”可以表示为:

\text{Raw Color} = c_0^0 \times Y_0^0 = c_0^0 \times 0.28209

其他系数我们不深究,先直接拿来用。

  1. # 0阶系数 (Degree 0)
  2. SH_C0 = 0.28209479177387814
  3.  
  4. # 1阶系数 (Degree 1) - 对应于 x, y, z 分量
  5. SH_C1_y = 0.4886025119029199
  6. SH_C1_z = 0.4886025119029199
  7. SH_C1_x = 0.4886025119029199
  8.  
  9. # 2阶系数 (Degree 2) - 对应于多项式基底
  10. SH_C2_xy = 1.0925484305920792
  11. SH_C2_yz = 1.0925484305920792
  12. SH_C2_zz = 0.31539156525252005
  13. SH_C2_xz = 1.0925484305920792
  14. SH_C2_xx_yy = 0.5462742152960396
  15.  
  16. # 3阶系数 (Degree 3) - 对应于更高次项
  17. SH_C3_y_3x2_y2 = 0.5900435899266435
  18. SH_C3_xyz = 2.890611442640554
  19. SH_C3_y_zz_x2_y2 = 0.4570457994644658
  20. SH_C3_zz_x2_y2 = 0.3731763325901154
  21. SH_C3_x_zz_x2_y2 = 0.4570457994644658
  22. SH_C3_z_x2_y2 = 1.445305721320277
  23. SH_C3_x_x2_3y2 = 0.5900435899266435