3D Gaussian Splatting for Real-Time Radiance Field Rendering 论文精读笔记
项目网页链接:https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/
论文链接:https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gaussian_splatting_high.pdf
源代码链接:https://github.com/graphdeco-inria/gaussian-splatting?tab=readme-ov-file
1 前言
contributions:
- 提出各向异性的3D高斯作为辐射场的高质量、非结构化表示
- 提出3D高斯属性的优化方法,以及自适应密度控制(为高质量表达场景)
- 提出的算法适应快速GPU计算(cuda kernel)的方法,支持各向异性高斯的泼溅和快速的反向传播算法执行,快速生成新视角(*重要)
1+2 优化场景的算法
3 优化渲染速度的方法
2 3DGS
2.1 overview
输入:一组静态照片+SfM估计的相机姿态与点云
选用高斯原因:各向异性体积可用于紧凑地表示精细结构
用点云初始化高斯:
高斯性质:mean(位置),covariance(形状),opacity(不透明度)
各向异性的颜色可用**球谐函数(SH)**表示
通过3dgs优化参数+高斯密度的自适应控制操作来创建可以表示场景的辐射场
提速的关键:Gaussians用GPU快排
流程图:
2.2 可微的3dgs(构建高斯)
为什么选择Gaussians:可微+方便投影成2D(可以快速α混合)
3D Gaussian公式:
G
(
x
)
=
e
−
1
2
(
x
)
T
Σ
−
1
(
x
)
G(x) = e^{-\frac{1}{2}(x)^T\Sigma^{-1}(x)}
G(x)=e−21(x)TΣ−1(x)
PS:x为坐标矩阵;Σ为协方差矩阵,隐式地包含了mean(μ)信息
混合时G(x)乘以α(不透明度)
投影公式:
∑
′
=
J
W
Σ
W
T
J
T
\sum ' = J W \; \Sigma \; W ^ { T } \; J ^ { T }
∑′=JWΣWTJT
因协方差矩阵中的数据有范围限制,梯度下降算法易更新出无效协方差矩阵。
解决方法:
高斯可以类椭球,用梯度下降改“Σ”→用梯度下降改“椭球3r+scale+rotate”
scaling:3D vector s
rotation:四元数 q
2.3 3dgs自适应密度控制优化(优化高斯)
不同位置3dgs密度不同 需要除点云初始化外的密度控制优化
需优化:μ,Σ,α,SH;密度(前后二者相关联)
2.3.1 优化
用SGD(随机梯度下降)优化,支持定制的cuda kernel
用sigmoid激活函数优化α,指数激活函数优化Σ的scale,以限制数据范围
初始化Σ(正实数*identity matrix)使得高斯为各向同性高斯,即分布密度值仅与到均值距离有关、与方向无关
以距离最近的三个点(SfM生成的点云)为标准生成初始化高斯
用标准指数衰减调度优化μ
生成图片对比目标图片的loss由D-SSIM(衡量两幅图片相似性的算法)得到:
L = ( 1 − λ ) L 1 + λ L D − S S I M \mathcal{L} = (1 - \lambda)\mathcal{L}_1 + \lambda\mathcal{L}_{D-SSIM} L=(1−λ)L1+λLD−SSIM
PS:实验中λ取0.2
2.3.2 自适应高斯控制
用稀疏点云初始化出的高斯很稀疏,需控制单位体积中的高斯数量
预优化后,每100次迭代densify一次,并删除所有α值小于一个极小阈值的高斯
关注高斯覆盖率极低(under-reconstruction)和单个高斯极大(over-reconstruction)的位置,因还原度低,此类位置视图-空间位置梯度很大
因此设置视图-空间位置梯度阈值(实验中取0.0002),超过阈值则需densify,优化过程如下图:
如图,对于欠重构处,克隆一个高斯并向位置梯度方向移动。
对于过重构处,分裂该高斯。新高斯的scale因子由实验得到(实验中取1.6),位置由原高斯作为采样PDF来确定。
在视图中占比过大的高斯可能由于距相机过近或本身过大,会定期被清除,以保证画面质量、控制高斯总数。
2.4 高斯的快速可微光栅化器(fast 3D→2D)
提速对象:投影渲染+高斯的快排(排相对视点的前后顺序,为了α混合)
2.4.1 该光栅化器特点:
- 为提速,先将所有高斯排序(距视点距离的顺序),再进行视角渲染;而非针对视角渲染的每个像素进行高斯排序
- 支持高效反向传播算法
- 内存占用小,每个像素固定占用一部分
- 光栅化管线可微,可投影各向异性高斯
2.4.2 渲染管线:
-
将屏幕分成多个16*16像素的瓦片(tiles)
-
进行视锥体剔除(frustum culling),以确定在视图范围内的高斯(只保留与视锥体相交99%置信区间的高斯)
-
再用一个防护带(guard band)去除位置过偏的高斯(eg. 过于靠后或过于靠近前剪裁面)
-
根据覆盖的瓦片数将每个高斯实例化,并给每个实例分配一个key,包含其在视图空间中的深度信息和覆盖的瓦片编号信息
-
基于key,使用GPU上的高效基数排序(fast GPU Radix sort)对高斯进行排序;后续渲染都基于这个顺序(可能会有瑕疵,但微不足道,速度更重要)
-
根据顺序(通过识别相对当下视点的最近高斯与最远高斯)为每个瓦片生成高斯序列,并为每个瓦片启动一个线程块 —— 即每一瓦片共享一序列,因此瓦片大小选择为重要指标
-
每一线程块将该瓦片对应的高斯序列加载进该块的共享存储器;对于块中每个像素,从前往后遍历共享序列进行α混合(最大化并行增益),累积至该像素的α达目标饱和度(唯一停止标准),停止遍历
-
以一定频率检查线程块中每个线程情况,当16*16个像素都饱和,该线程块收束
-
渲染出图像后计算loss、反向传播、优化参数……
特别地:
- 此方法不限制接收梯度更新的基本体数量,因此可灵活处理各类场景,无需特别调整
- 反向传播时,为减少动态内存开销,从后至前再次遍历所在瓦片对应高斯序列
- α代表该高斯对像素颜色的影响程度,因此可以决定该高斯从loss得到多少梯度指令
3 结果和总结
3.1 结果评估
pros:训练速度快,效果好
cons:内存占用大(高斯太多(eg. 200k~500k),每个高斯的参数也多)
尤其对比Nerf
3.2 消融实验(ablation study)
即评估不同条件/参数等因素对于结果的影响的实验
3.2.1 关于SfM
实验对比了 用随机抽样初始化高斯 和 用SfM点云初始化高斯 得出的结果:
渲染结果大体都不错,但前者会有画面细节问题,可能是由于有无法删除的漂浮物。
PS:SfM仅为一种估计方法,无法达到准确程度,后续研究若有更好方式,会提升效果。
3.2.2 关于致密化(Densification)
实验对比了 通过克隆控制密度、通过分裂控制密度 和 通过克隆&分裂控制密度(见2.3) 三种密度控制方式的结果:
只克隆可能会出现类似迷雾的画面表现,只分裂可能会丢失细节,结合起来效果最好。
3.2.3 对接收梯度的高斯数限制(靠后的高斯是否要变)
因后面的高斯对像素影响小(即使其α值较高),且不考虑靠后高斯可以提速,实验对比了 限制每个像素只有靠前的10个高斯接收梯度(左) 和 前文所述方法(右) 所得结果:
限制靠后高斯的调整对最终效果是有影响的。这可能说明靠前高斯们的α值都不大,不足以覆盖靠后的高斯发挥作用。
3.2.4 关于各向异性协方差
实验对比了 使用各向异性协方差矩阵定义高斯 和 使用各向同性的一个r(减小内存占用)定义高斯 所得结果:
对比表明使用各向异性协方差矩阵图像呈现效果确实更好。
3.2.5 关于球谐函数
球谐函数的引入提高不同视角渲染质量
3.3 不足(技术不足与效果不足)
- 未充分观察到的区域中会有artifacts(瑕疵、错误)(可能由于SfM初始化)
- 某些区域会生成错误的长条形或“斑点状”的高斯
- 实时渲染中可能会出错,体积大的高斯突然霸屏等(可能由于防护带草率地拒绝了部分高斯)
- 过于简单的可见性算法
- 未使用针对loss的正则化(添加惩罚项以防止模型过拟合)
- 内存占用大(待优化)
3.4 总结
3dgs是第一个用辐射场实现实时渲染的方法。
目前只有光栅化例程在优化的cuda kernel中实现,我们期望剩余的优化也可以移植到cuda中。
mesh(网格)在应用领域中占重要分量,因传统方法渲染更快,市场份额占比极大。因此将3dgs技术生成的高斯转为游戏制作等场景中需要的网格也是重要研究方向。
此文中没有呈现的3D高斯分布可视化展示,对理解高斯的规律、优化算法,可能有很大帮助。