3DGS综述

主要来自这篇综述,也会参考一些知乎和博客
引言

Ray Tracing也是NeRF👿
隐式辐射场 :,可微且紧凑,省内存,但对光线进行采样和体渲染的计算导致计算量很大(Nerf可以想象一边MLP算SDF一边步进确实会挺慢)
显式辐射场 : ,每个元素都存储了其在空间中相应位置的辐射信息,直接读,计算量少,但占内存。(就像搞的那个SDF。。。)
3DGS :,不采样,直接投影,用隐式的“大脑”(梯度优化+球谐系数)来驱动显式的“肉体”(存储结构+光栅化渲染)。视觉上去拟合。(根本上是显式的)
3D GS 使用了基于网格的可微光栅器(现在好像也能走类似RT的物理渲染,有空稍微看下光栅渲染的方法)
Nerf 和传统的 Mesh:一个是纯连续的、隐式表达在可微空间内;一个是纯离散的(虽然可以插值),显式表达在三维空间内,也就是体素中。3DGS 是在离散和连续间的一个平衡:在高斯球内部是连续的、可微的;在整个空间中,每个高斯球又是离散的,中庸之道这一块~
为前几天还在说RT不够Physical的我道歉
前向渲染
3DGS 根本上就是用椭球集来表示三维模型,并不算是新鲜事,最早在 1994 年的游戏《魔城迷踪ecstatica》中出现:
算是3D恐怖生存冒险+开放世界的鼻祖了,看论坛当年好像因为椭球建模技术轰动一时,但开放世界玩法在当时并不流行以及其他原因逐渐被历史遗忘
随着scale的上升,也能有很酷😎的效果

基本单元 3DGS
3DGS组成:中心 𝝁、不透明度 𝛼、3D 协方差矩阵 𝚺 和颜色 𝑐.
𝑐由球谐函数 (SH) 系数表示,SH 函数允许颜色根据视角而变化,通过在渲染过程中评估特定视图方向的 SH 系数,可以实现类似于镜面高光和光照变化的效果。
Frustum Culling
将相机视椎体外的3DGS剔除。
(a)Splatting 将3D高斯投影到图像空间
W 是相机的视图变换矩阵,J 是投影变换的雅可比矩阵(用于估算投影产生的形变)
这样就获得了每个3D高斯在屏幕上对应的2D高斯形状和大小
之前嵌入式玩机械臂,搞过通过April Tag定位世界坐标,差不多正好是这个的反过程
(b)3DGS 将图像划分为多个不重叠的Tile
为了避免为每个像素导出高斯函数的成本计算,3D GS 将精度从像素级转移到块级细节。
\text{Tile_X} = \lfloor \frac{u}{T} \rfloor, \quad \text{Tile_Y} = \lfloor \frac{v}{T} \rfloor
为了充分利用显卡的并行计算能力,把整个屏幕切分成许多不重叠的、尺寸相等的小方块,每个小方块就可以交给一个独立的GPU线程去处理。
(c)3DGS 复制覆盖多个Tile的高斯分布,为每个副本分配一个标识符,即图块 ID
有的2D高斯椭圆特别大,会同时覆盖好几个 Tile 小方块。为了保证每个小方块都能独立计算出颜色,需要复制这个覆盖多个格子的高斯体,给它贴上它覆盖的所有格子的编号标签(Tile ID),把它的副本分发到对应的格子里。
高位ID,低位深度,这样排序后,所有属于同一个 Tile 的高斯副本,在物理内存中会紧密挨在一起,省去了复杂的多级分类和归并,只需做一次全局线性排序,就能同时完成“按图块分类”和“按深度排序”两个目标。
这就导致同一个高斯体,可能有多个Tile的副本。
(d)渲染排序后的高斯,我们可以获得图块内的所有像素。
就像用PS一样,渲染一个像素点,搞清楚哪些Tile覆盖了这个像素点,以及哪个图层(Tile)在上面,然后就像用半透明的颜料叠涂一样,从后往前一层层把颜色叠加上去(Alpha混合)。
理想计算:

由远及近:先计算远处的颜色C1,然后近处的颜色 C2 只覆盖其不透明部分。
不透明度计算:

椭球马氏距离: ,这样离中心越远,不透明度就越低,这个椭球对颜色的影响就越小,很河狸
排序是难以并行的,因此3DGS会做些取舍。
3DGS训练
公众号什么的一直叫什么训练,神经什么的,害我一直以为是MLP之类的来生成3DGS,原来是类似于梯度下降地更新优化,但并不是神经网络,这部分后面再更新吧。
3DGS的优化方向
综述上的几个有趣的方向。
3D GS for Sparse Input
当输入视角很少时,拍不到的地方算法在这些“盲区”肆意捏造信息,从而产生漂浮的、撕裂的伪影。
基于正则化(Regularization-based)
不依赖外部数据,而是在当前场景的优化过程中,强行加入额外的几何约束,最常见的是用深度模型推出深度图信息。
基于泛化性(Generalizability-based)—— 用“外部先验”补全
子路线A(生成式增广):先用生成模型(如扩散模型)把稀疏视角“脑补”成密集视角,再喂给标准重建流程。
缺点:计算量极大,且重建质量被生成模型的上限锁死。
子路线B(前馈式直接预测):训练一个端到端的网络,输入单张图,直接输出每个像素对应的3D高斯椭球体。。
缺点:这类方法生成的高斯点均匀分布在空间里(像素对齐),导致高频细节(如纹理边缘)表现不够锐利,同时平滑区域(如墙壁)又会分配过多冗余高斯,造成浪费。
目前几乎所有方法都针对静态物体。未来若扩展到动态场景(如行人、飘动的衣物),不仅要解决空间稀疏问题,还要额外处理时间上的连续性(防止帧与帧之间抖动)和运动导致的拖影伪影。(传说中的4DGS?)
Memory-efficient 3D GS
随着scale的增大,内存占用问题会越来越严重,目前的优化方案主要为两个方向:
减少3DGS数量
- 基于体积的掩码,将影响小的3DGS基元剪枝。
- 通过聚类将空间邻近的高斯点划分成组,或者在哈希网格中把空间划分成多个小格子,在每个组或每个格子里选取一个“局部锚点,这个组内所有高斯点的属性不再独立存储,而是统一参照这个“锚点”的属性,只需额外记录一个微小的“偏移量”即可。
压缩属性
把每个高斯点自带的数据体积变小
- 不再为每个高斯单独存储这些巨大的数值,而是创建一本紧凑码本进行对照(就是一种量化方法吧,只是是自定义的,而不是均匀的而已)。
- 自适应动态量化:动态地分配位数。比如对于颜色鲜艳的区域,多分配几位保存细节;对于颜色平坦的区域(如纯白墙壁),少分配几位。
Photorealistic 3D GS
简单的可见性算法可能会导致高斯深度/混合顺序的剧烈切换。渲染图像的视觉保真度(包括锯齿、反射和伪影等方面)可以进一步优化。问题主要集中在三方面:
锯齿与模糊
由于离散采样,3DGS在处理不同分辨率易出现锯齿。
在训练时引入多尺度高斯、2D Mip滤镜,或者条件逻辑函数,让模型提前适应不同分辨率。
复杂材质物体
标准的高斯泼溅难以处理这些与视角相关的效果。因为它依赖于光栅化,所以它无法轻易地解释从一个表面反射(反射)或穿过另一个表面(透射)的光线。
补丁
-
给每个高斯点定义法线和着色函数,模拟高光反射;
-
引入镜像属性和平面镜像成像,专门重建镜面几何;
-
设计各向异性视相关外观场,精细捕捉金属拉丝等随视角剧烈变化的材质;
综述里的这些修复尝试通常只关注反射或透明度之一,但很少能同时以物理精度处理两者。(所以只能算是补丁,感觉治标不治本),去查了下之前看到的3DGS和RT结合。
RT-GS
结合了2D高斯基元、可微分光线追踪和基于物理的材质模型的统一框架
