news 2026/8/18 16:06:39

Fixed-Z vs 结构化采样:volsample 凭什么让体积渲染在相机移动时保持画面稳定?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Fixed-Z vs 结构化采样:volsample 凭什么让体积渲染在相机移动时保持画面稳定?

Fixed-Z vs 结构化采样:volsample 凭什么让体积渲染在相机移动时保持画面稳定?

【免费下载链接】volsampleStructured Volume Sampling - sample placement algorithm for real-time volume rendering with low aliasing, for camera-in-volume case.项目地址: https://gitcode.com/gh_mirrors/vo/volsample

在实时体积渲染(Volume Rendering)中,相机一旦进入云层、烟雾等体积内部并开始移动,画面就会像隔着摇晃的水面观察世界一样抖动闪烁,这就是困扰无数开发者的采样锯齿问题。volsample 正是为此而生的开源项目,它提出了一套全新的结构化采样(Structured Volume Sampling)算法,用很低的采样数就实现了相机移动时依旧稳定的体积渲染画面。本文将从 Fixed-Z 与结构化采样两种方案的对比出发,用最通俗的语言讲清楚:为什么 Fixed-Z 会崩,结构化采样又凭什么稳。

上图来自项目官方资料 img/overview.png:左侧是围绕相机栅格化的种子几何(十二面体),体积采样点被放置在与五边形面平行的平面上;右侧是渲染结果,不同颜色代表每条像素射线实际行进并混合的射线数量。

为什么相机一移动,体积渲染画面就疯狂闪烁?

实时体积渲染为了性能,通常只做 16~64 次采样。采样点就像是“画在空间里的一层层切片”,体积的密度、颜色都靠读取这些切片上的值来积分。

问题在于:如果采样层的位置是跟着相机走的,那么相机每移动一步,采样层就会在体积里“扫”过一片区域。体积数据在采样层上被反复切开、重组,同一帧里不同像素看到的采样密度不均匀,下一帧又完全错位——于是画面出现明显的带状闪烁、波纹和“脏块”,这就是采样锯齿。

Fixed-Z 采样:问题从“采样层跟着相机走”开始

最常见的做法就是 Fixed-Z 采样:所有采样点都放在与视方向(相机 Z 轴)垂直的平行平面上,随相机一起运动。它的优点是实现简单、代码只有几十行,缺点是只要相机移动,采样层就在体积里整体平移,锯齿立刻爆发。

在 RayMarchCore.cginc 中,RayMarchFixedZ就是这种方案:从t = dt开始,沿着射线每隔固定步长取一个样本。视线每帧移动,样本点就在体积中“扫”过,配合稀疏采样数,闪烁几乎不可避免。

治标不治本:Fixed-Z Pinned 的补救与局限

为了改善这个问题,项目里还实现了一个“改良版”:RayMarchFixedZPinned(见 RayMarchCore.cginc)。它的思路是把采样层“钉”在世界空间,通过累积相机前进距离_ForwardMotionIntegrated来反向补偿采样起始偏移,让采样层在相机前进时尽量保持静止。

这个方案对直线前进确实有效,但对旋转、侧移、升降就束手无策了:相机一转,屏幕边缘的采样层会随着视锥横扫体积,补偿机制完全失效,闪烁照旧。代码注释里也明确承认了这一点——它只能解决平移,解决不了旋转。

结构化采样:把采样层“钉”在世界空间

volsample 的核心贡献,是彻底换了一套思路:不再让采样层跟着相机,而是把采样层固定在世界空间的多组平行平面上

具体做法是:用一组(或多组)世界空间朝向的平行平面来定义采样层,相机无论怎么平移旋转,采样点永远落在这些静止的平面上。由于采样点在平面上是“无限密集”的,相机移动时样本只会沿平面滑动,永远不会穿过采样层——锯齿的根源被直接消灭了。

这个思想对应的核心代码是RaymarchStructured(RayMarchCore.cginc):先计算射线与每组平面的交点作为起始偏移t_0和步长dtIntersectPlanes负责这部分),再沿着平面逐层采样,最后把多组采样的结果按权重混合。

核心实现:一个围绕相机的十二面体

那么“用哪几组世界空间平面”就成了关键。volsample 的答案是:正十二面体(Dodecahedron)。十二面体的每个五边形面对应一组平行平面方向,12 个面覆盖了所有主要朝向,方向分布均匀,任意视线方向都能找到合适的采样平面。

具体构建工作由 PlatonicSolidBlend.cs 完成:它动态生成一个带倒角的十二面体网格,并把每组平面的法线编码进顶点的 UV 通道、把混合权重写进顶点色,然后让这个十二面体始终围绕相机栅格化渲染。

为什么需要“倒角”?因为不同面相交的棱边和顶点处,单组平面无法平滑衔接。倒角把棱边变成矩形、顶点变成小三角形,让三组平面可以在这些区域平滑过渡。

混合三趟渲染:1条、2条、3条射线

体积渲染时,像素被分成三种情况(见 VolumeRender.shader 的三个 Pass):

  • 五边形面区域:只用 1 条射线采样,权重为 1;
  • 倒角棱边矩形区域:用相邻两组平面的 2 条射线采样后混合;
  • 倒角顶点三角区域:用 3 组平面的 3 条射线采样后混合。

每条射线的混合权重会依据视线与平面的夹角(步长大小)平滑计算,保证三种区域之间没有硬边界、不产生接缝。这种“按几何区域分配采样射线数量”的设计,让画面在任意角度下都稳定且无明显瑕疵。

怎么亲手体验 volsample?

volsample 是一个开箱即用的 Unity 5 项目,克隆仓库后直接用 Unity 打开即可:

git clone https://gitcode.com/gh_mirrors/vo/volsample

体验入口非常友好:

  1. 打开测试场景src/unity/Assets/Scenes/下提供了云(clouds.unity)、雾立方体(fogcube.unity)和斯波扎大教堂(sponza.unity)三个体积渲染场景;
  2. 一键切换算法:运行后屏幕左上角有 GUI 开关,Structured Sampling是结构化采样,关闭它即可切换回 Fixed-Z(还可勾选Pin Samples对比 Fixed-Z Pinned),直观对比两种方案在相机移动时的画面差异;
  3. 控制逻辑:场景切换、关键词开关由 StructuredVolumeSampling.cs 的OnGUIOnRenderImage(第 80 行起)驱动。

如果你不想装 Unity,也可以直接看 Shadertoy 风格的 GLSL 源码:src/shadertoy/clouds.shader 是完整的体积云实时演示(点鼠标可切换结构化/朴素采样),src/shadertoy/diagram_BufA.shader 则是采样原理的可视化示意图。项目的完整幻灯片说明在 doc/volsample.pptx,img/teaser.jpg 是体积云渲染的缩略效果图。

总结:什么时候该用结构化采样?

一句话概括:如果你的体积渲染场景里,相机可能进入体积内部并自由移动(游戏飞行、云层穿梭、医学可视化),结构化采样就是解决闪烁的最优解;而如果你只是固定视角或相机不进入体积,简单的 Fixed-Z 依然够用且更省性能。

volsample 用“世界空间静止平面 + 十二面体几何 + 多射线混合”这套优雅组合,证明了低采样数与高稳定性可以兼得。无论你是做游戏特效、气象可视化还是科研渲染,都值得克隆下来跑一跑,亲眼看看“相机移动不再闪”是什么体验。🚀

【免费下载链接】volsampleStructured Volume Sampling - sample placement algorithm for real-time volume rendering with low aliasing, for camera-in-volume case.项目地址: https://gitcode.com/gh_mirrors/vo/volsample

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

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

【单片机课程设计/毕业设计】分体式红外遥控继电器驱动硬件系统设计与调试 基于单片机按键红外编码发射的多路继电器控制系统设计(021003)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/8/18 16:06:07

3秒给文件“换身份证“:apate 文件格式伪装工具零门槛教程

3秒给文件"换身份证":apate 文件格式伪装工具零门槛教程 【免费下载链接】apate 简洁、快速地对文件进行格式伪装 项目地址: https://gitcode.com/gh_mirrors/apa/apate 传文件被拒、格式不对打不开,几乎是每个电脑用户的日常。今天要聊…

作者头像 李华
网站建设 2026/8/18 15:55:27

医学影像三维可视化实战:3D Slicer免费开源工具完整上手指南

医学影像三维可视化实战:3D Slicer免费开源工具完整上手指南 【免费下载链接】Slicer Multi-platform, free open source software for visualization and image computing. 项目地址: https://gitcode.com/gh_mirrors/sl/Slicer 面对几百张CT、MRI二维切片&…

作者头像 李华
网站建设 2026/8/18 15:53:38

3分钟装好、全程不出网:draw.io 桌面版离线绘图上手记

3分钟装好、全程不出网:draw.io 桌面版离线绘图上手记 【免费下载链接】drawio-desktop Official electron build of draw.io 项目地址: https://gitcode.com/GitHub_Trending/dr/drawio-desktop 公司安全审计那天,摆在技术组面前的问题很具体&am…

作者头像 李华
网站建设 2026/8/18 15:52:52

一枚d3d8.dll救活了我的DX8老游戏:d3d8to9实操全记录

一枚d3d8.dll救活了我的DX8老游戏:d3d8to9实操全记录 【免费下载链接】d3d8to9 A D3D8 pseudo-driver which converts API calls and bytecode shaders to equivalent D3D9 ones. 项目地址: https://gitcode.com/gh_mirrors/d3/d3d8to9 某个周末的晚上&#…

作者头像 李华