ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

高斯泼溅3DGS实战:从NeRF瓶颈到实时三维重建全流程

高斯泼溅3DGS实战:从NeRF瓶颈到实时三维重建全流程 1. 高斯泼溅到底是什么为什么突然就火了第一次看到“高斯泼溅”这四个字我脑子里浮现的是颜料甩在墙上的画面。后来真正跑通第一个3DGS场景才意识到这个中文译名其实相当传神——它确实是在三维空间里“泼”出一堆椭球形的粒子每个粒子带着颜色、透明度和朝向最终渲染出一张完整的画面。高斯泼溅英文全称3D Gaussian Splatting简称3DGS是2023年SIGGRAPH上正式发表的一种三维场景表示与渲染方法。它的核心思路和NeRF神经辐射场走的是完全不同的路线NeRF用多层感知机隐式地记住整个场景的密度和颜色分布而3DGS直接在空间里撒了几十万到几百万个三维高斯椭球每个椭球有明确的位置、协方差矩阵、不透明度和球谐系数。渲染的时候把这些椭球投影到屏幕上按深度排序后做alpha混合就得到了最终图像。为什么说它把三维重建的速度提升了一个数量级这里要分两个维度来看。第一个维度是训练速度NeRF训练一个场景通常需要几个小时甚至十几个小时而3DGS在同等GPU上往往几分钟到半小时就能收敛。第二个维度是渲染速度NeRF渲染一帧需要沿光线采样上百个点每个点都要过一遍网络1080p分辨率下很难做到实时3DGS的渲染本质上是光栅化和游戏引擎画三角形是一个路子轻松跑到100帧以上。这两个速度优势叠加起来就是“一个数量级”这个说法的来源。适合谁来了解这个内容如果你做三维重建、数字孪生、VR/AR内容制作、机器人仿真或者单纯对“用几张照片重建一个可自由漫游的三维场景”感兴趣3DGS都值得花时间研究。它不像NeRF那样需要深厚的数学功底才能改代码工程化程度高上手门槛比想象中低。2. 从NeRF到3DGS技术路线为什么发生了转向2.1 NeRF的贡献与瓶颈NeRF在2020年横空出世的时候确实惊艳了整个图形学圈子。它用一个简单的MLP网络输入空间坐标和观察方向输出该点的颜色和密度然后通过体渲染积分得到像素值。这个思路优雅、统一而且效果极好尤其是对光照、反射、透明材质的处理至今仍是NeRF的强项。但NeRF的问题也很明显。首先是训练慢因为每条光线要采样几十到上百个点每个点都要过网络反向传播的计算量巨大。其次是渲染慢即使训练好了推理时仍然要沿光线采样想实时渲染就得用各种缓存和蒸馏技巧比如Instant-NGP用哈希编码把训练压到几分钟但渲染速度依然受限于体渲染的采样过程。再者NeRF的隐式表示很难直接编辑你想删掉场景里的一个物体或者把某个区域替换掉操作起来非常别扭。2.2 3DGS的核心突破点3DGS的作者们换了一个思路既然体渲染的瓶颈在于沿光线采样那能不能干脆不采样直接把场景表示成一群可以光栅化的图元于是他们选择了三维高斯椭球。每个高斯椭球有中心位置、协方差矩阵决定椭球的形状和朝向、不透明度和球谐系数决定不同视角下的颜色。渲染时把这些椭球投影到图像平面得到二维高斯分布然后按深度排序做alpha混合。这个方案的精妙之处在于它把“渲染”变成了“光栅化”而光栅化是GPU最擅长的事情。同时训练过程也不再需要沿光线采样而是直接对投影后的二维高斯做可微渲染梯度可以高效地回传到每个椭球的参数上。这就是为什么3DGS的训练和渲染都能比NeRF快一个数量级。2.3 为什么是“高斯”而不是其他图元你可能会问为什么偏偏选高斯椭球而不是小圆片、小立方体或者点云这里有几个实际考量。第一高斯函数在投影后仍然是高斯函数数学上非常干净二维投影的协方差矩阵可以直接由三维协方差矩阵和相机投影矩阵计算出来。第二高斯椭球有各向异性可以表示扁平的表面、细长的结构比各向同性的点云表达能力强得多。第三高斯函数的可微性很好梯度计算稳定适合做优化。第四alpha混合的排序可以用GPU的并行排序算法高效实现不需要逐像素做光线追踪。提示如果你之前接触过点云渲染可以这样理解——3DGS就是把每个点升级成了一个有形状、有透明度、有视角相关颜色的椭球并且让这些椭球可以通过梯度下降自动调整位置和形状。3. 3DGS的完整实操流程从拍照到实时漫游3.1 数据采集自己制作数据集的关键要点3DGS对输入数据的要求比NeRF宽松一些但也不是随便拍几张就能出好效果。我自己的经验是一个中等复杂度的物体或小场景大概需要50到200张照片覆盖各个角度重叠率保持在60%以上。如果是大场景比如一个房间或者一栋建筑的外立面可能需要几百到上千张。拍摄时要注意几个坑。第一避免运动模糊快门速度要够快最好用三脚架或者稳定器。第二光照要均匀避免强烈的方向性阴影因为3DGS对阴影的处理不如NeRF那么自然容易出现“鬼影”。第三不要用广角镜头边缘畸变太严重的照片后期COLMAP做SfM的时候容易匹配失败。第四如果场景里有反光或透明物体尽量避开或者接受重建效果打折扣这是所有基于多视图几何的方法的共同难题。拍完之后用COLMAP做稀疏重建和稠密重建得到相机内参、外参和初始点云。COLMAP的命令行操作大概是这样的colmap feature_extractor \ --database_path ./database.db \ --image_path ./images \ --ImageReader.camera_model OPENCV colmap exhaustive_matcher \ --database_path ./database.db colmap mapper \ --database_path ./database.db \ --image_path ./images \ --output_path ./sparse colmap image_undistorter \ --image_path ./images \ --input_path ./sparse/0 \ --output_path ./dense \ --output_type COLMAP跑完这些你会得到一个包含相机位姿和稀疏点云的COLMAP工程。3DGS的训练代码通常直接读取这个格式。3.2 环境配置GPU、CUDA和依赖安装3DGS的官方实现是基于CUDA的自定义光栅化器所以必须有一块NVIDIA GPU。显存建议至少8GB12GB以上更稳妥。我实测过RTX 3060 12GB跑小场景没问题RTX 4090 24GB可以跑比较大的场景。CUDA版本要和PyTorch版本匹配官方推荐CUDA 11.8以上。安装步骤大致如下conda create -n gs python3.10 conda activate gs pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install plyfile tqdm git clone https://github.com/graphdeco-inria/gaussian-splatting --recursive cd gaussian-splatting pip install submodules/diff-gaussian-rasterization pip install submodules/simple-knn这里有个常见的坑diff-gaussian-rasterization编译时需要nvcc如果你的CUDA路径没配好会报“nvcc not found”。解决办法是确认CUDA_HOME环境变量指向正确的CUDA安装目录并且把$CUDA_HOME/bin加到PATH里。注意如果你用的是Windows系统官方代码对Windows的支持不算特别友好建议用WSL2或者直接上Linux。我在Windows原生环境下编译diff-gaussian-rasterization踩过不少坑最后换到Ubuntu 22.04一次就过了。3.3 训练参数与显存优化3DGS的训练入口是train.py核心参数包括迭代次数、学习率、稠密化阈值等。默认配置是30000次迭代对于大多数场景够用了。如果场景特别大可以加到50000次。学习率方面位置的学习率会随着迭代次数指数衰减这是为了让高斯椭球先快速找到大致位置再精细调整。显存不够的话有几个调节手段。第一降低初始点云的数量COLMAP稠密重建时可以设置更低的密度。第二减小训练时的图像分辨率用--resolution 2表示下采样2倍。第三减少同时加载的图像数量但3DGS默认是随机采样图像这个不太好控制。第四如果实在跑不动可以先用小分辨率训练再逐步放大。训练过程中3DGS会周期性地做“稠密化”和“剪枝”在梯度大的区域分裂或克隆高斯椭球在不透明度过低的区域删除椭球。这个自适应机制是3DGS能自动调整表示精度的关键。3.4 渲染与可视化训练完成后会得到一个.ply格式的点云文件里面存储了所有高斯椭球的参数。官方提供了一个基于SIBR的实时查看器可以自由漫游场景。启动命令大概是./SIBR_viewers/install/bin/SIBR_gaussianViewer_app \ -m ./output/your_scene如果不想编译SIBR也可以用一些第三方查看器比如基于Web的gsplat.js或者SuperSplat。这些工具对分享和展示更友好但渲染质量可能略有差异。4. 实际项目中容易踩的坑与排查思路4.1 训练不收敛或效果模糊这是最常见的问题原因通常有几个。第一COLMAP的相机位姿不准尤其是纯旋转拍摄或者纹理稀疏的场景SfM容易失败。排查方法是看COLMAP输出的重投影误差如果平均误差超过1个像素就要考虑重新采集或者手动调整。第二初始点云太稀疏3DGS的稠密化机制需要一定数量的初始点才能启动。解决办法是在COLMAP稠密重建时提高密度或者用随机点云初始化。第三学习率设置不当位置学习率太高会导致椭球乱飞太低则收敛太慢。4.2 显存溢出OOM3DGS训练过程中高斯椭球的数量会动态增长显存占用也会随之上升。如果一开始能跑跑到一半OOM通常是稠密化太激进。可以调低densify_grad_threshold或者提高densification_interval让稠密化不那么频繁。另外训练时用--eval模式会额外占用显存做验证如果不需要可以关掉。4.3 渲染出现“漂浮物”或“鬼影”这通常是高斯椭球在空间中的分布不合理导致的。有些椭球被优化到了相机看不到的地方但仍然会影响渲染。解决办法是提高不透明度的剪枝阈值把那些透明度很低但体积很大的椭球删掉。另外如果场景中有动态物体比如走动的人也会产生鬼影因为3DGS假设场景是静态的。4.4 常见问题速查表问题现象可能原因排查方法解决思路训练Loss不下降相机位姿错误检查COLMAP重投影误差重新做SfM或手动标定渲染画面模糊初始点云太稀疏查看COLMAP稠密点云数量提高稠密重建密度训练中途OOM高斯椭球增长过快监控椭球数量变化调低稠密化阈值出现漂浮鬼影静态假设被破坏检查场景是否有动态物体剔除动态区域或接受瑕疵渲染速度慢椭球数量过多统计最终椭球数量提高剪枝阈值或降低分辨率颜色偏暗球谐系数欠拟合检查训练迭代次数增加迭代或提高学习率提示3DGS对COLMAP的依赖很强如果COLMAP跑不好后面怎么调参都是白费。我一般会花30%的时间在数据采集和COLMAP上确保位姿准确后面训练反而很省心。5. 3DGS的适用边界与后续扩展方向5.1 它擅长什么不擅长什么3DGS在静态场景、多视角覆盖充分、光照相对均匀的条件下表现最好。比如文物数字化、建筑扫描、产品展示、小规模场景重建这些场景用3DGS做出来的效果又快又好。但它也有明显的短板。第一对反光、透明、折射材质处理不好因为这些材质不满足多视图一致性假设。第二对动态场景无能为力虽然有一些后续工作在做动态3DGS但成熟度还不够。第三对稀疏视角的泛化能力弱如果只有几张照片重建质量会急剧下降。第四编辑和语义理解比较困难因为高斯椭球本身没有语义标签。5.2 和NeRF的互补关系虽然3DGS在速度上碾压NeRF但NeRF并没有被完全取代。在需要高质量光照、反射、透明效果的场景NeRF仍然有优势。而且NeRF的隐式表示在某些任务上更灵活比如少样本重建、生成式建模。实际项目中我见过有人用NeRF做离线高质量渲染用3DGS做实时预览两者结合使用。5.3 值得关注的后续工作3DGS发表之后社区涌现了大量改进工作。比如用更紧凑的表示减少椭球数量用层次化结构加速大场景渲染用深度先验改善稀疏视角重建用语义分割做可编辑的3DGS。如果你打算深入这个方向建议关注几个关键词压缩3DGS、动态3DGS、语义3DGS、大场景3DGS。这些方向都有开源实现可以直接拿来跑。5.4 硬件与部署的实际考量3DGS的渲染虽然快但对GPU仍然有要求。如果要在移动端或者VR头显上跑需要做模型压缩和量化。目前有一些工作把3DGS蒸馏到更小的表示或者用WebGPU做浏览器端渲染。如果你只是做离线渲染和展示一块中端NVIDIA GPU就够了。如果要实时漫游大场景建议至少RTX 4070以上。我在实际项目中的体会是3DGS最大的价值不是“替代NeRF”而是把三维重建的门槛从“需要理解体渲染和神经网络”降到了“会拍照、会跑COLMAP、会调几个参数”。这让更多非图形学背景的人也能快速做出可交互的三维场景。当然想做出真正高质量的结果还是要在数据采集和参数调优上花功夫。这个方向变化很快每隔几个月就有新工具和新方法出来保持动手跑一跑比只看论文收获大得多。
返回列表