本文主要是介绍3.5 Early-Z 与 Z Prepass,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、深度测试DepthTest
1.传统渲染管线中的深度测试
深度测试在逐片元操作中的第二步
2.解决物体可见遮挡性的问题
3.深度测试的逻辑
for(each triangle T) //对每一个三角形
{ for(each fragment(x,y,z) in T)//对每一个三角形中的片元 { if(fragment.z < ZBuffer[x,y])//深度测试:如果片元深度小于ZBuffer深度{ FrameBuffer[x,y] = fragment.rgb; //更新颜色 ZBuffer[x,y] = fragment.z; //更新深度 } else{ //深度测试失败 //什么都不做,片元数据被丢弃 } }
}
4.深度测试带来的问题
物体2与物体3的计算得到的片元都将会被丢弃
先将1、2、3进行片元着色后,在进行深度测试后抛弃2、3,则2、3在片元部分做的计算都浪费掉了。
二、提前深度测试Early-Z
应用阶段(CPU)->几何阶段(顶点着色器)->early-z(提前深度测试)->光栅化阶段(片元着色器)->各种测试(深度测试,透明度测试,模板测试等)->颜色缓冲区(buffer)
Early-Z失效:
1. 开启Alpha Test 或 clip/discard 等手动丢弃片元操作
2. 手动修改GPU插值得到的深度
3. 开启Alpha Blend
4. 关闭深度测试Depth Test
如果按照3-2-1顺序渲染测试,Early-Z将不会带来任何优化效果
三、使用Z-Prepass
方式一:双Pass法
- 使用两个Pass:
-
- 在第一个Pass即Z-Prepass中仅仅值写入深度,不计算输出任何颜色。
- 在第二个Pass中关闭深度写入,并且将深度比较函数设置为相等。
动态批处理问题:
DrawCall问题:
方式二:提前分离的PrePass
- 仍然使用两个Pass,但:
-
- 将原先第一个Pass(即Z-Prepass)单独分离出来未单独一个Shader,并先使用这个Shader将整个场景的Opaque的物体渲染一遍。
- 而原先材质只剩下元原先的第二个Pass,仍然关闭深度写入,并且将深度比较函数设置为相等。
例子:使用URP下的RendererFeature
Z-Prepass也是透明渲染的一种解决方案
单Pass不写入深度的透明渲染 第一Z-Prepass写入深度,第二Pass(Ztest Equal)透明渲染
四、Z-Prepass所带来的问题
Z-Prepass的计算消耗
五、Early-Z 和 Z-Prepass的实例应用
这篇关于3.5 Early-Z 与 Z Prepass的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!