GPU渲染过程中的Early-Z技术

传统的渲染管线是:
      应用阶段(CPU) ->几何阶段(顶点着色器) -> 光栅化阶段(片元着色器) -> 各种测试(深度测试,透明度测试,模板测试等) -> 颜色缓冲区(buffer)
       一系列测试是在执行过顶点/片元着色器后才执行的,也就是说就算我们指定了一些测试条件来剔除掉一部分像素,但是这些像素还是经过了计算,这部分计算是没有必要的。Over Draw就是这样产生的。

early-z是放在片段着色器之前,所以大致的渲染管线可以描述成:
      应用阶段(CPU)->几何阶段(顶点着色器)->early-z(提前深度测试)->光栅化阶段(片元着色器)->各种测试(深度测试,透明度测试,模板测试等)->颜色缓冲区(buffer)
      提前进行深度测试可以节省不必要像素的片元计算,所以会有性能的提升 

现代GPU中运用了Early-Z的技术,在Vertex阶段和Fragment阶段之间(光栅化之后,fragment之前)进行一次深度测试,如果深度测试失败,就不必进行fragment阶段的计算了,因此在性能上会有很大的提升。但是最终的ZTest仍然需要进行,以保证最终的遮挡关系结果正确。
 

early-z原理是光栅化后直接算深度,alphatest原理是片段着色器算完后算深度。

传统的3D硬件渲染管线中,Z test 所处的位置如下:

-------------------------------
multitex | PixelShader?
fog effects
alpha test
stencil\depth test *
alpha blending
dither
-------------------------------

可以看到,实际上在传统管线中,z test 不可能用来剔除 pixel shader 片断的执行。但是,在当前的一些显卡中,很多都把 z test 提前到了pixel shader 之前执行一次,被称
为 Early -Z Culling 优化。

但是从管线次序中可以清楚地看到,alpha test 成为了 z test 的限制,因为一旦打开了 alpha test, 对于在 alpha test 中失败的像素 Early-Z 将不能正确地被判断。因此对于部分显卡硬件,一旦关闭了 alpha test,Early-Z Culling就会被自动打开。

为了充分体现出 Early-Z Culling 的威力,一般来应该在 prezwriting 的 pass 阶段就应该先执行一次 alpha test,并且关闭对 color target 的填充,在 pixel shader 中只把 alpha值返回出去供 alpha test 使用。

但是问题随之出现: 对于一块未知的3D适配器,无法通过caps得知其是否支持 early-z culling优化,因此一旦在硬件不支持这个特性的显卡上使用此技术,反而会导致效率下降。

Render Pipeline渲染管线概述_Peter_Gao_的博客-CSDN博客

深入剖析GPU Early Z优化 - 风恋残雪 - 博客园

虚幻4渲染编程(Shader篇)【第十四卷:PreZ And EarlyZ In UE4】 - 知乎

EarlyZ和PreZ的区别 - 知乎

[unity]神秘的Early-Z到底是个啥? - 简书

https://sites.google.com/site/luliyi10242/earlyzopt

猜你喜欢

转载自blog.csdn.net/qq_42672770/article/details/122996588