现代渲染剔除技术大揭秘:多种剔除方法助力游戏性能优化!

张开发
2026/5/4 5:37:12 15 分钟阅读
现代渲染剔除技术大揭秘:多种剔除方法助力游戏性能优化!
【krupitskas参与的首款游戏挑战】2026年4月16日阅读时长16分钟。《黑道圣徒3重制版》是krupitskas参与发布的第一款游戏。钢港是建筑密集的开放世界城市还有狭窄室内走廊、喷气式飞机、汽车和跳伞场景做好剔除工作极具挑战在此向Timur Gagiev致敬。【引言剔除技术的重要性】在如今AI编程、“AI游戏生成”、DLSS 5、虚幻引擎5以及惊艳的高斯模糊演示的时代有人认为图形和游戏开发问题已解决这显然是无稽之谈。艰苦的工程工作、专业知识、权衡取舍和艺术指导不会过时所有游戏都需优化而剔除是重要的优化手段之一。好消息是近80%的优化方法可归结为“在不需要的时候别做多余的蠢事”坏消息是仍需在平衡场景结构、游戏设计、艺术指导、硬件限制和性能预算的前提下实现剔除功能。本文将介绍现代实时渲染器中常用的主要剔除技术。【1. 基础剔除距离剔除、背面剔除和视锥体剔除】这些是成本最低且应用最广泛的剔除技术会在执行更复杂的剔除操作之前先处理明显不需要渲染的对象。【距离剔除】最简单的形式是若对象与相机的距离超过最大距离就跳过该对象。这种方法速度极快对消失后视觉影响较小的小道具有效大多数引擎允许为每个网格或材质设置剔除距离。难点在于避免出现明显的突然显示或消失现象常见解决方法包括抖动淡入淡出、在剔除点之前采用激进的细节层次LOD切换或者使用替身。仅依靠距离剔除无法很好处理对象在屏幕上投影后只占几个像素的情况还需要进行屏幕空间尺寸检查。【背面剔除】这通常是使用图形API时遇到的第一种剔除技术作为管线状态对象PSO的一部分进行配置启用它是最容易获得性能提升的方法之一。每个三角形都有正面和背面对于封闭的网格背面永远不会被看到GPU可根据绕序自动跳过背面大约可节省典型几何体一半的光栅化和片段处理工作。在传统的顶点 片段管线中背面剔除在顶点着色器处理完顶点之后进行只能节省光栅化和片段处理的工作而无法节省顶点处理的工作在更偏向GPU驱动的管线中可将决策提前。背面剔除几乎是零成本的但会与透明度、双面材质以及一些明确利用它的剔除算法相互影响。【视锥体剔除】对于透视相机视锥体是截断的金字塔形状的空间表示相机能够看到的范围视锥体之外的物体不需要渲染。视锥体剔除会通过边界体测试物体与视锥体的六个面是否相交跳过不相交的物体。视锥体剔除几乎总是剔除管线中的第一步或者在距离剔除之后作为第二步速度快、成本低能一次性剔除场景中的大量物体。但对象级剔除存在核心权衡许多小物体可实现细粒度的剔除但每个物体都需要一个绘制调用和一次CPU端的可见性测试少数大物体的绘制调用成本较低但即使其中90%的三角形在屏幕外也不得不渲染整个物体并且要为所有这些三角形支付顶点着色器的成本。【2. 遮挡剔除】遮挡剔除可判断哪些物体被其他物体遮挡虽然实现起来更复杂但在像城市或室内这样的密集场景中往往能带来最大的性能提升。【硬件遮挡查询】所有主流图形API都提供类似遮挡查询的功能基本原理是渲染代理几何体并统计通过深度测试的样本数量若没有可见样本则说明代理几何体从该视角完全被遮挡通常可跳过渲染真实物体。在DX12中可使用 D3D12_QUERY_TYPE_BINARY_OCCLUSION它只返回0或1更节省成本。这里存在延迟和同步问题CPU通常在渲染第N 1帧时读取第N帧的结果这种一帧的延迟通常可接受但可能会导致短暂地继续渲染刚刚被遮挡的物体或者跳过刚刚变得可见的物体。【软件遮挡剔除CPU端】与向GPU请求查询不同可在CPU端光栅化一个低分辨率的深度缓冲区并根据这个缓冲区来测试物体是否被遮挡。英特尔的掩码软件遮挡剔除MSOC是这方面最知名的实现它使用SIMD指令以8x4像素的图块为单位来光栅化三角形每秒可以处理数百万个三角形。其优点是没有回读延迟缺点是会消耗CPU资源并且需要维护一个单独的简化遮挡物网格。【Hi - Z分层Z缓冲区】Hi - Z是深度缓冲区的多级纹理链通常被称为深度金字塔每一级存储屏幕上更大区域的保守深度值。要测试一个物体是否被遮挡需将其边界投影到屏幕空间选择大致匹配其覆盖范围的多级纹理级别然后将物体的最近深度与金字塔中的值进行比较。这种表示方式要保持保守性优秀的实现方案会更倾向于出现false negatives误判为可见而不是false positives误判为遮挡。这是当今大多数基于GPU的遮挡剔除的基础构建和查询速度都很快并且完全在GPU上进行。【双通遮挡剔除】在基于GPU的渲染器中常见模式是在渲染当前帧之前使用上一帧的Hi - Z来剔除物体。简单的单通方法成本较低但刚刚变得可见的物体会被错误地剔除在下一帧才会显示出来。双通方法解决了这个问题第一遍测试上一帧可见的物体渲染仍然可见的物体并从它们构建一个新的Hi - Z第二遍对第一遍中被剔除的所有物体进行重新测试将其与新的Hi - Z进行比较。第一遍使用的Hi - Z仍然是上一帧的会存在一些小的残留误差在相机突然切换的情况下会出现一帧的错误显示引擎通常会检测到这种情况并在该帧回退到完整的深度预渲染通道。与始终进行完整的深度预渲染通道相比基于GPU的双通方法成本要低得多这也是大多数现代游戏引擎采用这种方法的原因。【3. 更多剔除技术】【屏幕尺寸剔除】与基于固定的世界空间距离进行剔除不同屏幕尺寸剔除是根据物体在屏幕上的投影面积来决定是否剔除。一个距离相机10米的物体可能值得渲染但同样的物体在2000米外可能在屏幕上只投影为3个像素这时渲染它的绘制调用开销就不值得了。屏幕尺寸剔除比单纯的距离阈值更能优雅地处理这种情况。例如虚幻引擎使用屏幕尺寸作为静态网格LOD过渡的主要指标而最小/最大绘制距离则是单独的基于距离的控制参数。【潜在可见集PVS】PVS会预先计算世界中每个区域可能看到的其他区域运行时只需查找当前区域的PVS并跳过不在其中的任何区域。这种方法在运行时速度极快但计算成本高并且对动态物体的处理效果不佳。虽然PVS是预先计算好的且效果显著但对于程序生成的游戏来说它可能不切实际或无法实现。《雷神之锤》让PVS声名远扬在一些室内场景几何结构静态且烘焙时间可接受的游戏中它仍然很有用。【门户剔除】对于具有明确房间和门的室内场景门户剔除非常有效。每个门都被视为一个门户通过门户追踪相机的视线只渲染通过可见门户可以到达的房间这样可以非常轻松地剔除整个房间的几何体。门户剔除在许多以建筑为背景的第一人称游戏中很常见它与视锥体剔除配合得很好因为当透过多个门看时门户会自然地缩小有效视锥范围。【4. GPU驱动渲染和集群剔除】这里开始变得有趣起来不再由CPU决定要绘制的对象并为每个对象发出一个绘制调用而是将剔除逻辑推到GPU上并使用间接绘制调用来让GPU做出决策。【间接绘制】DirectX、Vulkan和Metal都支持间接绘制绘制参数来自GPU缓冲区而不是CPU代码。计算着色器执行剔除操作并将仍然可见的对象写入该缓冲区然后一个或少量的间接绘制调用会处理这个紧凑的列表这样CPU就不再需要遍历每个可见对象。InterlockedAdd会将仍然可见的绘制操作打包成一个紧凑的列表ExecuteIndirect会使用GPU写入的计数因此它只会处理在剔除过程中幸存下来的对象。【网格单元/集群剔除】现代基于GPU的渲染器可以在子网格级别进行剔除一个网格会被分割成多个网格单元即小的三角形集群通常每个集群包含大约64 - 128个三角形。每个网格单元都有自己的边界球体和一个表示其三角形法线范围的圆锥体。可以在GPU上独立地对每个网格单元执行视锥体剔除、遮挡剔除和背面剔除这比对象级剔除要精确得多。一个大型角色网格可能包含数百个网格单元从任何给定角度看只有一小部分是可见的。法线圆锥体设计巧妙如果一个网格单元中的所有法线大致指向同一个方向可通过一个非常低成本的圆锥体与视角的测试来拒绝整个网格单元。

更多文章