跳转到主要内容

深度预渲染优化指南:PreZ Pass全解析

demi 提交于

PreZ Pass(预写深度通道)是优化3D渲染性能的技术,通过先写深度再写颜色的两阶段渲染避免过度绘制。其核心原理是提前生成深度缓冲区,使主渲染Pass能利用Early-Z剔除被遮挡像素,大幅减少无效着色计算。该技术特别适用于植被、复杂遮挡场景,但对透明混合无效且会增加Draw Call开销。实现时需关闭主Pass的深度写入,仅做深度测试。PreZ Pass显著提升高填充率场景性能,是游戏引擎的常用优化手段。

下面详细介绍 PreZ Pass(预写深度通道),包括原理、流程、优缺点及实际应用场景。

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>1. PreZ Pass是什么?</strong></font>

PreZ(或 Z-prepass、Depth Pre-pass)是现代渲染管线中的一个先写深度、后写颜色的渲染步骤。

其核心思想:
首先给场景所有物体做一次只写深度的渲染,生成准确的深度缓冲区,再用这个深度信息优化后续主渲染过程。

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>2. PreZ Pass的作用和原理</strong></font>

<strong>为什么要做 PreZ?</strong>

避免“过度绘制”(overdraw):很多像素被后面的物体遮挡,主pass浪费着色器计算;PreZ能让这些像素提前被丢弃。

让 Early-Z(提前深度测试)最大化生效:只有深度缓冲里提前有正确数据,主pass才能真正做到“像素没被遮挡才算颜色”。

<strong>工作流程</strong>

1. PreZ Pass
<ul><li>只渲染深度,不写颜色(可关闭颜色输出)。</li>
<li>片元着色器只做 alpha-test、或者最简单的深度值。</li></ul>

2. 主渲染 Pass
<ul><li>开启深度测试和 Early-Z。</li>
<li>任何被遮挡的像素直接跳过昂贵的像素着色器,大幅提高性能。</li></ul>

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>3. PreZ Pass流程示意</strong></font>

1. 第一遍(PreZ Pass):
<ul><li>深度测试:开启,一般用“LESS”。</li>
<li>渲染目标:只有深度缓冲,颜色输出可以禁用。</li>
<li>着色器可以极简,仅 alpha-test(如果需要透明裁剪)。</li></ul>

2. 第二遍(主渲染 Pass):
<ul><li>读取深度缓冲区。</li>
<li>GPU使用 Early-Z 剔除被遮挡片元,仅渲染可见内容。</li></ul>

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>4. 优点</strong></font>

大幅降低无用像素着色和带宽消耗,性能提升显著,尤其是复杂遮挡场景。

Alpha-test 透明截断场景(树叶、草地、灌木等)最受益,遮挡片元直接丢弃。

与 MSAA + Alpha-To-Coverage 配合可获得更平滑的透明轮廓。

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>5. 缺点/注意点</strong></font>

增加一次场景遍历(多了一帧的Draw Call和小部分填充开销)。

如果场景极简单、遮挡极少,PreZ收益有限。

对于透明混合(非alpha-test)不能用PreZ,因为混合不像深度那样判定遮挡。

需要在主pass渲染时关闭写入深度(否则EarlyZ效果会被打破)、只做深度测试。

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>6. 典型应用场景</strong></font>

大面积覆盖的植被、草地、灌木、墙面等遮蔽物。

大型室外场景(树木、石头多、场景复杂)。

高填充率、复杂模型重叠的视角。

对单帧处理性能优化时,优先考虑PreZ Pass。

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>7. 实现示例(伪代码)</strong></font>

PreZ Pass渲染设置:
<pre>// 伪代码,仅说明思路
SetRenderTarget(None, DepthTexture); // 只写深度
EnableDepthTest(true);
EnableDepthWrite(true);
EnableColorWrite(false); // 不写颜色
EnableAlphaTest(true); // 仅必要时(如alpha遮罩)

DrawScene(); // 渲染所有物体
</pre>

主 Pass:
<pre>// 颜色输出、MSAA、Alpha-to-coverage等
SetRenderTarget(ColorTexture, DepthTexture); // 读深度,写颜色
EnableDepthTest(true);
EnableDepthWrite(false); // 只做深度判定,不写新深度
DrawScene(); // 渲染所有物体(同PreZ 顺序/或按前后分层)
</pre>

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>8. 小结</strong></font>

PreZ Pass(预写深度)是优化遮挡关系复杂场景性能的有效工具,配合 Early-Z 能最大限度减少无效的片元着色计算,让复杂场景渲染更加高效,长期被大量游戏、引擎所采用。

<hr>

<font color="#9a9a9a">版权声明:本文为CSDN博主「你一身傲骨怎能输」的原创文章,</font>
<font color="#9a9a9a">遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。</font>
<a href="https://blog.csdn.net/qq_33060405/article/details/150940333"><font color="#9a9a9a">原文链接:https://blog.csdn.net/qq_33060405/article/details/150940333</font></a&gt;
<br>