欢迎光临
我们一直在努力

3D 高斯泼溅 (3DGS) 入门:用 Python + CUDA 渲染你的房间,速度比 NeRF 快 100 倍

标签: #3DGS #ComputerVision #CUDA #Python #VirtualReality #Rendering


📉 前言:为什么 NeRF 会“死”?

NeRF 的本质是在“猜”。
它通过发射无数条光线,去问神经网络:“这个点的颜色是什么?密度是多少?”
这种基于 Ray Marching(光线步进) 的机制,注定了它的计算量是巨大的。

3DGS 的本质是在“画”。
它把场景表示为成千上万个 3D 高斯球(椭球体)。渲染时,直接把这些球“泼(Splat)”到屏幕上,利用 GPU 的排序和 Alpha 混合,瞬间成像。

原理对比 (Mermaid):

#mermaid-svg-T3qIG22n7w4Tvw3Y{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-T3qIG22n7w4Tvw3Y .error-icon{fill:#552222;}#mermaid-svg-T3qIG22n7w4Tvw3Y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-T3qIG22n7w4Tvw3Y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .marker.cross{stroke:#333333;}#mermaid-svg-T3qIG22n7w4Tvw3Y svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-T3qIG22n7w4Tvw3Y p{margin:0;}#mermaid-svg-T3qIG22n7w4Tvw3Y .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .cluster-label text{fill:#333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .cluster-label span{color:#333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .cluster-label span p{background-color:transparent;}#mermaid-svg-T3qIG22n7w4Tvw3Y .label text,#mermaid-svg-T3qIG22n7w4Tvw3Y span{fill:#333;color:#333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .node rect,#mermaid-svg-T3qIG22n7w4Tvw3Y .node circle,#mermaid-svg-T3qIG22n7w4Tvw3Y .node ellipse,#mermaid-svg-T3qIG22n7w4Tvw3Y .node polygon,#mermaid-svg-T3qIG22n7w4Tvw3Y .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-T3qIG22n7w4Tvw3Y .rough-node .label text,#mermaid-svg-T3qIG22n7w4Tvw3Y .node .label text,#mermaid-svg-T3qIG22n7w4Tvw3Y .image-shape .label,#mermaid-svg-T3qIG22n7w4Tvw3Y .icon-shape .label{text-anchor:middle;}#mermaid-svg-T3qIG22n7w4Tvw3Y .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-T3qIG22n7w4Tvw3Y .rough-node .label,#mermaid-svg-T3qIG22n7w4Tvw3Y .node .label,#mermaid-svg-T3qIG22n7w4Tvw3Y .image-shape .label,#mermaid-svg-T3qIG22n7w4Tvw3Y .icon-shape .label{text-align:center;}#mermaid-svg-T3qIG22n7w4Tvw3Y .node.clickable{cursor:pointer;}#mermaid-svg-T3qIG22n7w4Tvw3Y .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .arrowheadPath{fill:#333333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-T3qIG22n7w4Tvw3Y .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-T3qIG22n7w4Tvw3Y .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-T3qIG22n7w4Tvw3Y .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-T3qIG22n7w4Tvw3Y .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-T3qIG22n7w4Tvw3Y .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-T3qIG22n7w4Tvw3Y .cluster text{fill:#333;}#mermaid-svg-T3qIG22n7w4Tvw3Y .cluster span{color:#333;}#mermaid-svg-T3qIG22n7w4Tvw3Y div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-T3qIG22n7w4Tvw3Y .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-T3qIG22n7w4Tvw3Y rect.text{fill:none;stroke-width:0;}#mermaid-svg-T3qIG22n7w4Tvw3Y .icon-shape,#mermaid-svg-T3qIG22n7w4Tvw3Y .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-T3qIG22n7w4Tvw3Y .icon-shape p,#mermaid-svg-T3qIG22n7w4Tvw3Y .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-T3qIG22n7w4Tvw3Y .icon-shape rect,#mermaid-svg-T3qIG22n7w4Tvw3Y .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-T3qIG22n7w4Tvw3Y .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-T3qIG22n7w4Tvw3Y .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-T3qIG22n7w4Tvw3Y :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

3DGS (快: 光栅化)

优化

投影

排序 & Alpha混合

点云初始化

3D 高斯球集合

屏幕分块 (Tiles)

像素 (并行计算)

NeRF (慢: 光线步进)

发射光线

输入

计算

积分

相机

采样点 (x,y,z)

神经网络 (MLP)

颜色 & 密度

像素


🛠️ 一、 核心数据结构:什么是“高斯球”?

在代码中,一个 3DGS 场景本质上就是一个巨大的 Python List,里面存了数百万个“点”。
但这个点不是普通的点,它带有 4 类关键属性。

我们定义一个 GaussianModel 类:

import torch

class GaussianModel:
def __init__(self, num_points):
# 1. 位置 (XYZ) – 决定球在哪
self._xyz = torch.nn.Parameter(torch.zeros(num_points, 3))

# 2. 不透明度 (Opacity) – 决定球有多实
self._opacity = torch.nn.Parameter(torch.zeros(num_points, 1))

# 3. 几何形态 (Covariance) – 决定球是扁的还是圆的
# 为了优化方便,拆分为 缩放(Scale) 和 旋转(Rotation)
self._scaling = torch.nn.Parameter(torch.zeros(num_points, 3))
self._rotation = torch.nn.Parameter(torch.zeros(num_points, 4)) # 四元数

# 4. 颜色 (Spherical Harmonics) – 决定不同角度看是什么颜色
# 这是一个拟合系数,不是固定的 RGB
self._features_dc = torch.nn.Parameter(torch.zeros(num_points, 1, 3))
self._features_rest = torch.nn.Parameter(torch.zeros(num_points, 15, 3))

理解关键: 3DGS 的训练过程,其实就是用 梯度下降 (Gradient Descent) 不断调整这几百万个球的参数,让它们“泼”在屏幕上的样子,和你的照片一模一样。


🚀 二、 渲染流程:CUDA 里的魔法

Python 负责管理参数,CUDA 负责拼命干活。
3DGS 的核心黑科技在于 diff-gaussian-rasterization 这个库(由 Inria 团队开源)。

渲染一帧画面的逻辑如下:

  • 视锥裁剪 (Culling):把摄像机看不到的球扔掉。
  • 投影 (Projection):把 3D 椭球投影成 2D 平面上的椭圆。
  • 排序 (Sorting):这是最耗时的。 利用 Radix Sort(基数排序)根据深度(Z轴)对所有高斯球排序。
  • 光栅化 (Rasterization):从后往前,叠加颜色。
  • (注:这部分代码通常是编译好的 CUDA 核函数,Python 只需要调用 .apply())


    📸 三、 实战:把你的房间搬进电脑

    1. 环境准备

    你需要一块 NVIDIA 显卡(推荐 RTX 3060 以上),安装好 CUDA Toolkit 11.8+。

    git clone –recursive https://github.com/graphdeco-inria/gaussian-splatting
    cd gaussian-splatting
    pip install -r requirements.txt

    2. 数据采集 (COLMAP)

    拿出手机,围绕你的房间拍一段视频(慢一点,不要有动态模糊)。
    然后使用 ffmpeg 抽帧,并用 colmap 计算相机位姿。

    # 这一步建议使用自动化脚本 convert.py
    python convert.py -s data/my_room

    Colmap 会生成稀疏点云,作为高斯球的初始位置。

    3. 开始训练

    这是见证奇迹的时刻。

    python train.py -s data/my_room -m output/my_room

    你会看到终端里的 Loss 飞速下降。

    • 7000 次迭代:大概能看清轮廓。
    • 30000 次迭代(约 20-40 分钟):连桌子上的纹理、显示器的反光都清晰可见。
    4. 核心优化逻辑 (Adaptive Density Control)

    为什么 3DGS 能把细节还原得这么好?因为它支持自适应分裂。

    # 伪代码逻辑:每隔 100 次迭代执行一次
    def densify_and_prune(self, grads, threshold):
    # 1. 克隆 (Clone):
    # 如果一个高斯球梯度很大,但本身很小 -> 说明这里细节不够 -> 复制一个球填补
    self.clone_gaussians(grads > threshold)

    # 2. 分裂 (Split):
    # 如果一个高斯球梯度很大,且本身很大 -> 说明这个球太粗糙了 -> 把它劈成两个小球
    self.split_gaussians(grads > threshold)

    # 3. 移除 (Prune):
    # 把不透明度几乎为 0 的透明球删掉,节省显存
    self.prune_gaussians(self.opacity < 0.005)


    🎮 四、 效果展示与查看

    训练完成后,使用配套的 SIBR_viewer 查看。
    你会发现:

    • 帧率:轻松达到 140+ FPS。
    • 质量:比 iPhone 拍的照片还清晰,支持任意角度漫游。
    • 大小:虽然显存占用大,但导出的模型文件通常只有几百 MB。

    🎯 总结

    3DGS 彻底改变了三维重建的游戏规则。
    它告诉我们:显式表达(Explicit Representation)+ 可微渲染(Differentiable Rendering) 才是实时图形学的未来。

    2026 趋势预测:
    现在我们还在用 Python 跑 Demo,未来 3DGS 将被集成进 Unity 和 Unreal Engine,甚至直接作为一种视频格式(.splat)在浏览器中流式播放。

    Next Step:
    别光看。去 GitHub 下载 gaussian-splatting 源码,拍摄一段 30 秒的视频,今晚就拥有一个属于你自己的“数字孪生”房间。

    赞(0)
    未经允许不得转载:171主机测评 » 3D 高斯泼溅 (3DGS) 入门:用 Python + CUDA 渲染你的房间,速度比 NeRF 快 100 倍
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址