本课紧接 L4。你在 L4 中用 nerfacto 训练了一个 NeRF,现在用同一数据集训练 3D Gaussian Splatting,亲自感受两种方法在速度、质量和交互性上的差异。
L2 你已经理解了原理差异:NeRF 用隐式 MLP,3DGS 用显式高斯点云。但原理差异和工程差异是两回事。真正做项目时,你需要回答的是:
nerfstudio 同时支持 nerfacto(NeRF)和 splatfacto(3DGS),用同一数据、同一评估 pipeline 做对比,是建立选型直觉的最佳方式。
在大多数静态场景上,3DGS 的训练速度快 10-100 倍,渲染速度快 100+ 倍,质量与 NeRF 相当甚至更好。代价是显存占用更高(高斯参数显式存储),且对透明/反射物体处理较差。
splatfacto 是 nerfstudio 对 3D Gaussian Splatting 的实现。与原始 3DGS 代码相比,splatfacto 做了以下工程改进:
| 特性 | 原始 3DGS | splatfacto |
|---|---|---|
| 训练接口 | 独立仓库,自定义脚本 | ns-train splatfacto,统一 CLI |
| 数据格式 | COLMAP 输出 | 复用 nerfstudio 的 transforms.json |
| Viewer | 原生实时 viewer | nerfstudio Web Viewer |
| 评估 | 手动计算指标 | ns-eval 统一评估 |
| 导出 | PLY 点云 | PLY + 多种格式 |
| 超参调节 | 修改源码 | Hydra 配置系统 |
如果你已经装好了 nerfstudio(L4 完成),splatfacto 无需额外安装,直接可用。
用 L4 相同的 poster 数据集,训练 splatfacto,然后逐项对比。
ns-train splatfacto --data data/nerfstudio/poster
注意几个与 nerfacto 训练的不同体验:
ns-eval --load-config outputs/poster/splatfacto/.../config.yml \
--output-path eval-splatfacto.json
将结果与 L4 的 nerfacto 评估结果对比,填入下表:
| 指标 | nerfacto (NeRF) | splatfacto (3DGS) |
|---|---|---|
| 训练时间 | ~30 min (30k iters) | ~5-10 min (30k iters) |
| PSNR ↑ | ~30-33 dB | ~31-34 dB |
| SSIM ↑ | ~0.90-0.95 | ~0.92-0.97 |
| LPIPS ↓ | ~0.05-0.12 | ~0.04-0.10 |
| 渲染速度 | ~1-2 fps (全分辨率逐帧推理;Viewer 交互时通过自适应分辨率可达更高帧率) | ~60+ fps (光栅化) |
| 模型大小 | ~10-50 MB (MLP 权重) | ~100-500 MB (高斯参数) |
| 显存占用 (训练) | ~4-8 GB | ~6-12 GB |
典型结果:3DGS 在各项指标上持平或略优,训练速度和渲染速度则有数量级提升。
3DGS 的训练逻辑与 NeRF 完全不同。NeRF 是「优化一个 MLP 的权重」,3DGS 是「优化一组高斯点的参数,并在训练过程中动态增删高斯点」。因此它的超参数含义也不同。
ns-train splatfacto \
--pipeline.model.num-random 50000 \
--pipeline.model.sh-degree 3 \
--data data/custom/
| 参数 | 含义 | 默认值 | 调整建议 |
|---|---|---|---|
num-random | 初始随机高斯点数量 | 50000 | 场景大/细节多时增加;显存受限时减少 |
sh-degree | 球谐函数阶数 | 3 | 阶数越高颜色越丰富;0 阶=视角无关颜色,3 阶=全彩 |
random-init | 随机初始化 vs SfM 点云初始化 | false | 有 COLMAP 点云时设为 false(更好);无点云时设为 true |
这是 3DGS 最核心的机制。训练过程中,系统根据梯度自动决定:分裂大的高斯、克隆透明区域的高斯、删除透明度过低的高斯。
ns-train splatfacto \
--pipeline.model.densify-grad-thresh 0.0002 \
--pipeline.model.densify-size-thresh 0.01 \
--pipeline.model.cull-alpha-thresh 0.1 \
--data data/custom/
| 参数 | 含义 | 默认值 | 调整建议 |
|---|---|---|---|
densify-grad-thresh | 梯度阈值,超过则触发分裂/克隆 | 0.0002 | 场景细节不足时降低(更激进地增加高斯) |
densify-size-thresh | 高斯大小阈值,超过则分裂 | 0.01 | 大场景中提高(避免过早分裂) |
cull-alpha-thresh | 透明度阈值,低于则删除高斯 | 0.1 | 出现「空洞」时降低;出现噪点时提高 |
想象你在用橡皮泥捏一个雕像:
训练结束后,高斯数量通常会从 5 万增长到 50-200 万。数量越多,细节越丰富,显存占用也越高。
3DGS 的 Viewer 体验与 NeRF 有本质差异。NeRF 的 Viewer 是「实时发送相机位置 → 服务器推理 → 返回像素」,每次视角移动都需要网络传输 + GPU 计算。3DGS 的 Viewer 是「高斯参数一次性上传到 GPU → 本地光栅化渲染」,视角移动完全在本地完成。
实际感受:
| 操作 | nerfacto Viewer | splatfacto Viewer |
|---|---|---|
| 旋转视角 | 略有延迟,低分辨率预览 → 高分辨率填充 | 即时响应,全分辨率 |
| 缩放远近 | 等待推理 | 即时响应 |
| 相机路径录制 | 需要后台渲染 | 实时预览最终效果 |
| 导出视频 | 逐帧推理,耗时 | 光栅化,快 10-100 倍 |
这种实时性不仅是「体验好」,它直接决定了 3DGS 能否用于实时应用(VR/AR、游戏、Web 展示),而 NeRF 目前主要还是离线渲染。
3DGS 的显式表示让它在导出方面有独特优势。
ns-export gaussian-splat \
--load-config outputs/poster/splatfacto/.../config.yml \
--output-dir exports/poster_gs/
导出后得到一个 .ply 文件,包含每个高斯的完整参数:
x, y, z:位置nx, ny, nz:法线(通常不用)f_dc_*:球谐基函数 DC 分量(主导颜色)f_rest_*:球谐基函数高阶分量opacity:透明度scale_*:三个轴的尺度rot_*:四元数旋转PLY 文件可以被以下工具直接加载:
3DGS 导出为网格(mesh)比 NeRF 更困难。因为高斯是「模糊的球体」,没有明确的表面边界。如果需要三角网格用于传统图形管线,通常需要额外做表面提取(如 Poisson 重建),效果不如 NeRF 的 marching cubes 稳定。
经过 L4 和 L5 的实践,你现在可以建立一个简单的选型决策树:
| 场景需求 | 推荐方案 | 理由 |
|---|---|---|
| 需要实时渲染 / VR / Web | 3DGS | 光栅化天然实时 |
| 需要导出紧凑模型 (<100MB) | NeRF | MLP 权重远小于高斯参数 |
| 需要精确三角网格 | NeRF | 密度场 → marching cubes 成熟 |
| 快速迭代实验 / 大量场景 | 3DGS | 训练快 10 倍,迭代效率高 |
| 透明物体 / 反射面 | 两者都差 | 3DGS 更难处理;NeRF 可尝试反射建模 |
| 低显存环境 (<6GB) | NeRF | nerfacto 可在 4GB 运行;3DGS 需要更多 |
| 动态场景 / 4D | 前沿研究 | 两者都有扩展方法,但都不够成熟 |
更详细的对比参考:3DGS vs NeRF 技术选型对比表。
densify-grad-thresh(如 0.0001 和 0.0005),观察高斯数量和重建细节的变化。ns-export gaussian-splat 导出 PLY,尝试用 在线 viewer 加载查看。如果在 splatfacto 训练、参数调节或导出过程中遇到任何问题,随时问我。下一课(L6)我们将深入做 NeRF 和 3DGS 的系统性技术选型对比。