文章目录
- 每日一句正能量
- 摘要
- 一、引言:为什么3DGS值得被认真对待?
- 二、3DGS算法核心流程
- 2.1 五步走策略
- 2.2 算法伪代码
- 三、3D高斯参数化:场景到底被表示成了什么?
- 3.1 四个参数
- 3.2 协方差矩阵的巧妙参数化
- 3.3 颜色为什么用球谐(SH)?
- 四、可微分渲染:3DGS的"秘密武器"
- 4.1 为什么可微分如此重要?
- 4.2 Splatting:从3D高斯到2D像素
- 五、自适应密度控制:高斯的"优胜劣汰"
- 5.1 分裂与剪枝
- 5.2 为什么密度控制如此重要?
- 六、端侧性能猜想:3DGS在移动端跑得动吗?
- 6.1 三大性能瓶颈
- 6.2 端侧优化方向
- 6.3 性能目标猜想
- 七、结语:3DGS的简洁之美
每日一句正能量
把每一个如果都活成幸好。
不是否认过去,而是选择从任何经历中提炼出对当下有益的部分。
清醒而温柔,坚韧而诗意,在守护自我的同时,与世界进行创造性的互动。
摘要
摘要:3D Gaussian Splatting(3DGS)自2023年8月发表以来,以"训练快、渲染快、视觉好"三大特性迅速席卷三维视觉领域。本文基于论文公开资料与社区开源实现,系统解读3DGS的算法原理——从高斯参数化、可微分渲染到自适应密度控制,并结合移动端硬件特性,对其端侧部署的性能瓶颈与优化方向做出技术猜想。
一、引言:为什么3DGS值得被认真对待?
2023年8月,INRIA和马克斯·普朗克研究所的研究团队发表了一篇题为《3D Gaussian Splatting for Real-Time Radiance Field Rendering》的论文。这篇论文没有提出新的网络结构,也没有使用Transformer——它提出的方法如此简洁,以至于很多人第一次读完后会觉得"就这?"
但这个"就这"的方法,在NeRF(神经辐射场)统治了三维重建领域三年后,实现了三个突破:
- 训练速度:从NeRF的数小时缩短到数分钟
- 渲染速度:从NeRF的<10fps提升到60fps+实时渲染
- 视觉质量:在多个数据集上达到或超越NeRF的PSNR指标
作为一名校企合作讲师,我关注的不仅是论文里的公式,更是这项技术从"实验室"走向"课堂"、走向"产业"的路径。本文试图回答两个问题:3DGS为什么这么快?它在端侧部署会遇到什么瓶颈?
二、3DGS算法核心流程
2.1 五步走策略
图1:3DGS算法核心流程——初始化 → 渲染 → 损失 → 优化 → 密度控制(循环迭代)
3DGS的算法流程可以概括为五个步骤的闭环迭代:
SfM点云初始化 → 高斯参数初始化 → 可微分渲染 → 光度损失计算 → 自适应密度控制 ↑___________________________________________|第一步:SfM点云初始化
使用COLMAP(Structure from Motion)从输入的多视角照片中,估计相机位姿并稀疏重建出初始点云。通常得到约10,000个点。这些点是后续高斯分布的"种子"。
第二步:高斯参数初始化
每个SfM点被转换为一个3D高斯椭球:位置=点的坐标,协方差=各向同性(球形),颜色=该点邻域像素的均值,透明度=0.5。
第三步:可微分渲染
将3D高斯投影到2D屏幕空间,按深度排序后进行alpha混合,生成渲染图像。
第四步:光度损失计算
比较渲染图像与真实照片的像素差异,计算L1损失 + SSIM损失。
第五步:自适应密度控制
根据梯度信息,对高斯进行"分裂"(densification)或"剪枝"(pruning)。每100次迭代执行一次。
2.2 算法伪代码
// 3DGS核心算法伪代码functiontrain3DGS(images,poses){// 1. SfM初始化pointCloud=COLMAP(images,poses);gaussians=initGaussians(pointCloud);// 2. 迭代优化for(iteration=0;iteration<30000;iteration++){// 2.1 随机采样一个视角camera=sampleCamera(poses);// 2.2 可微分渲染renderedImage=differentiableRender(gaussians,camera);// 2.3 计算损失loss=L1Loss(renderedImage,groundTruth)+λ*SSIMLoss(renderedImage,groundTruth);// 2.4 反向传播loss.backward();// 2.5 优化器更新optimizer.step();// 2.6 自适应密度控制(每100次)if(iteration%100==0){gaussians=adaptiveDensityControl(gaussians);}}returngaussians;}三、3D高斯参数化:场景到底被表示成了什么?
3.1 四个参数
图2:3D高斯参数化——位置 · 协方差 · 颜色 · 透明度
3DGS用数百万个3D高斯椭球表示场景。每个高斯由四个参数定义:
| 参数 | 维度 | 含义 | 存储 |
|---|---|---|---|
| 位置 x | 3 | 高斯中心坐标 (x, y, z) | Float32 × 3 |
| 协方差 Σ | 6 | 3×3协方差矩阵(对称,只存6个独立元素) | Float32 × 6 |
| 颜色 c | 12 | 球谐系数 SH(3 bands,RGB各4个系数) | Float32 × 12 |
| 透明度 α | 1 | 不透明度,经Sigmoid映射到[0,1] | Float32 × 1 |
总参数量:3 + 6 + 12 + 1 =22个Float/高斯
100万个高斯 ≈ 22M floats ≈84MB(Float32)
3.2 协方差矩阵的巧妙参数化
协方差矩阵必须是半正定的,直接优化矩阵元素很难保证这一约束。3DGS的解决方案非常巧妙:
Σ = RSS^TR^T = (RS)(RS)^T其中:
- R是旋转矩阵(由四元数 q 参数化,4个参数)
- S是缩放矩阵(对角阵,3个参数)
这样,协方差矩阵可以分解为"旋转 + 缩放"的组合,既保证了半正定性,又只需7个参数(4+3),但论文实际存储6个参数(通过Cholesky分解的变体)。
3.3 颜色为什么用球谐(SH)?
传统纹理颜色是固定的,但真实世界的颜色会随视角变化(如金属反光、绸缎光泽)。球谐函数(Spherical Harmonics)是一种定义在球面上的正交基函数,可以用少量系数近似视角相关的颜色:
c(v) = Σ SH_coeff[i] * SH_basis[i](v)其中 v 是视角方向。3DGS默认使用3阶SH(12个系数),足以捕捉大部分视角相关效果。
四、可微分渲染:3DGS的"秘密武器"
4.1 为什么可微分如此重要?
图3:可微分渲染 vs 传统渲染——3DGS通过梯度反向传播直接优化3D参数
传统光栅化渲染(如OpenGL/DirectX)的过程是不可微分的:
- 离散化操作(如深度测试、三角形裁剪)没有明确定义的梯度
- 无法直接通过"渲染图像与真实照片的误差"来反向优化3D场景参数
NeRF的解决方案是用MLP(多层感知机)隐式表示场景,渲染过程是MLP的前向传播,天然可微分。但代价是渲染慢——每条光线需要数百次MLP前向传播。
3DGS的解决方案更优雅:让渲染过程本身可微分。
4.2 Splatting:从3D高斯到2D像素
// 可微分渲染核心逻辑functiondifferentiableRender(gaussians,camera){// 1. 3D高斯投影到2DprojectedGaussians=[];for(gofgaussians){// 世界坐标 → 相机坐标g_camera=camera.worldToCamera(g.position);// 相机坐标 → 屏幕坐标(投影变换)g_screen=camera.project(g_camera);// 3D协方差 → 2D协方差(Jacobian变换)g_cov2D=projectCovariance(g.covariance,camera,g.position);projectedGaussians.push({position:g_screen,covariance:g_cov2D,color:evaluateSH(g.color,camera.viewDir),alpha:g.alpha});}// 2. 按深度排序projectedGaussians.sort((a,b)=>a.depth-b.depth);// 3. Alpha混合(从前到后)image=zeros(camera.width,camera.height);for(gofprojectedGaussians){// 计算每个像素受到的高斯影响for(pixeling.boundingBox){// 2D高斯概率密度weight=gaussian2D(pixel,g.position,g.covariance);// Alpha混合alpha=g.alpha*weight;image[pixel]=image[pixel]+alpha*g.color*(1-image[pixel].alpha);}}returnimage;}关键洞察:上述所有操作(投影、排序、alpha混合)都是可微分的。这意味着可以通过自动微分(autograd)直接计算渲染图像对每个高斯参数的梯度。
五、自适应密度控制:高斯的"优胜劣汰"
5.1 分裂与剪枝
图4:自适应密度控制——高斯的分裂(densification)与剪枝(pruning)
3DGS训练过程中,高斯数量不是固定的,而是通过"自适应密度控制"动态调整:
分裂(Densification):
- 触发条件:某个高斯的视图空间位置梯度 > τ_pos(阈值,默认0.0002),且该高斯的尺度大于场景尺度的1.5%
- 操作:将该高斯分裂为两个较小的高斯,沿梯度最大的方向分离
- 目的:在需要更多细节的区域自动增加高斯密度
剪枝(Pruning):
- 触发条件:某个高斯的透明度 α < ε_α(阈值,默认0.005)
- 操作:直接移除该高斯
- 目的:清除对场景贡献微弱的"噪声"高斯
// 自适应密度控制伪代码functionadaptiveDensityControl(gaussians){constnewGaussians=[];for(gofgaussians){// 检查是否需要分裂if(g.viewSpaceGradient>TAU_POS&&g.scale>SCENE_SCALE*0.015){// 分裂为两个高斯const[g1,g2]=splitGaussian(g);newGaussians.push(g1,g2);}// 检查是否需要剪枝elseif(g.alpha<EPSILON_ALPHA){// 直接丢弃continue;}else{newGaussians.push(g);}}returnnewGaussians;}5.2 为什么密度控制如此重要?
| 场景 | 无密度控制 | 有密度控制 |
|---|---|---|
| 平坦墙面 | 过度建模,浪费高斯 | 少量大高斯即可覆盖 |
| 复杂纹理 | 高斯不足,细节模糊 | 自动分裂,增加密度 |
| 透明/空洞 | 残留高斯,产生雾状伪影 | 低透明度高斯被剪枝 |
六、端侧性能猜想:3DGS在移动端跑得动吗?
6.1 三大性能瓶颈
图5:端侧3DGS性能猜想——排序瓶颈、内存瓶颈、带宽瓶颈
基于公开资料与移动端GPU特性,我对3DGS端侧部署的三大瓶颈做出技术猜想:
瓶颈一:排序
每帧渲染前,需要将所有高斯按深度排序。排序复杂度为 O(n log n),100万个高斯在移动端GPU上约需10ms。这意味着仅排序就消耗了60fps目标(16.6ms/帧)的大部分时间。
猜想:使用GPU RadixSort替代传统排序,可将排序时间降至2-3ms。更进一步,如果相邻帧的相机移动较小,可以重用上一帧的排序结果,仅在局部调整。
瓶颈二:内存
100万个高斯需要约84MB显存(Float32)。加上渲染缓冲区、中间结果,总显存占用可能超过200MB。对于中端手机(4-6GB RAM,共享显存),这是一个不小的负担。
猜想:Float32 → Float16可将内存减半至42MB。进一步对SH系数进行量化(如8-bit),可将总模型压缩到20-30MB。
瓶颈三:带宽
Splatting渲染需要频繁读写显存——读取高斯参数、写入像素颜色。移动端LPDDR的带宽远低于桌面GDDR,这会成为渲染帧率的瓶颈。
猜想:采用Tile-based渲染策略,将屏幕划分为16×16的瓦片,每个瓦片独立处理,减少全局显存访问。配合Early-Z测试,可大幅减少overdraw。
6.2 端侧优化方向
| 优化方向 | 具体策略 | 预期收益 |
|---|---|---|
| 排序优化 | GPU RadixSort + 帧间排序重用 | 排序时间 -70% |
| 内存优化 | Float16 + SH量化 + 参数共享 | 模型大小 -75% |
| 渲染优化 | Tile-based + Early-Z + 视锥剔除 | 渲染时间 -60% |
| 模型优化 | LOD分级 + 远距离降采样 | 有效高斯数 -80% |
| 硬件优化 | NPU推理 + GPU并行 | 整体吞吐量 +50% |
6.3 性能目标猜想
综合上述优化,我对移动端3DGS实时渲染的性能目标做出如下猜想:
| 指标 | 当前(无优化) | 目标(优化后) |
|---|---|---|
| 渲染帧率 | 15-25 fps | 60 fps |
| 模型大小 | 100-200 MB | <30 MB |
| 加载时间 | 5-10 s | <2 s |
| 内存占用 | 300-500 MB | <150 MB |
| 分辨率 | 720p | 1080p |
七、结语:3DGS的简洁之美
3DGS之所以引人入胜,不在于它的复杂性,而在于它的简洁性。
它没有使用神经网络,没有复杂的训练策略,没有庞大的模型权重。它只是用最基础的数学工具——高斯分布——来表达三维场景,然后用最基础的可微分渲染来优化这些分布。
但正是这种简洁,带来了惊人的效率:训练快、渲染快、效果好。这提醒我们一个常被遗忘的工程原则:简单的方法,如果设计得当,往往比复杂的方法更有效。
作为一名讲师,我希望学生在学习3DGS时,不仅记住公式和参数,更理解背后的设计思想:如何用可学习的基元(primitives)+ 可微分的渲染(differentiable rendering)+ 自适应的密度控制(adaptive density control),构建一个端到端优化的三维表示系统。
这个思想,可能会影响未来十年的三维视觉技术发展。
转载自:https://blog.csdn.net/u014727709/article/details/164403521
欢迎 👍点赞✍评论⭐收藏,欢迎指正