news 2026/9/6 2:12:22

【共创稿事节】基于公开资料的3DGS技术原理分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【共创稿事节】基于公开资料的3DGS技术原理分析

文章目录

    • 每日一句正能量
    • 摘要
    • 一、引言:为什么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高斯椭球表示场景。每个高斯由四个参数定义:

参数维度含义存储
位置 x3高斯中心坐标 (x, y, z)Float32 × 3
协方差 Σ63×3协方差矩阵(对称,只存6个独立元素)Float32 × 6
颜色 c12球谐系数 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 fps60 fps
模型大小100-200 MB<30 MB
加载时间5-10 s<2 s
内存占用300-500 MB<150 MB
分辨率720p1080p

七、结语:3DGS的简洁之美

3DGS之所以引人入胜,不在于它的复杂性,而在于它的简洁性

它没有使用神经网络,没有复杂的训练策略,没有庞大的模型权重。它只是用最基础的数学工具——高斯分布——来表达三维场景,然后用最基础的可微分渲染来优化这些分布。

但正是这种简洁,带来了惊人的效率:训练快、渲染快、效果好。这提醒我们一个常被遗忘的工程原则:简单的方法,如果设计得当,往往比复杂的方法更有效

作为一名讲师,我希望学生在学习3DGS时,不仅记住公式和参数,更理解背后的设计思想:如何用可学习的基元(primitives)+ 可微分的渲染(differentiable rendering)+ 自适应的密度控制(adaptive density control),构建一个端到端优化的三维表示系统

这个思想,可能会影响未来十年的三维视觉技术发展。


转载自:https://blog.csdn.net/u014727709/article/details/164403521
欢迎 👍点赞✍评论⭐收藏,欢迎指正

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 2:09:35

使用内存探测bpf

一、完整实操步骤&#xff08;标准化流程&#xff09; 1. 启动KV服务端程序 执行启动命令&#xff0c;正常拉起KV存储服务&#xff0c;确保服务端口监听正常、无启动报错&#xff1a; ./kvstore 启动后保持服务常驻后台运行&#xff0c;等待客户端压测/请求访问。 2. 获取…

作者头像 李华
网站建设 2026/9/6 2:08:07

Java转AI Agent:工程经验重新定价,如何拿到翻倍offer

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 2:07:47

7.web记录

37.和区别 两个等号判断的是值是否相等 不判断类型 严格等于&#xff1a;会判断类型是否相同38.循环while(){} 小括号仅一条语句写循环的条件&#xff08;如何循环&#xff09;&#xff0c;大括号写循环体的代码&#xff08;循环要做什么&#xff09;do{}while() 循环先执行循环…

作者头像 李华
网站建设 2026/9/6 2:04:19

计算机网络安全防御系统设计:从架构到落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 2:02:00

MCP 入门:从普通函数到可运行的 MCP Server 与 Client

本文面向了解 Python 基础、希望理解 AI 工具调用的读者。全文用“查询订单状态”作为例子&#xff0c;先解释 MCP 解决什么问题&#xff0c;再拆解架构、能力类型和调用流程&#xff0c;最后用 Python 完成一个可以本地运行的 MCP Server 与 Client。示例使用模拟数据&#xf…

作者头像 李华