深入理解 3D Gaussian Splatting (3DGS):从原理到实践
1. 引言:从 NeRF 到 3DGS
1.1 什么是新视角合成?
新视角合成(Novel View Synthesis, NVS) 是计算机视觉与图形学的经典任务:给定一个场景的多张已知视角图像,生成从任意新视角观察该场景的图像。
它在很多领域都有重要应用:
- VR/AR 内容生成:构建沉浸式三维场景
- 数字孪生:工业仿真、城市建模
- 影视特效:实拍场景的三维重建与编辑
- 文化遗产:文物、遗址的高保真数字化
- 自动驾驶:场景重建与仿真
过去几年,神经辐射场(NeRF) 是这个领域最耀眼的明星,但它的训练和渲染速度始终是痛点。直到 2023 年,3D Gaussian Splatting (3DGS) 横空出世,一举解决了”高质量 + 实时”这一对看似矛盾的需求。
1.2 3D Gaussian Splatting 是什么?
3D Gaussian Splatting (3DGS) 是 Kerbl 等人在 SIGGRAPH 2023 上提出的革命性方法,论文标题为 “3D Gaussian Splatting for Real-Time Radiance Field Rendering”。
它的核心思想非常优雅:
不再用隐式的神经网络表示场景,而是用一组显式的、各向异性的 3D 高斯椭球作为基本渲染单元,并通过可微的光栅化器将它们”泼溅”到图像平面上。
这里的 Splatting(泼溅) 是关键——它指的是将 3D 的高斯椭球投影到 2D 图像平面(投影后仍是高斯分布),再进行 alpha 合成。
1.3 为什么 3DGS 能引起轰动?
| 指标 | NeRF (原始) | Instant-NGP | 3DGS |
|---|---|---|---|
| 训练时间 | 数小时~数天 | 几分钟 | ~30-60 分钟 |
| 渲染速度 | 极慢(逐光线采样) | ~30 FPS | 30+ FPS @ 1080p |
| 显存占用 | 高 | 中等 | 与场景规模线性相关 |
| 显式编辑 | 困难 | 困难 | 天然支持(高斯可编辑) |
3DGS 在保持高质量重建的同时,把渲染速度提升到了实时级别,并且场景表示是显式的、可编辑的。
2. 为什么选择高斯椭球?
2.1 表示方法的演进
在讨论 3DGS 之前,我们先回顾一下场景表示方法的演进:
| 方法 | 表示形式 | 优点 | 缺点 |
|---|---|---|---|
| 点云(Point Cloud) | 离散点 + 颜色 | 简单、易获取 | 无体素、稀疏、不连续 |
| 体素网格(Voxel Grid) | 规则三维网格 | 规则、易采样 | 内存爆炸、分辨率受限 |
| Mesh(网格) | 顶点 + 面片 | 高效渲染、纹理清晰 | 难以从图像重建 |
| NeRF | MLP(隐式) | 连续表示、高质量 | 训练慢、渲染慢、难编辑 |
| 3DGS | 3D 高斯椭球 | 实时、显式、可编辑 | 场景文件较大 |
2.2 高斯椭球的直观理解
为什么是”椭球”而不是”球”?
各向异性(Anisotropy) 是关键。想象一个真实的物体表面:
- 细长的树枝:沿长度方向延伸,垂直方向较窄 → 需要细长椭球
- 平坦的墙面:几乎是一个平面 → 需要极扁的椭球(接近圆盘)
- 球形果实:各方向尺度相当 → 球形高斯即可
如果只能用球形高斯来表示这些结构,就需要数量巨大的小球,效率极低。椭球可以用更少的元素表达更丰富的几何形状,这是 3DGS 高效性的基础。
2.3 与点云的关系
3DGS 可以看作是一种”升级版”的点云:
- 点云:每个点是一个 (x, y, z, color) 的零维样本
- 3DGS:每个”点”是一个有位置、形状(协方差矩阵)、颜色、不透明度的三维概率分布
这种”带体积”和”带朝向”的特性,使得 3DGS 既能表达几何,也能表达外观,并且渲染时不会有”空洞”。
3. 数学基础:3D 高斯椭球的表示
3.1 单个高斯的参数化
场景中第 个高斯椭球由以下参数定义:
其中:
- :均值向量(高斯的中心位置)
- :协方差矩阵(决定椭球的形状与朝向)
为了保证协方差矩阵的半正定性(即数学上构成有效的椭球),3DGS 采用了巧妙的分解方式:
其中:
- :从四元数 构造的旋转矩阵
- :缩放矩阵(三个轴方向的尺度)
3.2 各向异性与各向同性
|| 概念 | 协方差矩阵 | 视觉效果 | ||------|------------|----------| || 各向同性(Isotropic) | (球形) | 球状云团 | || 正交各向异性(Orthotropic) | | 沿坐标轴对齐的椭球 | || 完全各向异性(Anisotropic) | (任意朝向) | 任意朝向的椭球(3DGS 使用) |
3DGS 选择了完全各向异性的椭球,这让每个高斯都能精确地贴合局部几何结构。
这里是付费内容
3.3 完整参数列表
每个高斯椭球 的参数总结:
| 参数 | 符号 | 维度 | 含义 | 优化方式 |
|---|---|---|---|---|
| 位置 | 3 | 高斯的中心 | 直接优化(梯度下降) | |
| 旋转 | 4(四元数) | 椭球的朝向 | 直接优化 + 归一化 | |
| 缩放 | 3 | 三轴尺度 | 通过 保证正值 | |
| 不透明度 | 1 | 椭球的”密度” | 通过 约束到 | |
| 球谐系数 | 视角相关颜色 | 直接优化 |
球谐函数(Spherical Harmonics, SH) 用于表示视角相关的辐射场——这就是为什么 3DGS 能够正确渲染出镜面反射等视角相关效果,而不仅仅是漫反射。
3.4 视角相关颜色的直观理解
传统点云的颜色是固定的(RGB),但 3DGS 引入球谐后可以表达:
- 漫反射:低阶球谐即可表达
- 高光 / 镜面反射:需要高阶球谐(视角变化时颜色会变)
例如,看一个金属球时,正面和侧面看到的颜色亮度不同——这正是 SH 表达的能力。
4. 核心创新:可微 3D 高斯光栅化
4.1 传统光栅化与可微光栅化
要把 3D 椭球渲染成 2D 图像,需要解决两个问题:
- 可见性(Visibility):从当前相机视角,哪些高斯是可见的?
- 可微性(Differentiability):渲染结果对每个高斯的参数都是可导的,这样才能用梯度下降优化。
3DGS 的最大贡献之一,是第一个高效的可微 3D 高斯光栅化器。
4.2 椭球的 2D 投影
给定一个 3D 高斯椭球()和一个相机(投影矩阵 ),其 2D 投影仍然是高斯分布。
具体来说,2D 投影后的协方差矩阵为:
其中:
- :世界到相机的变换矩阵的 部分
- :相机投影函数的雅可比矩阵(Jacobian)
直观上:
3D 椭球投影到 2D 图像上仍然是椭球,只是形状和大小随视角变化(近大远小)。
4.3 分块排序(Tile-Based Rasterization)
3DGS 的渲染器采用分块(Tile)并行策略:
- 将屏幕划分为若干小块(如 像素)
- 视锥剔除(Frustum Culling):剔除完全不在视锥内的高斯
- 逐高斯处理:对每个高斯,计算它覆盖哪些 tile
- 将高斯分配到对应 tile 的列表中(同一高斯可能分配到多个 tile)
- 对每个 tile 内部的高斯按深度排序
- alpha 合成(Alpha Compositing):在每个 tile 内从前向后合成像素颜色
这种策略既保证了渲染速度,又避免了对所有高斯做全局排序的代价。
4.4 Alpha 合成公式
最终的像素颜色 由所有覆盖该像素的高斯按从前到后的顺序合成:
其中:
- :第 个高斯的颜色(由 SH 和视角决定)
- :该高斯对当前像素的不透明度贡献
- :累积透射率(到第 个高斯时,光线尚未被遮挡的比例)
注意:这里 的计算必须从前往后,但 的梯度计算则依赖从前向后的链式求导——这与 NeRF 体渲染的”从后往前”积分有本质区别。
4.5 简化代码示意
虽然完整的光栅化器需要数百行 CUDA 代码,但核心逻辑可简化为:
import torch
def render_pixel(tile_gaussians, pixel_uv): """ tile_gaussians: 当前 tile 覆盖的高斯(按深度排序) pixel_uv: 目标像素坐标 """ color = torch.zeros(3, device=pixel_uv.device) transmittance = torch.ones(1, device=pixel_uv.device)
for gauss in tile_gaussians: # 2D 高斯在该像素处的不透明度 alpha = compute_2d_alpha(gauss, pixel_uv)
# alpha 合成 color += transmittance * alpha * gauss.color transmittance *= (1.0 - alpha)
# 早期终止:透射率足够小 if transmittance.item() < 1e-4: break
return color5. 自适应密度控制(Adaptive Density Control)
5.1 为什么需要密度控制?
初始化时,3DGS 通常使用稀疏点云(来自 COLMAP 或随机采样)作为高斯中心。如果高斯数量太少,几何不完整;太多,又会导致冗余和浪费。3DGS 在训练过程中动态增减高斯,这是其高效性的关键之一。
5.2 克隆(Cloning / Densification)
对于欠重建区域(几何细节缺失),即高斯的位置梯度大但形状扁平:
- 克隆:在该高斯周围复制一份,沿位置梯度方向略微移动
适合场景:欠重建的小细节(如物体的微小结构)
5.3 分裂(Splitting)
对于过度重建区域,即一个高斯覆盖了过大的范围:
- 分裂:将一个大高斯替换为两个稍小的高斯,沿着最大缩放方向
适合场景:大而扁平的高斯需要更细粒度的表达
5.4 周期性修剪(Periodic Pruning)
每经过若干次迭代,还需要做剪枝:
- 删除不透明度极低的高斯(透明,几乎不可见)
- 删除在训练视角下体积过大的高斯(通常是漂浮物)
5.5 密度控制伪代码
def adaptive_density_control(gaussians, optimizers, viewspace_grad, t): if t % 1000 != 0: return gaussians
# 提取平均位置梯度 avg_grad = viewspace_grad.norm(dim=-1).mean(dim=0) # (N,)
# 判断需要克隆还是分裂 mask_clone = (avg_grad > GRAD_THRESH) & (gaussians.scale.max(dim=1) < SCALE_THRESH) mask_split = (avg_grad > GRAD_THRESH) & (gaussians.scale.max(dim=1) >= SCALE_THRESH)
# 克隆 gaussians.clone(mask_clone) # 分裂 gaussians.split(mask_split) # 剪枝 gaussians.prune(opacity < 0.005)
# 重置优化器状态 reset_optimizer(optimizers, gaussians) return gaussians6. 训练流程
6.1 整体流程图
3DGS 的训练过程是一个迭代优化:
输入图像 + COLMAP 标定 ↓ 初始化点云 → 初始化高斯椭球 ↓ ┌────────────────────────────┐ │ 迭代优化 (30000 次) │ │ ├─ 渲染当前视角 │ │ ├─ 计算损失 L1 + SSIM │ │ ├─ 反向传播 │ │ ├─ Adam 优化器更新参数 │ │ └─ 周期性自适应密度控制 │ └────────────────────────────┘ ↓ 输出: 优化后的高斯集合 + 球谐系数 ↓ 实时渲染(1080p @ 30+ FPS)6.2 损失函数
3DGS 使用一个组合损失:
其中:
- :像素级 L1 损失
- :结构相似性损失(SSIM)
- :通常设为 0.2
SSIM 损失 让 3DGS 在保持锐利边缘的同时,获得更好的整体结构相似性。如果只用 L1,结果会偏模糊。
6.3 优化器与学习率
3DGS 使用 Adam 优化器,但不同参数有不同的学习率:
| 参数 | 学习率 | 说明 |
|---|---|---|
| 位置 | 较慢,避免位置漂移 | |
| 旋转 | 较快,配合归一化 | |
| 缩放 | 通过 变换 | |
| 不透明度 | 较快,便于剪枝 | |
| 球谐系数 | 适度 | |
| 球谐阶数 | 每 1000 步提升 1 阶 | 关键:1→2→3,渐进式 |
渐进式球谐阶数提升 是个精妙的设计:先用低阶(漫反射)稳定几何,再逐渐引入高阶(视角相关效果),避免训练早期因高阶球谐不稳定而导致的退化。
6.4 典型训练时间
| 场景规模 | 高斯数量 | 训练时间(单 GPU) |
|---|---|---|
| 简单物体 | ~50k | ~10 分钟 |
| 一般场景 | 100k~1M | 30~60 分钟 |
| 大型场景 | 1M~5M | 1~2 小时 |
| 城市级别 | 10M+ | 数小时 |
3DGS 在一张 RTX 4090 上即可训练大多数场景,是 NeRF 难以想象的便利。
7. 完整示例:基于 gsplat 库的训练
7.1 环境准备
pip install gsplat torch torchvision# 或pip install "gsplat[all]"7.2 核心训练代码
import torchfrom gsplat import rasterizationfrom torch import nnfrom torch.optim import Adam
class GaussianModel(nn.Module): def __init__(self, points, colors): super().__init__() N = points.shape[0] # 位置 self.means = nn.Parameter(points) # 缩放(取 log 保证正值) self.scales = nn.Parameter(torch.full((N, 3), -3.0)) # 旋转(四元数) self.quats = nn.Parameter(torch.zeros(N, 4)) self.quats.data[:, 0] = 1.0 # 初始化为单位四元数 # 不透明度(取 logit) self.opacities = nn.Parameter(torch.full((N,), 0.5).logit()) # 球谐系数(这里只用 0 阶,即 DC 颜色) self.colors = nn.Parameter(colors)
def forward(self, camera): # 调用可微光栅化器 out_img, out_alpha, _ = rasterization( means=self.means, quats=self.quats, scales=torch.exp(self.scales), opacities=torch.sigmoid(self.opacities), colors=self.colors, viewmats=camera.viewmat, Ks=camera.K, width=camera.W, height=camera.H, ) return out_img7.3 训练循环
import torch.nn.functional as Ffrom torchmetrics.image import StructuralSimilarityIndexMeasure
ssim = StructuralSimilarityIndexMeasure(data_range=1.0)
def train_step(model, optimizer, view): rendered = model(view) # (1, H, W, 3) gt = view.image.unsqueeze(0) # (1, H, W, 3)
l1 = F.l1_loss(rendered, gt) loss_ssim = 1 - ssim(rendered.permute(0, 3, 1, 2), gt.permute(0, 3, 1, 2)) loss = 0.8 * l1 + 0.2 * loss_ssim
optimizer.zero_grad() loss.backward() optimizer.step() return loss.item()8. 3DGS vs NeRF:深度对比
8.1 本质区别
| 维度 | NeRF | 3DGS |
|---|---|---|
| 表示方式 | 隐式(MLP) | 显式(3D 高斯集合) |
| 渲染方式 | 沿光线采样 | 高斯泼溅 + alpha 合成 |
| 训练 | 一次 MLP 训练 | 逐高斯参数优化 |
| 渲染速度 | 慢(每像素 ~100 次采样) | 快(无采样) |
| 显存占用 | 与图像分辨率相关 | 与高斯数量相关 |
| 场景编辑 | 困难 | 天然支持(直接操作高斯) |
8.2 性能基准
在 Mip-NeRF 360 基准测试上的典型结果:
| 方法 | PSNR ↑ | SSIM ↑ | LPIPS ↓ | FPS ↑ |
|---|---|---|---|---|
| NeRF | 27.21 | 0.749 | 0.229 | <1 |
| Instant-NGP | 28.18 | 0.796 | 0.207 | ~30 |
| Mip-NeRF 360 | 29.13 | 0.844 | 0.184 | <1 |
| 3DGS | 30.41 | 0.870 | 0.149 | ~120 |
3DGS 在所有指标上都优于之前的 SOTA,并且渲染速度提升了 100 倍以上。
8.3 各自的适用场景
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 静态场景实时渲染 | 3DGS | 速度与质量兼得 |
| 大规模 / 城市级重建 | 3DGS + 分块 | 高斯可分布式管理 |
| 极稀疏视角(< 10 张) | NeRF 变体 | 3DGS 难以稳定 |
| 动态场景 / 4D | 4D-GS / DyNeRF | 需要时序建模 |
| 神经语义编辑 | NeRF + Instruct-Nerf2NeRF | 隐式表示便于编辑 |
| 物理仿真 / 碰撞 | 3DGS | 显式几何可直接用于物理 |
| 场景重建 + 物理仿真 | PhysGaussian | 3DGS 的显式性优势 |
9. 进阶主题
9.1 动态场景:4D-GS
将时间维度引入,每个高斯带时间相关的形变场,可以重建动态场景:
代表工作:4D-GS、Deformable 3DGS、Dynamic 3D Gaussians。
9.2 大规模场景:VastGaussian
面对城市级大场景,单卡训练困难。VastGaussian 提出分区域训练 + 全局合并策略:
- 将场景分为多个子区域
- 每个子区域独立训练 3DGS
- 用”代理高斯”(progressive merging)合并子区域结果
9.3 物理仿真:PhysGaussian
3DGS 是显式几何,可以直接用于物理仿真。PhysGaussian 实现了:
- 通过高斯密度场恢复连续体积密度
- 在仿真器(如 Material Point Method, MPM)中代入 进行物理求解
- 可以模拟切割、碰撞、形变等交互效果
9.4 编辑:GaussianEditor / Instruct-GS2GS
利用 InstructPix2Pix 或 Segment Anything (SAM) 等 2D 基础模型,引导 3DGS 的局部编辑:
- 文本指令:“把这个杯子变成红色”
- 选择性替换部分高斯的颜色 / 球谐系数
9.5 压缩:LightGaussian / CompGS
3DGS 场景文件通常较大(数百 MB 到 GB)。压缩方向:
- 剪枝冗余高斯
- 球哈系数低位量化
- 矢量量化 + 熵编码
- 网格化封装
代表方法可在保持 95%+ 质量的同时,将模型缩小 10~25 倍。
10. 关键数学公式汇总
为方便查阅,下面列出本文涉及的核心公式:
- 3D 高斯椭球:
- 协方差分解:
- 2D 投影协方差:
- Alpha 合成:
- 总损失:
- 参数激活函数:
11. 总结与展望
3DGS 的核心贡献
- 显式表示:用一组 3D 高斯椭球作为基本渲染单元,每个椭球带有位置、形状、颜色、视角相关辐射
- 可微光栅化器:第一个支持高效反向传播的 3D 高斯光栅化器
- 自适应密度控制:训练过程中动态增删高斯,使场景表示既紧凑又完整
- 实时高质量:在 RTX 4090 上 1080p 实时渲染,PSNR 优于 NeRF
当前挑战
- 场景文件较大:动辄数百 MB
- 稀疏视角不稳定:训练图像太少时容易过拟合
- 动态 / 4D 建模:仍处于早期阶段
- 编辑可控性:相比 NeRF 更可控,但工业级工具链尚不成熟
未来方向
| 方向 | 代表工作 / 思路 |
|---|---|
| 动态 4D 重建 | 4D-GS、Dynamic 3DGS |
| 大规模场景 | VastGaussian、城市级分块训练 |
| 物理交互 | PhysGaussian、GaussianSim |
| AI 编辑 | GaussianEditor、Instruct-GS2GS |
| 模型压缩 | LightGaussian、CompGS、剪枝量化 |
| 端到端应用 | 自动驾驶仿真、机器人具身、重光照、姿态估计 |
3D Gaussian Splatting 不仅是一项渲染技术,它正在成为新一代三维内容创作的”基础设施”——像 LLM 之于文本、Stable Diffusion 之于图像一样,重新定义我们生成、编辑、交互三维场景的方式。
参考资料
- Kerbl, B., Kopanas, G., Leimkühler, T., & Drettakis, G. (2023). “3D Gaussian Splatting for Real-Time Radiance Field Rendering.” ACM Transactions on Graphics (SIGGRAPH).
- Mildenhall, B., et al. (2020). “NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis.” ECCV.
- Müller, T., et al. (2022). “Instant Neural Graphics Primitives with a Multiresolution Hash Encoding.” ACM Transactions on Graphics (SIGGRAPH).
- Barron, J. T., et al. (2022). “Mip-NeRF 360: Unbounded Anti-Aliased Neural Radiance Fields.” CVPR.
- Wu, G., et al. (2024). “4D Gaussian Splatting for Real-Time Dynamic Scene Rendering.” CVPR.
- Lin, J., et al. (2024). “VastGaussian: Vast 3D Gaussians for Large Scene Reconstruction.” CVPR.
- Xie, T., et al. (2024). “PhysGaussian: Physics-Integrated 3D Gaussians for Generative Dynamics.” CVPR.
- Ye, M., et al. (2024). “GaussianEditor: Editing 3D Gaussians with Text Prompts.” CVPR.
- Fan, Z., et al. (2024). “LightGaussian: Unbounded 3D Gaussian Compression with 15x Reduction.” CVPR.
- Kerbl, B., et al. (2024). “Hierarchical 3D Gaussian Splatting (HGS).” ACM TOG.
- Zwicker, M., Pfister, H., van Baar, J., & Gross, M. (2001). “EWA Splatting.” IEEE TVCG — 3DGS 的数学前身。
- “gsplat: An Open-Source Library for Gaussian Splatting.” GitHub: nerfstudio-project/gsplat.
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!

