3D Gaussian Splatting 入门:从照片到可自由浏览的三维场景
面向第一次接触 3DGS 的读者,解释它解决什么问题、如何从照片生成场景、与 Mesh、点云和 NeRF 有何不同,以及应如何判断它是否适合真实项目。
如果你只看 3D Gaussian Splatting(3DGS)的演示,它很像一种“把手机视频变成真实三维世界”的魔法:墙面的旧痕、树叶间的半透明、玻璃反光和室内光照都被保留下来,用户还能移动视点,而不是被困在原来的拍摄机位。
真正准确的理解是:**3DGS 是一种以新视角合成为首要目标的场景表示与渲染方法。**它擅长回答“从这个新机位看过去,画面应该是什么样”,却不会自动给出可用于 CAD、碰撞检测或物理模拟的可靠表面。
这个差别决定了 3DGS 适合什么、不适合什么,也解释了为什么一个看起来极其真实的 splat 场景,近看可能出现漂浮物,人物走进去也可能直接穿墙。
3DGS 到底解决了什么问题
假设你围绕一个房间拍了几百张照片。希望计算机生成任意新机位下的画面,需要同时解决三件事:
- 每张照片从哪里、朝哪个方向拍摄;
- 空间中有什么结构和颜色;
- 新相机看到哪些内容、遮住哪些内容,以及最终像素如何合成。
传统摄影测量通常先恢复相机位姿,再建立点云和 Mesh,最后生成纹理。它得到的是传统图形管线熟悉的几何资产,便于测量和编辑;但头发、细枝、反射、高光和半透明等外观很难用干净的表面与纹理完整表达。
NeRF 走的是另一条路线:用神经网络表示连续的空间位置、观察方向、密度和颜色,再沿每条相机光线反复采样并进行体积渲染。NeRF 原论文把场景表示为一个从五维坐标到密度和视角相关颜色的连续函数,优化目标同样是让渲染图逼近输入照片。NeRF 项目页
3DGS 保留了辐射场“直接拟合图像外观”的思路,但不再让渲染器沿光线不断查询大型网络。它显式维护大量带方向和大小的三维 Gaussian,把它们投影到屏幕上,再按可见性和透明度合成。原始工作把三个部分组合起来:从相机标定产生的稀疏点初始化、Gaussian 参数与密度控制的交替优化,以及面向 GPU 的可见性感知 splatting。3DGS 官方项目页
一个 Gaussian 保存了什么
不要把 Gaussian 想成普通点云里的“一个彩色点”。一个典型 Gaussian 至少携带:
- 三维中心位置
μ; - 旋转与三个方向上的尺度,它们共同决定椭球形状;
- 透明度
α; - 基础颜色以及用于表达视角相关颜色的球谐系数(Spherical Harmonics,SH)。
椭球中心贡献最大,向边缘平滑衰减。多个椭球可以沿墙面拉长,也可以用许多小 Gaussian 逼近叶片、头发和细碎反光。训练会反复移动、缩放、旋转、复制、拆分或删除这些 primitive,直到从训练相机看过去时,渲染图尽量接近原图。
这也是 3DGS 与普通点云的关键差异:点云通常记录采样结果,3DGS 的 Gaussian 是为了图像重建而学习出来的可渲染 primitive。
从照片到可浏览场景的完整链路
1. 采集照片或视频
输入可以是相机照片,也可以是从视频抽取的帧。相邻画面必须有足够重叠,曝光、白平衡和焦距最好保持稳定。相机移动时需要产生视差;站在原地只旋转镜头,无法为三维结构提供足够证据。
动态的人、车、树叶和屏幕内容会破坏“所有照片观察同一个静态世界”的假设。镜子和透明物体则会让同一空间位置在不同视角呈现完全不同的内容。
2. 求解相机位姿和稀疏结构
训练并不知道每张照片从哪里拍摄,因此一般先用 Structure-from-Motion(SfM)寻找跨图像特征对应,恢复相机位置、方向和稀疏点云。COLMAP 是最常见的开源实现之一,同时提供 SfM 与 Multi-View Stereo。COLMAP 文档
这一步失败时,后面的训练再久也救不回来。典型迹象包括:大量图片未注册、相机轨迹断裂、房间被错误折叠,或重复纹理导致两个区域粘到一起。
3. 优化 Gaussian
稀疏点提供初始位置,优化器选择训练相机、渲染当前 Gaussian、计算渲染图与真实照片的误差,再更新位置、形状、透明度和颜色。误差持续较大的区域可能增加 Gaussian,贡献过小或异常膨胀的 Gaussian 会被删除。
Nerfstudio 的 Splatfacto 就是一个工程化实现,它使用 gsplat 作为 CUDA rasterization 后端,并可以直接使用 COLMAP 或 ns-process-data 产生的稀疏点初始化。Splatfacto 文档
4. 清理、压缩和交付
训练输出往往包括采集者、天空中的漂浮点、反光产生的伪影和不可见区域的错误 Gaussian。它还可能坐标轴不一致、尺度未知、文件过大。
因此生产前通常需要裁剪、删除离群点、调整朝向和原点、压缩属性、建立 LOD,并在目标渲染器里检查。SuperSplat 提供了浏览器中的查看、裁剪、优化和发布流程,是理解 3DGS 资产交付很方便的开源工具。SuperSplat 文档
为什么它看起来比 Mesh 扫描更真实
3DGS 优化的是训练图像上的颜色重建,而不是先逼迫世界变成干净三角面。这让它能自然保留一些难以建模的现象:
- 毛发、草木和细枝造成的软边缘;
- 高频纹理和细碎结构;
- 训练视角范围内的高光与反射;
- 烟雾、玻璃边缘和半透明外观;
- 复杂光照已经形成的明暗关系。
但“保留了外观”不等于“理解了材质”。很多 3DGS 资产把拍摄时的阴影、高光和环境光一起烘进颜色。把太阳移到另一边,阴影不会自动改变;把虚拟物体放进去,它也不一定会得到正确反射。
它为什么不是一种新 Mesh
Mesh 明确告诉渲染器哪些顶点组成哪个三角面,表面在哪里、法线朝哪里、两个区域是否相连。Gaussian 是重叠的软体分布,通常没有封闭拓扑,也没有可靠的内外关系。
因此以下能力都不是原始 3DGS 自动具备的:
- 碰撞、导航与刚体物理;
- 精确测量和工程尺寸;
- 骨骼蒙皮和传统动画;
- PBR 材质编辑与任意重光照;
- 可靠深度写入、阴影和全局光照;
- 对象级选择、语义和业务属性。
工程上常见的答案不是“只选 Mesh 或只选 3DGS”,而是混合表示:Mesh 负责碰撞、深度和可编辑结构,3DGS 负责真实外观。
怎样判断一个 3DGS 结果是否真的好
只看作者挑选的一段环绕视频远远不够。至少需要检查:
| 检查项 | 要观察什么 | 常见失败 |
|---|---|---|
| 新视角 | 未参与训练的机位是否稳定 | 画面拉伸、浮点突然出现 |
| 近景 | 靠近表面时是否仍有细节 | 椭球变大、表面像毛毡 |
| 时间稳定 | 连续移动相机时是否闪烁 | popping、排序变化、漂浮物 |
| 几何 | 深度和法线是否符合任务需要 | 墙面厚度错误、边界穿透 |
| 资源预算 | 文件、显存、首屏和帧率 | 桌面流畅、手机无法加载 |
| 可编辑性 | 是否能分对象、改光照和碰撞 | 所有外观粘成一个整体 |
论文常用 PSNR、SSIM、LPIPS 和 FPS;产品还必须记录资产大小、首次加载、显存峰值、目标设备帧率、失败视角和网络条件。
哪些项目现在适合采用 3DGS
很适合
- 房产、展馆、遗址和真实地点的自由视点浏览;
- 虚拟制片中的实景采集和机位预览;
- 影视、广告和电商中的高保真实物展示;
- 机器人或数字孪生系统里的视觉外观层;
- 对真实感要求高、交互结构较少的 VR 场景。
适合混合方案
- 游戏场景:Splat 负责环境外观,Mesh 负责碰撞和导航;
- AR:Splat 负责现实外观,深度或 Mesh 负责遮挡和锚定;
- 数字人:骨骼和参数化人体负责驱动,Gaussian 负责皮肤、头发和衣服外观;
- 城市级场景:需要层级、分块、LOD、流式加载和语义索引。
不应只依赖 3DGS
- 测绘、CAD 和尺寸必须可信的任务;
- 需要任意拆装、形变、布料和破坏的游戏资产;
- 强依赖动态光照、材质参数和光线路径的产品;
- 输入覆盖很少却要求完全准确还原不可见区域的任务。
建立正确的学习顺序
理解 3DGS 最容易走的弯路,是一开始就被数百个论文变体和仓库淹没。更稳妥的顺序是:
- 先理解它是“显式 Gaussian + 图像优化 + splat rasterization”;
- 再理解协方差、投影、排序和 alpha 合成;
- 亲手跑通静态数据,观察采集和相机位姿如何影响结果;
- 再学习压缩、动态场景、Avatar、流媒体和 XR;
- 最后根据目标任务补 Mesh、语义、物理或重光照能力。
本系列后续文章就按这个顺序展开。下一篇会进入 Gaussian 的数学属性和 GPU 渲染过程,但只保留理解工程实现所需的公式。