news 2026/10/23 1:56:00

Mesh2Splat深度测试机制:Mesh-Gaussian遮挡剔除为什么能显著提升3DGS渲染性能?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mesh2Splat深度测试机制:Mesh-Gaussian遮挡剔除为什么能显著提升3DGS渲染性能?

【免费下载链接】mesh2splat

Fast mesh to 3D gaussian splat conversion

项目地址:https://gitcode.com/gh_mirrors/me/mesh2splat
点击查看免费下载

Mesh2Splat是一款将 3D 网格(Mesh)在毫秒级转换为 3DGS(3D Gaussian Splatting)模型的开源工具。除了转换本身,它自带的 3DGS 渲染器中隐藏着一个实用的性能优化:Mesh-Gaussian 深度测试(Depth Test)——让原始网格充当"遮挡物",把被它挡住的 3D 高斯直接从渲染管线中剔除,从而显著提升 3DGS 渲染性能。本文将拆解这套机制的工作原理。

为什么 3DGS 渲染天生"贵"?

先理解背景:3DGS 渲染的核心流程是——对场景中每一个高斯做投影、深度排序(从后到前),然后逐片元 alpha 混合。这意味着:

  • 一个几百万高斯的大模型,排序(radix sort)每帧都要跑;
  • 每个高斯都会画出一个屏幕空间四边形(quad),参与像素混合;
  • 哪怕一个高斯完全被不透明的网格挡在后面,它依然会被排序、被绘制,白白消耗 GPU。

这就是 3DGS 渲染开销大的根源之一:没有天然的遮挡剔除。而 Mesh2Splat 的场景恰好特殊——同一个对象既有原始网格、又有转换出的高斯,网格天然是高斯的完美遮挡源。🎯

深度预传递:先画 Mesh,记录深度

核心代码位于 DepthPrepass.cpp,它做三件事:

  1. 只渲染不透明网格:遍历所有 mesh,跳过baseColorFactor.a != 1.0的半透明物体;
  2. 只写深度、不写颜色:顶点着色器 depthPrepassVS.glsl 只计算gl_Position,片元着色器 depthPrepassPS.glsl 仅把gl_FragCoord.z写入深度贴图;
  3. 结果存入深度纹理:由 renderer.cpp 中的createDepthTexture()创建一张全屏GL_DEPTH_COMPONENT纹理,挂到独立 FBO 上。

一次普通的三角形光栅化,就把"屏幕每个像素最近的不透明 Mesh 深度"这张图算好了。

高斯剔除:判断发生在排序之前

真正的剔除发生在高斯预传递(Gaussian Prepass)里。CPU 侧在 GaussiansPrepass.cpp 中把开关u_depthTestMesh和深度纹理u_depthTexture绑定进 Compute Shader:

  • 视锥裁剪:先做宽松的裁剪空间剔除(1.05 倍外扩,保证保守);
  • 深度测试:在 gaussianSplattingPrepassCS.glsl 中,每个高斯中心投影到 NDC 后采样 Mesh 深度纹理,如果自身深度myDepth > depth + eps,直接return;
  • 不写入选中列表:通过测试的高斯才用原子计数器atomicCounterIncrement写入 per-quad 变换缓冲。

关键点在于剔除的时机:被挡的高斯在计算 2D 协方差矩阵(含特征值分解,见 gaussianSplattingPrepassCS.glsl)之前就被丢弃了,后续管线根本不知道它们存在。

性能提升来自哪里?三级联动减负

剔除一个高斯,收益会沿渲染管线放大三层:

阶段省下的开销
🔢 预传递2D 协方差投影、特征值分解、quad 参数计算
🧮 排序radix sort 的输入规模直接变小,见 RadixSortPass.cpp
🎨 光栅化少画 quad、少做 alpha 混合,降低 overdraw

3DGS 渲染的瓶颈往往在排序和像素混合,而这两个阶段的工作量都正比于"存活高斯数"。当相机视角下大部分高斯被不透明 Mesh 遮挡时(比如只看到模型的正面),剔除比例可能非常高,帧时间随之明显下降——这正是 UI 上该选项括号里写着"improves rendering performance"的原因。

如何开启 Mesh-Gaussian 深度测试

在渲染器 UI 中勾选"Enable mesh-gaussian depth test"复选框(定义见 ImGuiUI.cpp),事件经 guiRendererConcreteMediator.cpp 处理:

  • 启用depthPrepass渲染通道,并调用setDepthTestEnabled(true)(renderer.cpp);
  • 渲染帧循环按 renderer.cpp 定义的顺序依次执行:depthPrepass → gaussiansPrepass → radixSort → gaussianSplatting → ...,深度纹理在预传递前先准备好。

对比开关前后的帧时间,就能直观感受到剔除带来的提升。

适用边界:哪些情况不生效

这套机制是保守且有限制的,源码里写得很清楚:

  • 只对不透明高斯生效:深度判断仅对gaussian.color.a > 0.95的高斯执行(见 gaussianSplattingPrepassCS.glsl),半透明高斯目前不做剔除(shader 中留有 "Not working for transparent ones yet" 的注释);
  • 只测高斯中心点:以中心投影位置采样深度,贴边的高斯可能产生轻微遮挡误判,因此比较时加了eps = 0.00002的容差;
  • 格式限制:仅在主渲染格式(u_format == 0)下开启,调试可视化模式下自动关闭。

总结

Mesh2Splat 的 Mesh-Gaussian 深度测试是一次典型的"用已有资源做早期剔除":一次廉价的深度预传递 + 每高斯一次的纹理采样,换掉了排序、光栅化、混合三大阶段的大量无效工作。对于"网格与高斯同屏"的 3DGS 工作流,这是一个性价比极高的渲染性能优化。✅

【免费下载链接】mesh2splat

Fast mesh to 3D gaussian splat conversion

项目地址:https://gitcode.com/gh_mirrors/me/mesh2splat
点击查看免费下载

相关推荐

上一篇:系统级"划译"的实现原理与工程实践:CopyTranslator 拖拽复制(Drag Copy)机制深度解析
下一篇:Android-AdvancedRecyclerview与Kotlin协程:实现异步加载的拖拽列表终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

神经网络评估指标:准确率、召回率等详解(代码验证)

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

作者头像 李华