Hey,是不是在3D渲染时遇到过性能瓶颈?今天就来聊聊PreZ Pass,这个提升渲染效率的神技!
PreZ Pass是什么?
PreZ Pass,顾名思义,就是先渲染深度信息,再渲染颜色信息。它的核心思想是,先计算出场景中每个物体的深度,然后利用这个深度信息来优化后续的渲染过程。
PreZ Pass的作用和原理
为什么要用PreZ Pass呢?主要是为了避免“过度绘制”,也就是很多像素被后面的物体遮挡,主渲染过程却还在计算这些像素的颜色,造成性能浪费。PreZ Pass通过提前计算深度信息,可以让这些被遮挡的像素在早期就被丢弃,从而提高渲染效率。
PreZ Pass流程示意
- 第一遍(PreZ Pass):只渲染深度,不写颜色。片元着色器只做alpha-test或者最简单的深度值。
- 第二遍(主渲染 Pass):读取深度缓冲区,GPU使用Early-Z剔除被遮挡片元,仅渲染可见内容。
优点
- 大幅降低无用像素着色和带宽消耗,性能提升显著。
- Alpha-test透明截断场景(如树叶、草地等)最受益。
- 与MSAA + Alpha-To-Coverage配合可获得更平滑的透明轮廓。
缺点/注意点
- 增加一次场景遍历,多了一帧的Draw Call和小部分填充开销。
- 如果场景极简单、遮挡极少,PreZ收益有限。
- 对于透明混合(非alpha-test)不能用PreZ。
- 需要在主pass渲染时关闭写入深度,只做深度测试。
典型应用场景
- 大面积覆盖的植被、草地、灌木、墙面等遮蔽物。
- 大型室外场景(树木、石头多、场景复杂)。
- 高填充率、复杂模型重叠的视角。
实现示例(伪代码)
// 伪代码,仅说明思路
SetRenderTarget(None, DepthTexture); // 只写深度
EnableDepthTest(true);
EnableDepthWrite(true);
EnableColorWrite(false); // 不写颜色
EnableAlphaTest(true); // 仅必要时(如alpha遮罩)
DrawScene(); // 渲染所有物体
// 颜色输出、MSAA、Alpha-to-coverage等
SetRenderTarget(ColorTexture, DepthTexture); // 读深度,写颜色
EnableDepthTest(true);
EnableDepthWrite(false); // 只做深度判定,不写新深度
DrawScene(); // 渲染所有物体(同PreZ 顺序/或按前后分层)
小结
PreZ Pass是优化遮挡关系复杂场景性能的有效工具,配合Early-Z能最大限度减少无效的片元着色计算,让复杂场景渲染更加高效。
我是苏承栈,来自极星编程网(www.jxgpc.com),更多技术干货,尽在极星编程网!
