ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

遮挡剔除 HZB

遮挡剔除 HZB 1. 引言在实时渲染中遮挡剔除Occlusion Culling是提升性能的关键手段之一。它的核心思想很简单不绘制那些被其他物体挡住、最终不会出现在屏幕上的物体。而 HZBHierarchical Z-Buffer层次 Z 缓冲正是实现高效遮挡剔除的一种经典且强大的数据结构。本文将从零开始用通俗的语言带你理解 HZB 的原理、构建方式以及它在实际渲染管线中的应用。2. 为什么需要遮挡剔除想象一个大型游戏场景你站在一栋大楼前身后是整座城市。如果 GPU 老老实实地把城市里每一栋楼、每一条街道的三角形都画一遍那么大量被大楼挡住的物体其实根本不会出现在屏幕上白白浪费了宝贵的渲染时间。遮挡剔除要解决的就是这个问题在绘制之前先判断某个物体是否可见如果不可见就直接跳过。常见的剔除手段包括视锥剔除Frustum Culling剔除不在摄像机视野范围内的物体。背面剔除Backface Culling剔除背对摄像机的三角形。遮挡剔除Occlusion Culling剔除被其他物体完全遮挡的物体。前两种相对简单而遮挡剔除因为要判断“谁挡住了谁”需要更巧妙的数据结构HZB 就是其中的代表。3. 从 Z-Buffer 到 HZB要理解 HZB先得回顾它的基础——Z-Buffer深度缓冲。在渲染过程中GPU 会为屏幕上的每个像素记录一个深度值表示该像素距离摄像机有多远。当两个物体投射到同一个像素时深度值小的更靠近摄像机会覆盖深度值大的。这个深度缓冲就是 Z-Buffer。Z-Buffer 本身是逐像素的分辨率很高。但如果我们想快速判断“一个很大的物体是否被遮挡”逐像素检查显然太慢了。于是就有了 HZB 的思路把 Z-Buffer 逐级缩小每一级都记录上一级中更大远的深度值即更远离摄像机的值形成一棵“深度金字塔”。这样当我们想判断一个物体是否被遮挡时不需要看每一个像素只需要在合适的层级上做少量采样即可。4. HZB 的构建过程HZB 通常不是直接证明“物体可见”而是尝试证明“物体肯定被完全挡住”。只要无法确定就保守地让物体继续绘制。HZB 的构建本质上是一个降采样Downsampling的过程。假设原始 Z-Buffer 的分辨率是 1024×1024那么构建过程如下第一级Level 0就是原始的 Z-Buffer。第二级Level 1分辨率降为 512×512每个像素取 Level 0 中对应 2×2 区域里的最大远深度值。第三级Level 2分辨率降为 256×256每个像素取 Level 1 中对应 2×2 区域里的最大远深度值。以此类推直到分辨率降到 1×1 为止。为什么要取最大值而不是最小值因为最大值代表“这个区域里离摄像机最远的深度”。如果一个物体的深度比这个最远值还大说明它完全在这个区域之后必然被遮挡。在实际工程中在普通 Z 和 Reversed-Z 中深度数值的远近方向相反所以实现里到底取min还是max不能死记。原则始终是一样的不能漏掉任何可能可见的部分降采样时取最远的深度值。5. 用 HZB 做遮挡剔除有了 HZB 之后遮挡剔除的流程大致如下把待检测物体的包围盒Bounding Box投影到屏幕上得到一个屏幕空间矩形。根据这个矩形的大小在 HZB 中选择一个合适的层级。原则是矩形越大选择的层级越高分辨率越低这样只需要采样少数几个像素。在选定的层级上采样矩形覆盖范围内的深度值取其中的最小近值。把物体的实际深度通常是包围盒离摄像机最近的那个点的深度与采样到的深度值比较如果物体的深度更大说明它完全被遮挡可以剔除否则保留。这里的关键是“选择合适的层级”。如果层级选得太高分辨率太低采样结果过于粗糙可能会误判把本来可见的物体剔除掉如果层级选得太低分辨率太高采样次数太多性能收益不明显。工程上通常根据投影矩形的面积来动态选择层级。6. 一个简单的伪代码示例下面用伪代码描述 HZB 遮挡剔除的核心逻辑帮助你理解整体流程// 判断物体是否被遮挡 bool IsOccluded(HZB hzb, BoundingBox bounds, Camera camera) { // 1. 把包围盒投影到屏幕空间 ScreenRect rect ProjectToScreen(bounds, camera); // 2. 根据投影面积选择合适的 HZB 层级 int level SelectLevel(rect.Area()); // 3. 在选定层级上采样深度取最大远值 float maxDepth hzb.SampleMaxDepth(rect, level); // 4. 计算物体离摄像机最近的深度 float objectDepth bounds.NearPlaneDepth(camera); // 5. 如果物体深度更大说明被完全遮挡 return objectDepth maxDepth ; }7. HZB 的优缺点优点缺点剔除效率高适合大量静态和动态物体构建 HZB 本身需要额外的 GPU 开销层级结构天然支持“由粗到细”的快速判断对细长或形状不规则的物体包围盒投影可能不够精确实现相对成熟主流引擎均有支持需要维护深度缓冲且更新时机需要精心设计在实际项目中HZB 通常不会单独使用而是与视锥剔除、软件光栅化剔除等手段配合形成一套完整的剔除方案。8. 总结HZB 是一种基于深度金字塔的遮挡剔除技术核心思想是把逐像素的深度信息逐级降采样从而用很小的代价快速判断物体是否被遮挡。它的构建过程简单、剔除效率高是实时渲染中不可或缺的工具之一。9.Tips1、HZB 并不能完全判断所有遮挡情况例如下图下边一个简化的二维空间例子A点比B点离摄像机更近所以经过遮挡剔除算法并不能判断方块被遮挡方块不会在遮挡剔除这个阶段被剔除。方块还是会被渲染但是方块的像素颜色否显示在最终的画面上还是看方块的每个像素的深度是否在相机的最近距离了
返回列表