不用神经网络,用一堆“3D椭球”就能重建场景,还能以200+FPS实时渲染
近年来,3D重建与新视角合成领域涌现了不少令人兴奋的工作。从经典的NeRF(神经辐射场)到最新的3D Gaussian Splatting(3DGS),技术的迭代速度让人目不暇接。今天,我们就来深入浅出地聊聊3DGS——这个被许多人视为“NeRF终结者”的新秀。
一、从一个简单的想法开始
想象一下:如果你要用一堆点来描述一个三维物体,最直接的方式是什么?
传统的做法是使用点云——每个点只有位置和颜色信息。但点云的问题是,它只是“悬浮”在空间中的离散点,很难渲染出连续的表面。
3DGS的思路非常巧妙:把每个点变成一个“小椭球”(三维高斯分布),无数个这样的小椭球堆叠在一起,就能连续地、平滑地表达整个场景。
💡直观类比:就像用一堆软软的、可伸缩的“果冻粒”去填充一个物体,每个果冻粒都有自己的形状、大小、透明度和颜色。当从某个角度观察时,我们把这些果冻粒按前后顺序叠加,就得到了一张完整的图像。
二、核心要素:每个高斯球包含什么?
在3DGS中,场景由数百万个三维高斯函数表示。每个高斯元(我们称之为一个“高斯溅射”)由以下几组参数定义:
1. 位置(均值) (\mu \in \mathbb{R}^3)
这个高斯球在空间中的中心坐标。
2. 协方差矩阵 (\Sigma \in \mathbb{R}^{3 \times 3})
控制高斯球的形状(是胖是瘦、是长条还是圆球)和朝向。协方差矩阵必须是半正定的,实际存储时通常分解为缩放矩阵 (S)和旋转矩阵 (R):
[
\Sigma = R S S^T R^T
]
- 缩放 (S = \text{diag}(s_x, s_y, s_z)):三个方向上的“长度”。
- 旋转 (R):用四元数表示,避免正交化问题。
3. 不透明度 (\alpha \in [0, 1])
控制这个高斯球的透明程度。(\alpha=1) 表示完全不透明,(\alpha=0) 表示完全透明。
4. 颜色 (c)
为了能够表示视角相关的效果(如金属高光、光泽感),3DGS采用了球谐函数(Spherical Harmonics, SH)。每个高斯球存储一组球谐系数(通常阶数≤3),根据观察方向实时计算出当前的颜色值。
📐球谐函数简介:它类似于傅里叶级数,但定义在球面上。通过几个系数就能近似任何随方向变化的函数。在3DGS中,我们用SH来表示“从这个方向看过去,这个高斯球应该是什么颜色”。
三、从3D高斯到2D图像:渲染公式
3DGS的目标是:给定一个相机位姿,把这些3D高斯球投影到成像平面上,合成一张2D图像。
步骤1:将3D高斯投影到2D
对于一个均值为 (\mu)、协方差为 (\Sigma) 的三维高斯,经过透视投影变换 (W)(一个3×3的仿射近似),它在图像平面上的投影也是一个二维高斯,其协方差矩阵为:
[
\Sigma’ = J W \Sigma W^T J^T
]
- (W):从世界坐标系到相机坐标系的线性变换(旋转和平移的线性部分)。
- (J):投影变换的雅可比矩阵,是透视投影在 (\mu) 处的局部线性近似。
这个公式是3DGS中最关键的数学之一。它告诉我们:一个椭球体经过透视投影后,在图像上变成了一个椭圆,而 (\Sigma’) 就是这个椭圆的形状。
步骤2:对各高斯进行排序
为了正确进行alpha混合,所有高斯必须按从远到近的顺序(相对于相机)排列。3DGS使用一种快速的基数排序算法,每帧都重新计算高斯中心在相机空间中的深度,然后排序。
步骤3:逐像素的alpha混合
对于图像上的每个像素,我们遍历该像素覆盖的所有高斯(按深度从近到远),按照下面的公式累积颜色:
[
C = \sum_{i=1}^{N} T_i \cdot \alpha_i \cdot c_i
]
其中:
- (c_i):第 (i) 个高斯的颜色(由球谐函数+观察方向计算得到)
- (\alpha_i):第 (i) 个高斯的不透明度
- (T_i = \prod_{j=1}^{i-1} (1 - \alpha_j)):累积透射率,表示光线在经过前面 (i-1) 个高斯后还剩多少能量
这个公式实际上就是前向alpha混合,与NeRF中的体渲染公式本质相同,但计算效率极高,因为它只需要在二维投影椭圆内做积分,而不是像NeRF那样沿射线采样几百个点。
四、如何训练(优化)这些高斯?
3DGS的训练不是传统的“前向-反向传播”一次完成。它是一个迭代优化+自适应调整的过程。
4.1 损失函数
使用L1损失与D-SSIM(结构相似性)损失的组合:
[
\mathcal{L} = (1 - \lambda) \mathcal{L}1 + \lambda \mathcal{L}{\text{D-SSIM}}
]
通常取 (\lambda = 0.2)。
4.2 优化参数
需要优化的参数包括:
- 每个高斯的均值 (\mu)
- 每个高斯的缩放 (s_x, s_y, s_z) 和旋转四元数
- 每个高斯的透明度 (\alpha)
- 每个高斯的球谐系数
优化器通常使用Adam,并配合指数衰减的学习率。
4.3 自适应密度控制——最关键的一步
固定数量的高斯无法很好地表达场景。3DGS会在训练过程中动态增删高斯:
- 分裂(Split):如果一个高斯太大(在图像空间中投影面积超过一定阈值),说明它覆盖了过多细节不够的区域,就把它分裂成两个小高斯。
- 克隆(Clone):如果一个高斯太小但处于“欠重建”区域(梯度较大),就克隆一个相同的放在旁边。
- 剔除(Prune):透明度极低((\alpha < \epsilon))的高斯或位置异常的高斯会被移除。
这种自适应策略使得高斯密度在纹理丰富区域自动增加,在平坦区域保持稀疏,极大提高了表达效率。
五、为什么3DGS比NeRF快这么多?
| 方面 | NeRF | 3DGS |
|---|---|---|
| 场景表示 | 隐式函数(MLP权重) | 显式高斯点集 |
| 渲染方式 | 每条射线采样数百点 | 投影后排序+alpha混合 |
| 计算瓶颈 | MLP前向传播 | 高斯投影与排序 |
| 训练时间 | 数小时到一天 | 30分钟~1小时 |
| 渲染速度 | 数秒/帧 | 200+ FPS |
3DGS的核心优势在于:
- 显式表示:不需要查询神经网络,直接操作几何图元。
- 光栅化路径:传统图形学管线的优化(如分块剔除、并行化)可以大量应用。
- 无采样冗余:每个像素只混合与其椭圆相交的少数高斯,而不是固定的几百个点。
六、一个简单的例子帮助理解
假设我们要重建一个红色的苹果:
- 初始时,随机撒1000个高斯点在整个空间。
- 开始时,所有高斯都是半透明、灰色的。
- 经过几轮优化:靠近苹果表面的高斯变红、变实;内部的透明度降到接近0;苹果梗附近分裂出很多小高斯来抓住细节。
- 训练完成后:从任意角度渲染,按深度排序这些高斯,混合出苹果的图像——而且这个渲染过程可以在游戏引擎里实时完成。
七、总结
3D Gaussian Splatting = 三维高斯椭球 + 可微投影 + 自适应密度控制
- 优点:实时渲染、训练相对快、能表示复杂的镜面效果。
- 缺点:需要较多显存(存储数百万个高斯)、对初始点云质量有一定依赖、大尺度场景需要分块。
自从2023年提出以来,3DGS已经衍生出大量改进工作(如4D-GS用于动态场景、LightGaussian用于压缩、Mip-GS用于抗锯齿等)。如果你想入门3D重建或实时渲染,3DGS是一个极佳的学习起点。
📌延伸阅读建议:论文原文“3D Gaussian Splatting for Real-Time Radiance Field Rendering”(Kerbl et al., SIGGRAPH 2023);GitHub上有非常成熟的开源实现(如
gaussian-splatting)。
希望这篇文章能帮助你理解3DGS的精髓。如果你对某个公式或概念还有疑问,欢迎留言讨论!