文章目录
- [1. 3DGS 到底在解决什么问题](#1. 3DGS 到底在解决什么问题)
-
- [1.1 NeRF做对了什么](#1.1 NeRF做对了什么)
- [1.2 但 NeRF 慢在哪](#1.2 但 NeRF 慢在哪)
- [1.3 点云一派也有自己的问题](#1.3 点云一派也有自己的问题)
- [2. 核心思想:把场景变成一堆会发光的高斯球](#2. 核心思想:把场景变成一堆会发光的高斯球)
- [3. 理论部分:想深入开发得看懂](#3. 理论部分:想深入开发得看懂)
-
- [3.1 三维高斯的数学定义](#3.1 三维高斯的数学定义)
- [3.2 从三维椭球到二维椭圆](#3.2 从三维椭球到二维椭圆)
- [3.3 为什么协方差不能直接优化](#3.3 为什么协方差不能直接优化)
- [3.4 Alpha Blending:为什么它可以替代体渲染](#3.4 Alpha Blending:为什么它可以替代体渲染)
- [4. 训练流程到底发生了什么?](#4. 训练流程到底发生了什么?)
- [5. 为什么 3DGS 能这么快?](#5. 为什么 3DGS 能这么快?)
- [6. 使用场景](#6. 使用场景)
- [7. 3DGS 的问题](#7. 3DGS 的问题)
- [8. 3DGS 之后发生了什么?](#8. 3DGS 之后发生了什么?)
-
- [Scaffold-GS(CVPR 2024)](#Scaffold-GS(CVPR 2024))
- [Mip-Splatting(CVPR 2024)](#Mip-Splatting(CVPR 2024))
- Octree-GS
- [Dynamic 3D Gaussians](#Dynamic 3D Gaussians)
- [GaussianEditor / 3DGS-Editor](#GaussianEditor / 3DGS-Editor)
- 收尾

如果在过去两年接触过新视角合成,大概率听说过 NeRF 的大名。
NeRF 确实漂亮。给定一组照片,它能学出一个连续的三维场函数 ,让你在一个场景里自由推拉镜头------看到的是连续、平滑、没有几何缝隙的新视角。画质方面,Mip-NeRF360 至今还是很多 benchmark 上的天花板。
但如果真的在自己的 GPU 上跑过 NeRF,大概率也经历过这个场景:
训练 48 小时,推理一帧 10 秒。
每生成一张 1080p 的图,GPU 风扇都会发出一种悲壮的轰鸣。这不怪显卡,怪的是 NeRF 的渲染策略------每条光线发射出去,要在空间里密密麻麻地采样几百个点,每个点都要过一次 MLP,然后做体渲染积分(volume rendering)。GPU 确实擅长并行,但你让它反复算一个巨大的 MLP 在几百个位置上的推理值,它也没辙。
而同时,游戏引擎里几毫秒一帧已经在跑 4K 了。这就形成了一个诡异的局面:学术界能生成最漂亮的图片,但只能当幻灯片看;工业界能实时跑,但渲染质量远不如 NeRF。
3D Gaussian Splatting(3DGS)就是在这个裂缝里冒出来的。
它既没有像 NeRF 那样走「隐式连续场 + 体渲染」的路线,也没有回到传统三角网格的老路。它选择了一种介于两者之间的表示方法------用百万个可微分的三维高斯椭球,把整个场景显式地「糊」出来。然后直接上光栅化,不搞光线采样那套。
结果是:
- 训练时间:35-45 分钟(Mip-NeRF360 要 48 小时)
- 推理帧率:134 FPS(Mip-NeRF360 是 0.06 FPS)
- 渲染质量:持平甚至超过 previous SOTA
数据好看到有点离谱。这篇博客就来拆一下,它是怎么做到的。
1. 3DGS 到底在解决什么问题
1.1 NeRF做对了什么
NeRF的核心思路非常优雅:场景不是点云、不是网格、不是体素------而是一个连续的五维辐射场函数。给定一个空间位置 (x, y, z) 和一个观察方向 (θ, φ),它用 MLP 同时预测这个位置的密度 σ 和颜色 c。
这种连续表示的优点很明显:
- 无限分辨率:不存在离散化带来的锯齿或空洞
- 几何表达自然:MLP 隐式建模了连续表面
- 可微:一切端到端优化
1.2 但 NeRF 慢在哪
慢在渲染的每一步都有代价。
想象一下你要生成一张 1080p 的图(约 200 万像素)。对于每一个像素:
- 从相机光心发出一条光线
- 沿光线在近远平面之间均匀 + 重要性采样,比如 128 个点
- 每个点送入 MLP 推理密度和颜色
- 把 128 个采样点按体渲染公式积分,得到最终像素颜色
所以一张 1080p 画面,NeRF 要做的 MLP 推理量大约是:
2,000,000 像素 × 128 采样/像素 = 2.56 亿次 MLP 推理
哪怕 InstantNGP 用哈希编码把 MLP 做小,采样数量也降到了 20-30 个点,但本质上还是要沿光线做多次查询。而每条光线的查询之间缺乏空间局域性,缓存友好度低,GPU 利用率上不去。
问题根源在于:连续场表示本身,需要用「大量的随机采样」来近似积分。采样少了就噪,采样多了就慢。
1.3 点云一派也有自己的问题
和 NeRF 相对的思路是用显式几何做渲染。点云是最直接的------每个点带颜色,直接 splat 到屏幕上。速度快,但问题也很硬:
- 点与点之间有空洞
- 没有各向异性:一个点在屏幕上投影的形状永远是圆,没法表达平滑表面的连续过渡
- 渲染结果不连续:视角稍微一变,点的遮挡关系就可能突变
三角网格解决了连续性问题,但从多张照片重建高质量的网格(MVS)本身就是一个难题。重建失败的场景里,空洞和不准确几何会直接传染到渲染结果。
NeRF 和点云其实是一个两难选择:你选连续表示,就要被迫承受昂贵的体渲染;你选显式表示,就得处理空洞和不连续。
3DGS 的回答是:为什么不能两者都要?
2. 核心思想:把场景变成一堆会发光的高斯球
作者做了一个非常朴素但在当时很大胆的决定:不用 MLP,不用网格,直接用三维高斯函数作为场景的基本构成单元。
每个三维高斯可以看成一个半透明、带颜色、会变形的小椭球云团。它和点云的最大区别在于:
- 点云是一个零维的点,在数学上没体积
- 高斯是一个连续的三维密度分布,有形状、有大小、有朝向
每个高斯函数在三维空间中对周围区域的「贡献」是平滑衰减的------中心最强,越往外越弱,衰减速度由协方差矩阵控制。这种表示天然适合做体渲染的积分:你不需要像 NeRF 那样沿光线采样几百个点,因为高斯本身的形状就定义了一个连续的密度场。
那为什么不用三角网格?因为网格是显式表面,优化一个网格需要拓扑结构------顶点之间的连接关系是离散的。而高斯是独立的、无序的,每个高斯只对自己的参数负责,你可以在优化过程中随意增删,不需要操心拓扑一致性。
为什么不用体素?体素网格是离散的、均匀的。一个精细结构需要高分辨率网格,但均匀网格在空旷区域就是巨大的浪费。高斯可以自由地「拉长」或「压扁」来适应不同形状,本质上是一种自适应分辨率的表示。
高斯球:我只是个点云,怎么突然要承担实时渲染的 KPI?
但选对了基本单元只是第一步。真正让 3DGS 跑起来的,是后面的整套可微渲染管线。
3. 理论部分:想深入开发得看懂
这一部分没有复杂的推导,但需要理解每一条公式背后的几何直觉。
3.1 三维高斯的数学定义
一个三维高斯函数由两部分控制:
- 均值 μ ∈ ℝ³:高斯中心的位置,也是点云中的那个点
- 协方差矩阵 Σ ∈ ℝ³ˣ³:控制高斯在三个轴方向上的拉伸程度和旋转姿态
公式长这样:
G ( x ) = e − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) G(x) = e^{-\frac{1}{2}(x-\mu)^T \Sigma^{-1} (x-\mu)} G(x)=e−21(x−μ)TΣ−1(x−μ)
这个公式的几何含义是:给定一个空间点 x,它对这个高斯的「贡献权值」是多少。如果 x 在 μ 附近,G 的值接近于 1;距离越远,指数项越大,G 向 0 衰减。
协方差矩阵 Σ 才是最关键的参数。
假设我们把 Σ 做特征值分解:
Σ = R S S T R T \Sigma = R S S^T R^T Σ=RSSTRT
- R 是旋转矩阵(由四元数参数化)
- S = diag(s_x, s_y, s_z) 是三个轴上的缩放因子
特征向量决定了高斯椭球的三个主轴方向,特征值决定了每个轴上的「胖瘦」。这就意味着一个三维高斯可以表示任意轴对齐或旋转的椭球------它能被拉成一根细长的线(拟合树枝),也能被压成一个扁平的饼(拟合墙壁)。
这就是「各向异性」在物理层面的含义。
作者的直觉是:真实世界中的表面是连续的,但表面上不同的方向有不同的曲率变化率。如果每个高斯只能是一个圆球(各向同性),那你需要非常多小球来填满一个平滑斜面。但如果允许高斯在曲率低的维度上拉长,你只需要很少几个就能覆盖同样面积。
3.2 从三维椭球到二维椭圆
渲染是一个从 3D 到 2D 的过程。高斯虽然定义在三维空间里,但最终要投影到屏幕上。这就带来了一个问题:如何把一个三维高斯椭球投影成二维的椭圆?
答案来自经典的 EWA(Elliptical Weighted Average)Splatting 方法。
整个过程分三步走:
Step 1: 世界坐标 → 相机坐标
用视角变换矩阵 W(viewing transformation)把高斯中心 μ 从世界坐标系变换到相机坐标系。
Step 2: 投影变换
透视投影不是线性的,但 Zwicker 等人在 SIGGRAPH 2001 的文章里证明,在局部可以用一个仿射近似。这个近似的 Jacobian 矩阵 J 描述了:当三维空间中的点发生微小位移时,在屏幕上对应的像素位移是多少。
Step 3: 协方差投影
合并两步,得到相机坐标系下的协方差 Σ':
Σ ′ = J W Σ W T J T \Sigma' = J W \Sigma W^T J^T Σ′=JWΣWTJT
其中 J 是透视投影的 Jacobian 矩阵。这个公式的本质是:协方差矩阵作为一个二次型,在经历了线性和仿射变换后,变换方式就是两侧乘变换矩阵及其转置。 类似协方差传播的公式。
得到 Σ' 之后,取它的左上角 2×2 子矩阵------这就是投影到图像平面后的二维协方差,即屏幕空间的二维高斯椭圆。
这里有一个需要消化的细节:为什么 Σ' 是 3×3 的,却只取了 2×2 的子矩阵?
因为透视投影将 3D 点映射到 2D 齐次坐标(x, y, depth),而我们在光栅化阶段只需要知道这个高斯在 (x, y) 平面的形状。第三行第三列对应的是深度方向的信息,在二维椭圆中不需要。
3.3 为什么协方差不能直接优化
读到这里,你可能会想------为什么不直接在反向传播里更新 Σ 这个矩阵呢?
因为协方差矩阵有物理解释 要求:它必须是半正定的。
在梯度下降过程中,你直接更新一个 3×3 矩阵的元素,完全无法保证更新后的矩阵还是半正定的。一步更新,特征值可能变成负的,此时高斯就不再有「山峰」形状,物理上没有意义了。
作者的做法是:不直接优化 Σ,而是优化它的分解参数。
- 缩放因子 s ∈ ℝ³:控制三个轴的长度
- 旋转四元数 q ∈ ℝ⁴:控制三个轴的朝向
- 然后用公式 Σ = RSSᵀRᵀ 重建协方差矩阵
s 只需要用 exp 激活保证正数,q 只需要归一化保证单位长度。这样梯度下降无论如何更新,得到的 Σ 都天然半正定。
3.4 Alpha Blending:为什么它可以替代体渲染
终于到了渲染的核心------像素颜色怎么算出来的。
对于每个像素,它被若干投影到屏幕上的二维高斯椭圆覆盖。这些高斯从近到远排序,然后做透明度混合。
公式:
C = ∑ i = 1 N T i α i c i C = \sum_{i=1}^N T_i \alpha_i c_i C=i=1∑NTiαici
其中:
T i = ∏ j = 1 i − 1 ( 1 − α j ) T_i = \prod_{j=1}^{i-1} (1 - \alpha_j) Ti=j=1∏i−1(1−αj)
- cᵢ 是第 i 个高斯的颜色(由球谐函数算出)
- αᵢ 是该高斯在像素中心的不透明度(由高斯的二维投影值乘以一个学习的 opacity 参数算出)
- Tᵢ 是累积透射率,即从相机到第 i 个高斯之前,光线没有被拦住的概率
这和 NeRF 的体渲染公式在数学形式上完全等价------论文里专门推导了这一点(Eq. 2 vs Eq. 3)。
但两者的计算方式却天差地别:
- NeRF:沿光线采样 N 个点,每个点需要 MLP 推理,再积分
- 3DGS:把投影到像素上的高斯按深度排好队,然后从头到尾做一遍加权求和
体渲染是连续采样的离散近似,而 3DGS 的 α-blending 是一个显式的离散排序求和。 前者被迫采样是因为不知道密度场在何处变化,后者直接用高斯本身的形状定义了密度的空间分布,所以不需要采样。
GPU 在光栅化上的并行能力比在 MLP 推理上强得多。这是 3DGS 能跑快的核心原因之一。
4. 训练流程到底发生了什么?
把数学部分消化之后,整个训练流程其实已经不神秘了。让我们一步一步拆开来看。
4.1 初始化
你要训练 3DGS,至少需要一组多视角照片。用 COLMAP(或者任何 SfM 工具)做相机标定,COLMAP 顺带会产出一个稀疏点云。
每个点初始化成一个三维高斯。
- xyz:直接取 COLMAP 点的坐标
- scale:初始化为该点到最近三个相邻点距离的平均值(各向同性椭球)
- rotation:初始为单位四元数
- opacity:初始化为一个接近 0 的值,后面让优化自己去调
- SH 系数:初始化为 0,只保留零阶(漫反射)
COLMAP 给的点通常很稀疏------一个室内场景可能只有几万个点。但没关系,后面优化过程中会通过密度控制自动增删。
对于合成数据集(比如 NeRF-Synthetic 的 Blender 场景),COLMAP 点云都不需要------你甚至可以在场景包围盒内随机采样 10 万个点,优化过程中自动修剪到 6000-10000 个有效高斯。
4.2 可微渲染
初始化完毕之后进入优化循环:
for each iteration:
1. 随机选一张训练视图
2. 把当前所有高斯渲染到这张视图的相机位置 → 得到图像
3. 计算与真实图像的 L1 + D-SSIM 损失
4. 反向传播,更新所有高斯的参数
损失函数:
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
λ 在论文里取 0.2。L1 损失保证颜色准确,D-SSIM(structural dissimilarity)保证局部结构一致。
优化用的是 Adam,学习率调度的细节包括:
- 位置学习率使用指数衰减
- 前 250 步用 4 倍降分辨率训练,250-500 步逐步升回原分辨率(warm-up)
- SH 系数先只优化零阶(漫反射),每 1000 步增加一个频带,直至全部 4 阶
4.3 Adaptive Density Control(自适应密度控制)
这是 3DGS 最巧妙的设计之一。
场景中有不同尺度的结构:大片的墙面需要大高斯,细长的树枝需要小高斯。如果你在初始化时就固定了高斯的数量和大小,是不可能同时覆盖好这两种情况的。
作者的做法是:在优化过程中动态增删高斯。
关键判断依据:view-space positional gradient。
简单说,如果某个高斯在训练过程中,它在屏幕空间的位置梯度平均值很大,说明这个高斯所在的区域还没有被正确地拟合,优化器正在拼命地试图移动它来补偿误差。
作者设定了一个阈值 τ_pos = 0.0002。超过这个阈值的高斯被标记为「需要处理」。
处理方式有两种:
Clone(复制)
当高斯比较小,且处于欠拟合(under-reconstruction) 区域。
比如一个精细的网状结构,目前只有稀疏的几个高斯覆盖。这时候直接复制当前高斯,沿着梯度方向移动副本,增加该区域的密度。
效果:增加系统总「体积」,增加高斯数量。
Split(分裂)
当高斯比较大,且它覆盖的区域的变化剧烈(高方差)。
比如一个本该由多个小高斯拟合的曲边,但现在只有一个大高斯糊在那里。这时候把这个高斯切成两个,位置在新高斯的概率密度函数下采样,scale 除以一个经验系数 φ=1.6。
效果:保持系统总「体积」不变,但增加高斯数量。
Prune(剪枝)
每隔 N 步(N=3000),把所有 opacity 低于阈值 ε_α 的高斯直接移除。这个策略的原理解释:opacity 低的高斯本质上对最终渲染没有贡献,留着纯属浪费。更有意思的是,作者会定期把所有高斯的 opacity 重置到接近 0,然后让优化重新决定哪些高斯应该活着------只有那些确实被梯度支持的高斯才会重新获得较高的 opacity 值。
这相当于给高斯群体做了一次「自然选择」。
实际的增删演化
从 COLMAP 的几万个点开始,经过完整的训练(30K 迭代),一个典型场景最终会包含约 100-500 万个高斯。这些高斯会呈现出高度各向异性的形状------墙上贴着的扁平椭球、枝干上的细长椭球、水面附近的复杂簇------每一种形状对应着场景中的不同几何结构。
5. 为什么 3DGS 能这么快?
现在来回答那个最直观的问题:凭什么它比 NeRF 快这么多?
不需要 MLP 推理
3DGS 的渲染管线里没有神经网络。颜色用球谐函数直接计算------就是几个系数做线性组合加球谐基函数求值,一次 SIMD 指令搞定。相比 MLP 的矩阵乘法 + ReLU,这个开销可以忽略。
不需要沿光线采样
前面算过,NeRF 渲染一张图要 2 亿次以上的 MLP 推理。3DGS 的每个像素只需要对覆盖它的高斯做 α-blending------室内场景平均每个像素覆盖 10-30 个高斯。
这是 5-6 个数量级的差距,不叫优势,叫降维打击。
光栅化比体渲染更适合 GPU
体渲染的困境在于:虽然 GPU 可以并行处理所有像素的光线,但每条光线内部的采样点之间是顺序依赖的(transmittance 必须从近到远累积)。这使得 GPU 的并行效率大打折扣。
而 3DGS 的光栅化,本质上是:
- 每个高斯投影到屏幕上一个 2D 椭圆
- 每个像素遍历覆盖它的高斯列表,做 α-blending
这个过程在 GPU 上可以用类似传统游戏引擎的 tile-based 渲染高效实现。所有高斯的排序一次完成(GPU Radix sort),然后 16×16 像素为一个 tile,每个 tile 在独立的 thread block 内处理,内存访问局部性好,共享缓存利用率高。
复杂度对比
| 方法 | 训练时间 | 推理帧率(1080p) | 渲染方式 | 表示类型 |
|---|---|---|---|---|
| Mip-NeRF360 | 48 小时 | 0.06 FPS | 体渲染 + MLP | 隐式连续场 |
| InstantNGP | ~7 分钟 | 10-15 FPS | 哈希网格 + 小 MLP | 隐式(带加速结构) |
| Plenoxels | ~25 分钟 | 8-12 FPS | 稀疏体素 + 球谐 | 显式(体素) |
| 3DGS-7K | ~6 分钟 | 160 FPS | 高斯 Splatting | 显式(高斯) |
| 3DGS-30K | ~40 分钟 | 134 FPS | 高斯 Splatting | 显式(高斯) |
注意:3DGS-7K 训练 6 分钟,帧率 160 FPS。3DGS-30K 训练更久质量更高,帧率微降到 134 FPS(因为高斯更多了)。
这波属于空间换时间------用百万个可导的高斯参数换掉了 MLP 的推理成本。
6. 使用场景
3DGS 出来之后,应用落地几乎是顺理成章的。不是因为它是顶会论文,而是因为它的工程属性太好了。
数字孪生
工厂、园区、室内空间的精确重建。传统方法要么用激光扫描(贵),要么用 NeRF(慢)。3DGS 提供了一条折中路径:用普通相机拍摄,几十分钟训练,实时浏览。
VR/AR
VR 对帧率的要求是硬性的------低于 90 FPS 头晕。之前 NeRF 在 VR 里基本是 PPT 级别。3DGS 的实时帧率让它第一次具备了在 VR 头显里做场景浏览的可能。
文旅重建
考古遗址、古建筑、博物馆藏品的三维数字化。典型案例是浙江大学对多个文化遗址的 3DGS 重建。一个佛像拍几百张照片,训练几十分钟,就可以在网页端任意旋转缩放查看。
游戏资产生成
传统游戏资产制作流程:建模 → UV 展开 → 纹理烘焙 → LOD 生成。3DGS 提供了一条替代路径:从实拍 → 直接可用的渲染场景。虽然在交互性上还不能完全替代手工建模(下文会讲局限),但在大世界环境、远景填充这类场景中已经非常有用了。
自动驾驶仿真
收集一段道路的多视角视频 → 重建 3DGS → 在新视角下渲染。用在自动驾驶仿真器里生成多样化的训练数据。相比 NeRF 逐帧推理,3DGS 能做到实时仿真循环。
机器人环境建模
机器人需要在搭建好的场景里做任务规划,速度比画质更重要。3DGS 可以几分钟内重建一个房间,然后机器人可以实时在新视角下观察环境。
7. 3DGS 的问题
虽然 3DGS 的 paper 展示了极其漂亮的结果,但把它用到真实项目中的人很清楚:它离完美还有相当距离。
显存占用爆炸
每个高斯需要存储:3 维位置 + 4 维四元数 + 3 维 scale + 1 维 opacity + 48 维球谐(4 阶 SH = 16 个 RGB 系数)。一片场景几百到几百万的高斯,直接压进显存。
在实际运行中,300 万个高斯的场景显存占用大约 500-700 MB。这似乎还行,但如果你要渲染更大的场景------比如整个城市街区------高斯数量会飙升到几千万甚至更多。8GB 显存非常吃紧。
根本原因:3DGS 没有层次结构(LOD)。每个高斯无论大小远近,在 GPU 排序和渲染时都被平等对待。
高斯数量爆炸
adaptive density control 设计得相当巧妙,但也有副作用:它会倾向于不停地制造新高斯。
在纹理复杂的区域(比如树叶、草地),梯度反复触发 split/clone,高斯数量会失控地增长。论文里一套超参跑所有场景,但实际使用时往往需要针对场景调节 densification 阈值,否则会陷入「高斯越来越多,显存越来越少」的恶性循环。
动态场景困难
原版 3DGS 假设场景是静态的。这是因为它的核心假设是每个高斯从一个固定位置出发去拟合一个静态表面。如果场景里有动态物体,高斯的 position 会在不同视角下被拉向矛盾的方向。
后续有很多工作在做 Dynamic 3DGS(比如将高斯绑定到一个形变场上),但原版本身就支持不了。
编辑能力有限
这是 3DGS 目前最被吐槽的一点。
你有一个重建好的高斯场景,想做编辑------比如把桌子换成红色的------发现无从下手。高斯不像三角网格有明确的表面拓扑关系,每个高斯只有一堆参数。你很难回答「哪些高斯对应着这张桌子」这类问题。这也是为什么之后的 GaussianEditor 等工作要加语义分割能力。
大场景管理
3DGS 对 unbounded 场景的处理不算差,但如果你试图用一个 3DGS 重建整整一栋楼,所有高空远距离的高斯和近处的高斯混在一起排序,效率会急剧下降。而且因为高斯数量没有上限,场景边界越大,Gaussian 数量越线性增长------最后变成一个显存的无底洞。
8. 3DGS 之后发生了什么?
3DGS 发表于 SIGGRAPH 2023,之后的两年里各种改进和变体像雨后春笋一样冒出来。这里简单梳理一下方向。
Scaffold-GS(CVPR 2024)
解决了:高斯数量膨胀 + 缺乏结构的问题。
Scaffold-GS 引入了锚点机制:每个锚点负责管理一组子高斯,而不是让每个高斯在空间里自由飘荡。这样既控制了高斯总数的增长,又引入了层次化结构,使得 LOD 和场景裁剪变得自然。
Mip-Splatting(CVPR 2024)
解决了:多尺度渲染的 aliasing 问题。
原版 3DGS 在不同分辨率下渲染时,高斯投影的尺寸没有自适应调整。Mip-Splatting 对高斯做了3D 平滑滤波 和2D Mip 滤波,解决了 zoom-out 时出现的锯齿和闪烁。
Octree-GS
解决了:大场景管理 + LOD。
用八叉树结构来管理高斯,离相机近的区域用细粒度的高斯,远处用粗粒度。在城市场景、大规模室内场景中效果明显,显存占用大幅下降。
Dynamic 3D Gaussians
解决了:动态场景渲染。
把高斯的位置和旋转参数绑定到一个形变场(deformation field)上,或者用每个时间步分别预测高斯参数。实现了与 3DGS 画质相当的动态新视角合成。
GaussianEditor / 3DGS-Editor
解决了:场景编辑。
引入语义分割 + 掩码控制 + 扩散模型,先让用户指定要编辑的区域,再用文本引导编辑该区域内高斯的颜色和几何。虽然还不够精细,但至少迈出了第一步。
值得注意的是,这些改进方案没有一个是「推翻 3DGS 自己另起炉灶」------它们大部分是在原始的 Gaussian 表示和渲染引擎上加外围模块。这本身就在说明:3DGS 的底层设计是经得起推敲的。
收尾
过去几年,NeRF 像一个执着追求极致画质的艺术家,而 3DGS 更像一个懂工程落地的产品经理。它没有推翻神经渲染,而是换了一种表示方式,让实时新视角合成第一次真正具备了进入工业场景的可能。
从技术选择的逻辑上看,3DGS 的每一步------选高斯而不是体素、用各向异性协方差而不是各向同性、用 tile-based 光栅化而不是逐像素排序------都是在做一个共同的权衡:把计算量从渲染时提前到优化时。
NeRF 把几乎所有工作放在推理阶段------MLP 在渲染时才计算值。3DGS 把海量参数放在存储里------渲染时只需要查表做混合。一个重推理,一个重存储。
很难说哪个路线会最终胜出。但随着显存越来越便宜、场景越来越复杂,3DGS 这条「空间换时间」的路线,至少在实时渲染这个目标上,走得极其漂亮。
但话说回来:
如果 NeRF 的终点是学习一个连续场函数,那么 3DGS 的问题可能才刚刚开始------当场景被表示成数百万个可编辑的高斯之后,我们究竟是在做渲染,还是已经在构建一种新的三维操作系统?
这个问题,可能需要下一个 3DGS 级别的突破来回答。
以上个人整理,难免有误。若发现错误,欢迎在评论区留言指正,非常感谢!