前置知识:高斯分布,协方差矩阵,线性变换,四元数,机器学习,计算机图形学/计算机视觉,高性能计算
定义:
3DGS实时渲染,即3D Gaussian Splatting in Real-time Rendering,使用了3D gaussian作为基底,对输入的SfM点云的位置(x,y,z)和颜色(r,g,b)进行gaussian model初始化,通过GPU并行计算,运用计算机图形学的传统光栅化方法将高斯渲染到屏幕上面,通过渲染结果做偏微分做loss反向传播并更新高斯参数,利用随机梯度下降进行学习,并且交错迭代优化。
具体细节:
为什么选用高斯?
-
高斯可以近似为椭球,渲染到2D屏幕上近似为圆,不仅可以实现以圆为基底的光栅化渲染,而且具有可微的性质,所以可学习。
- 2阶协方差矩阵转换为二次曲线得到椭圆表达式
- 偏微分得到位置mean和协方差矩阵(用scale和quternion表示),颜色(r,g,b),opacity ,反深度,椭球曲线conic等信息,与L1和SSIM Loss做反向传播进行优化更新
-
高斯有很多优秀的性质,加快计算以达到实时渲染
- 协方差矩阵表示3D高斯在各个坐标轴的缩放及旋转,相应地可以通过旋转矩阵和缩放矩阵表示协方差矩阵
- 3D高斯通过矩阵变换后得到的还是一个3D高斯,我们光栅化时转换坐标系时需要用到
- 两个高斯做卷积还是一个高斯,并且得到的高斯的协方差矩阵是两个高斯的协方差矩阵之和,后面做EWA反走样时会用到
- 3D高斯沿着某个轴做积分可以得到2D高斯,而且这个2D高斯的协方差矩阵就是3D高斯的协方差矩阵的左上角2x2部分
如何进行光栅化?
-
3D -> 2D
- 转换坐标系,从3D高斯投影为2D高斯,注意这里的3D椭球从不同视角看投影出来的2D椭圆是不同的。我们使用了协方差矩阵为核心,从世界空间到相机空间是一个仿射变换。而从相机空间齐次空间是一个非线性变换,不满足上述性质,论文中提出了一种近似的放射投影变换(local affine approximation),是二阶泰勒展开得到的Jacobian Matrix,然后做积分得到2D高斯,而且根本不用做积分运算,因为2D高斯协方差矩阵已经得到了。
- 为了减少阴影和混叠,我们需要反走样Antialiasing,我们对信号增加一个低通滤波器以避免混叠现象。经过证明,对整个信号的卷积等价于对足迹函数的卷积,即2D协方差矩阵对角线的两个数加上定值0.3,让所有高斯"胖"一些,让更多高斯贡献到某一像素上。
- 用协方差矩阵得到相应的椭球形状,然后近似成圆,得到半径和圆心(2Dmean),找到这个圆对应了几个Tile,用球谐函数拟合这个圆的颜色,按位深度排序得到 [Tile | Sphere] 键值对,以Tile为Block,Pixel为Thread进行GPU并行计算,加快渲染速度。
-
渲染方程
对应到3DGS算法上面,表示某个高斯的颜色(feature),是累计的透明度,是这次的透明度,卷积经过预计算的协方差矩阵可以得出。
其中:
- 颜色是输入的颜色,但是为了让不同视角看起来的颜色不同(高光和漫反射),我们使用球谐函数拟合出不同视角的颜色。
- 透明度乘以足迹函数就是高斯分布,即概率
这样,我们不断进行累加,运用GPU并行计算,就可以得到一个2D视图场景。
怎样做反向传播?
对于一个可学习模型的反向传播,我们要先知道输入项和输出项。
在这里,我们可以认为输入项是逐像素的颜色张量 。
输出项是高斯的相关参数,包括:逐高斯的颜色张量、逐高斯的不透明度、椭球中心的位置、椭球的旋转角度、椭球的轴长。
由于是梯度下降法,然后就是计算梯度,利用Loss函数偏微分计算出即可。
具体就是Pytorch和Loss比较,在前向传播后会返回一个Loss对输出值的偏微分,即,然后我们可以通过换元一步步计算出对应的偏微分,即得到梯度。
在这里,Loss为L1和D-SSIM的组合损失函数,其中D-SSIM权重为0.2
训练时如何优化?
-
增加高斯的数量。
论文中使用了一种基于gradient的densification方法对高斯密度进行调节。
论文将需要调节的高斯分为两类:- under-reconstruction:高斯并不能填满需要表达的几何
- over-reconstrucition:高斯过大导致完全覆盖了一片区域
这些需要调节的高斯的位置梯度往往很大,因为优化器更倾向于把这些错误纠正。
论文中直接算历史平均位置梯度,如果在某次调节中发现这个高斯的平均梯度大于某个预定值,就认为这个高斯需要调节。
-
对高斯进行剪枝。
- 当透明度小于0.005时,就认为这个高斯不存在(大片空白场景),将其剪枝
- 当高斯scale过大时或者投影到屏幕上过大时,将其剪枝
- 每过3000次迭代将所有高斯的透明度设置为0.01,这样优化器就会忽略增加那些错误的高斯的透明度从而做到剪枝掉空中的’floater’的作用。
-
增加球谐函数的维度。
每过1000次迭代增加一个球谐函数的维度,最高为3 -
通过学习率变化策略。
- 先warm-up再下降
- 不同的参数交错训练,且使用不同的优化器和初始学习率