Hotdry.

Article

现代GPU渲染中的可见性剔除技术:工程实现与性能权衡

系统综述GPU渲染管线中的可见性剔除技术,涵盖视锥剔除、层级Z缓冲、门户剔除等工程实现与性能优化策略。

2026-04-20systems

在现代 GPU 渲染管线中,可见性剔除技术是决定渲染性能的核心要素。随着场景复杂度从数万几何体增长到数百万乃至数千万级别,如何高效地丢弃不可见对象,将渲染资源集中于可见区域,直接影响着帧率稳定性和用户体验。本文系统梳理主流剔除技术的工程实现路径与性能权衡,为引擎开发者提供可操作的参数指引。

视锥剔除:基础但不可替代的第一道防线

视锥剔除是渲染管线中最基本也是最早执行的剔除步骤,其核心逻辑是判断对象的空间包围盒是否与摄像机视锥体相交。任何与视锥体无交集的对象都可以直接丢弃,无需进入后续渲染阶段。这道防线的实现分为两大流派:CPU 端剔除与 GPU 端剔除。

CPU 端视锥剔除的优势在于剔除结果可直接影响 Draw Call 调度,开发者可以在提交绘制前就决定哪些对象需要参与渲染。其典型实现流程为:每帧更新对象的变换矩阵,计算世界空间下的包围盒(通常使用轴对齐包围盒 AABB 或 Oriented Bounding Box),将包围盒的八个顶点投影到视锥体空间进行交集测试。当场景包含数万个对象时,CPU 端串行遍历的开销不可忽视,此时 GPU 驱动渲染(GPU-Driven Rendering)成为更优选择。GPU 端视锥剔除利用计算着色器并行处理大量对象,每个线程负责一个对象的剔除判断,结果写入间接绘制缓冲区,CPU 仅需执行一次间接调用即可完成所有可见对象的渲染。Bevy 引擎在其最新版渲染器中即采用了这一方案,通过 GPU 计算着色器完成视锥剔除后直接触发间接绘制,省去了 CPU 端的遍历开销。

值得注意的是,视锥剔除的粒度选择直接影响效率。过于粗粒度的剔除可能导致大量零碎对象被错误保留,过于细粒度则带来过高的测试开销。工程实践中通常将场景划分为多级层次结构(如 BVH),先对粗粒度节点进行剔除测试,仅对通过测试的节点进一步检查其子对象,这种分层策略在大型开放世界场景中效果显著。

层级 Z 缓冲剔除:遮挡剔除的核心支柱

当对象位于视锥体内但被其他几何体遮挡时,视锥剔除无能为力,此时需要遮挡剔除(Occlusion Culling)技术介入。层级 Z 缓冲(Hierarchical Z-Buffering,简称 HZB)是当前工业界最成熟的遮挡剔除方案,其核心思想是利用多分辨率深度金字塔快速判断对象是否被遮挡。

HZB 的工程实现包含三个关键阶段。第一阶段是深度金字塔构建:渲染遮挡物(Occluder)到深度缓冲后,通过多次降采样生成 Mip 链,每层 Mip 存储对应 2x2 像素区域的最大深度值(针对 Z 轴正向)或最小深度值(针对 Z 轴负向),形成从精细到粗糙的深度金字塔。第二阶段是遮挡测试:对于每个候选被遮挡物(Occludee),计算其屏幕空间包围盒,根据包围盒尺寸选择合适层级的 Mip 进行采样深度比对。若包围盒中心深度大于采样深度的最大值,则该对象被判定为不可见。第三阶段是结果应用:通过测试的对象进入后续渲染流程,未通过测试的对象可延迟至后续帧重新评估。

HZB 的工程参数直接影响剔除效果与性能开销。深度缓冲分辨率通常设置为渲染分辨率的 1/4 至 1/8,过低会降低剔除精度导致过多无效绘制,过高则增加显存与带宽消耗。Mip 层级数量的选择需要权衡精度与构建开销,典型配置为 4 至 6 层。测试阈值设置上,对包围盒深度比较时引入适量余量(Margin)可以避免边缘情况下的错误剔除,但过大的余量会导致本应剔除的对象被错误保留。此外,HZB 的 GPU 内存占用需要在多帧之间复用,并通过双缓冲机制避免数据竞争。

门户剔除:室内场景的针对性优化

对于建筑内景、地下设施等具有明确空间划分结构的场景,门户剔除(Portal Culling)是一种高效的区域级剔除方案。其核心思想是将场景划分为多个连通区域,相邻区域之间通过 “门户” 进行连接,只有当摄像机所在区域的门户可见时,才需要渲染相邻区域的内容。

门户剔除的工程实现需要场景编辑器提供预处理支持。设计师在构建关卡时标注门户位置与连接关系,系统据此构建区域 - 门户拓扑图。运行时每帧执行以下流程:确定摄像机当前所在区域,根据摄像机视锥体筛选该区域的所有门户;对于每个可见门户,计算其屏幕空间透视投影结果,只有当门户在视锥体内且未被完全遮挡时,才将门户对应的相邻区域标记为潜在可见;递归执行上述过程,直到所有可见区域确定完毕。Unreal Engine 和 CryEngine 等商业引擎的室内渲染系统均采用了这一技术的变体。

门户剔除的效率高度依赖场景布局的合理性。理想的门户应该是相对较小的开口(如门框、窗洞),这样可以利用视锥剔除快速过滤大量不可见区域。相反,如果场景中充满大面积开放空间,门户剔除的效果会大打折扣。工程实践中常采用 “保守可见集” 策略:即使某区域理论上不可见,仍将其部分几何体纳入渲染队列,以避免穿墙瞬间的对象突然弹出。

混合策略与前沿演进

现代渲染引擎很少依赖单一剔除技术,而是构建多阶段混合剔除管线。典型配置为:视锥剔除作为第一级过滤,移除视锥体外对象;LOD 选择基于距离进一步简化几何体复杂度;HZB 遮挡剔除处理视锥体内被遮挡对象;门户剔除或区域剔除处理特定场景结构;Early-Z 与 Tile-Based 光栅化在硬件层面提供最后一层保障。各阶段顺序与参数需要根据目标硬件特性和场景类型进行调优。

GPU 驱动渲染的普及正在改变剔除技术的部署形态。传统上剔除由 CPU 执行并产生 Draw Call,但 CPU-GPU 通信开销在对象数量突破数十万时成为瓶颈。新型方案将剔除完全迁移至 GPU:计算着色器并行处理所有对象,生成可见对象索引缓冲,再通过间接绘制调用完成渲染。这种模式在《刺客信条》、《看门狗》等开放世界大作中已有成熟应用。

从性能监控角度,开发者应关注以下关键指标:剔除前后的 Draw Call 数量对比(理想情况下剔除率应达 70% 以上)、GPU 时间中顶点处理与光栅化占比、深度缓冲带宽消耗、遮挡查询延迟(Occlusion Query Latency)。当发现剔除效率下降时,首先排查场景中是否存在过多小尺寸对象(其包围盒与视锥体的交集测试开销可能超过渲染开销),其次检查遮挡物数量是否足够支撑 HZB 的有效运作。

工程实践建议

针对不同规模与类型的场景,推荐以下参数配置作为起点:对于大型户外场景,以视锥剔除为主、HZB 为辅,设置视锥剔除的 AABB 简化阈值为包围盒对角线长度的 5%,HZB 深度缓冲降采样倍率为 4;对于室内场景,优先部署门户剔除系统,配合适度的视锥剔除,门户筛选深度控制在 3 至 5 层递归;对于 VR 等对帧时间敏感的场景,所有剔除操作应在 GPU 计算着色器中异步执行,避免 CPU 端的同步等待。

在实现层面,建议采用数据驱动架构:所有可剔除对象注册到统一的对象注册表,每帧由剔除系统生成可见对象列表,渲染系统仅消费该列表。这种分离设计使得剔除策略的迭代优化不会影响渲染通路的稳定性。同时,剔除系统应支持帧时间预算控制:当单帧剔除耗时超过阈值时,自动降级为更简单的剔除策略(如仅执行视锥剔除),保障帧率平稳。


参考资料

  • GPU-Driven Rendering and Culling techniques, williscool.com
  • Hierarchical Z-Map Based Occlusion Culling, RasterGrid Blog
  • Advanced Occlusion Culling with Portals, Hi-Z Buffers and Clustered Rendering, Daydream Soft
  • Bevy Engine GPU Frustum Culling Implementation, GitHub Pull Request #12889
  • Unreal Engine Culling/Visibility Techniques Documentation

systems