前言
尝试精读了3dgs的论文原文,本文可以看做一个阅读笔记或者总结
论文基本信息
| 项目 | 详情 |
|---|---|
| 标题 | 3D Gaussian Splatting for Real-Time Radiance Field Rendering |
| 作者 | Bernhard Kerbl, Georgios Kopanas, Thomas Leimkühler, George Drettakis |
| 单位 | Inria, Université Côte d’Azur |
| arXiv | 2308.04079 |
| 代码 | graphdeco-inria/gaussian-splatting |
研究背景和动机
本文提出了3DGS的方法,实现了在更短的训练时间内,达到SOTA的视觉效果及1080P高质量实时新视角重建。
在本文之前:
- NeRF方法每条射线需要采样几十上百个点,而每个点需要跑一次MLP,渲染一张图需要进行成千上万次的网络前向传播;
- 隐式表示紧凑但查询慢,显示表示查询快但质量差或占内存大,都无法实现实时渲染;
核心方法
3DGS的核心有三点:
- 使用3D Gaussian作为场景基元,代替原有的表示方法;
- 自适应密度控制;
- 使用可微分的渲染器(可微 tile-based 光栅化);
使用3D Gaussian作为场景基元
3D Gaussian相较三角形、体素、点云等场景基元,有着连续、可微、不依赖拓扑结构的优秀性质;相较MLP的隐式表示方法,它不需要进行ray marching,渲染速度快。
连续可微:
3d高斯是连续可微的,公式如下:
$$G(x) = \exp\Big(-\frac{1}{2}(x-\mu)^T \Sigma^{-1}(x-\mu)\Big)$$
其中,exp是指数函数,其内部是一个二次多项式,因此复合的结果处处无线可微。
对比三角形,三角形的分片是连续的。可是在边界处,由于”像素在三角形内”的判断结果是离散值,因此函数值会发生跳变,因此三角形不可微;
点云是离散的,且完全不可微;
体素本身是离散的。但使用三线性插值等方法可以将函数变为连续的分片线性函数,但在边界处存在跳变
各向异性协方差
- 协方差矩阵 (\Sigma = RSS^TR^T) 的分解方式(R 是旋转,S 是缩放)
- 为什么分解成 R 和 S?(保证半正定性、参数量可控)
- 与各向同性(isotropic)高斯对比的优缺点
协方差矩阵只有当半正定时才是有意义的。将协方差矩阵进行分解:
$$\Sigma = RSS^TR^T$$
其中R为旋转矩阵、S为缩放矩阵。通过协方差矩阵的几何意义,可以得知这个分解是可行的,且这几个矩阵相乘的积总是正定的。
同时,旋转矩阵可以用四元数表示,缩放矩阵只需要维护三个方向的缩放系数,因此在这种分解方式下,只需要记录7个值就可以表示协方差矩阵,参数少,优化速度快,且总是满足其正定性。
与各向同性高斯对比:各向同性高斯不需要记录旋转信息,需要的参数量更小;可是各向同性高斯的形状是一个简单的球,难以近似现实中的物体,比如对于一个平面,需要密密麻麻的小球才能够近似表示。
$\Sigma$ 和高斯公式推出的一些性质
对 $G(x) = \exp\Big(-\frac{1}{2}(x-\mu)^T \Sigma^{-1}(x-\mu)\Big)$ 求等值面,可以得到一个高斯椭球。经过一系列的化简和坐标变换,可以得到一个标准椭球公式:
$$\frac{y_1^2}{r^2\lambda_1} + \frac{y_2^2}{r^2\lambda_2} + \frac{y_3^2}{r^2\lambda_3} = 1$$
其中 $y = Q^T(x-\mu)$
所以 $\mu$ 决定椭球的中心,$Q$ 决定椭球旋转方向,$\lambda$ 决定了每个方向上的尺度。
椭球半轴轴长为 $r\sqrt{\lambda_1}, r\sqrt{\lambda_2}, r\sqrt{\lambda_3}$当 $\Sigma$ 有负特征值,G(x)在某些方向上函数值是发散的,对应的等值面也可能变成不闭合的双曲面;当 $\Sigma$ 有特征值为 0 ,其是不可逆的,公式不再成立。因此 $\Sigma$ 要求是正定的。
投影到二维
- 投影近似(affine approximation of perspective projection)的基本思路
- 为什么要近似?精确投影的高斯不再是高斯
精确的透视投影是一个非线性的变换,在经过这个变换之后,原本的高斯椭球不会变成一个标准的二维高斯。
通过在高斯中心附近做线性变换,用雅可比矩阵去近似透视投影,最终得到的是 2D 椭圆高斯。
每个高斯的属性总结
| 属性 | 符号 | 维度 | 作用 |
|---|---|---|---|
| 中心位置 | (\mu) | 3 | 决定高斯椭球最终的中心位置 |
| 协方差矩阵 | (\Sigma) | 3×3 → 分解为 R(4) + S(3) | 决定高斯椭球的方向、形状、大小 |
| 不透明度 | (\alpha) | 1 | 决定某个高斯对最终颜色的贡献权重 |
| 球谐系数 | SH coeff | 48(3 阶 SH × RGB) | 编码视角相关的颜色 |
自适应密度控制
- 增加高斯:3DGS由sfm稀疏点云初始化高斯。后面训练时,算法会去统计每个高斯在视图空间中的位置梯度,如果这个梯度很大,说明这个结果对这个高斯的变化很敏感,所以会将这个高斯clone或split。
- 减少高斯:算法会剔除掉几乎透明的高斯。同时,每经过一定次数的迭代,算法会将alpha重置为很小的值,重新审视每个高斯到底有没有贡献。
为什么要动态调整高斯数量?
- 初始 SfM 点云是不完整的(遮挡区域没有点、弱纹理区域点稀疏)
- 固定的高斯集合无法覆盖所有细节
两种增加策略:Clone 与 Split
当某个高斯在视图空间的位置梯度过大,说明需要进行clone或split:
- Clone:高斯过小时触发?复制并沿梯度方向移动
- Split:高斯过大时触发?拆成两个小一号的高斯
- 两者的阈值设置:梯度阈值 $\tau_{\text{pos}}=0.0002$,尺寸阈值0.01(1%)
split实际是将高斯替换成两个尺寸除以1.6的小高斯。1.6是实验出来的经验值
与训练交替执行
密度控制每隔一定迭代次数(论文设定为从第 500 次迭代开始,每 100 次执行一次)与训练交替进行。训练初期高斯数量少,迭代很快;随着 Clone 和 Split 不断触发,高斯数量从初始的几万暴涨到几百万,每轮迭代的计算量显著增加——这与我实际训练时的观察一致(见笔记一中的训练日志)。
下一步
本文只覆盖了论文的三个核心部分中的两个——场景基元表示和自适应密度控制。第三个核心”可微 Tile-based 光栅化”是实现实时渲染的关键引擎,涉及逐 tile 排序、alpha blending 和 CUDA 反向传播等工程细节,计划在后续笔记中单独展开。训练流程(初始化策略、L1 + D-SSIM 损失函数等)也留到后面结合代码一并分析。