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

MY BLOG DIRECTORY:

YivanLee:专题概述及目录

INTRODUCTION:

前段时间和大家讨论起了PreZ和EarlyZ这个话题,发现我的理解并不全面,再经过几番讨论和我查找资料研究源码后,感觉对这块终于有了一些正确的了解。


MAIN CONTENT:

要讨论PreZ和EarlyZ这个话题的话还是要从渲染管线入手。

v2-45a5f51fb22ee07d81d5703c8ba71b37_b.jpg

当我们使用各种方法把场景里的物体尽量剔除干净后,留下了一些我们必须要渲染的物体

v2-a70ba3241bc2816ffc24109ffbfc6548_b.jpg

这些物体的数据就会被送到渲染管线进行渲染。

多数情况会有如下重叠的情况出现

v2-58dbe07bd9a30dae489ea0e8bf26978f_b.jpg

在最原始的渲染流程中,会先渲染A。再渲染B,在渲染B的时候会比较当前渲染的像素的深度和深度Buffer的值,如果通过深度测试则保留,没有通过深度测试则会被丢弃,这时就会带来浪费。当PixleShader计算量越大的时候,这个浪费就会越明显,所以显卡商把深度比较这个事情放到PixleShader前面进行,这个新的阶段取名叫EarlyZ(当然还有其它方法技术名字就是其它的了),如果这个像素一开始就无法通过深度测试,那PixleShader根本就不会计算它,使用这个EarlyZ机制来节省大量性能。(下图中红色部分的像素不会跑PS计算,绿色的会计算)

v2-abb38acf03114584e9403a7277bcde20_b.jpg

EarlyZ使用的时候会有一些限制,Alpha Test或者Depth modify都会使early z失效,但是后面渲染的批次还可以继续使用EarlyZ(Hierachical Z)优化。所以当想要在渲染的时候使用AlphaTest的时候,就不能使用earlyZ优化了。所以把AlphaTest这个操作转移到其它地方去,比如PreDepthPass。

在UnrealEngine4中就把AlphaTest这个操作放到了PrePass中。过程如下:

假设A的黑色区域为OpacityMask的区域

v2-e8fa39a33c98147cb127ceae10544b0f_b.jpg

首先先渲染一次PreDepthPass,这个Pass只渲染深度关闭颜色写入。在渲染Depth的时候就用AlphaTest把OpacityMask的区域像素的深度剔除掉。PrePass写深度的时候因为使用了AlphaTest,所以EarlyZ这个时候失效。

v2-cfd7640d2cbad6a14a8ea4d736b64c7a_b.jpg
v2-0b7da3f42f770854be9710c793bd274d_b.jpg

然后再正常渲染,深度测试设置为Equal模式,正常渲染的时候没有使用AlphaTest,所以EarlyZ在这个时候起效,涂红部分的像素会直接跳过不会进入PixleShader计算。

v2-ab485f86bac7552ca698f6fc25cce1a1_b.jpg

所以当有大量重叠物体,使用PrePass+EarlyZ优化的方案能节省大量性能,比如绝地求生中的大量草丛。


SUMMARY AND OUTLOOK:

下面再来对整个OpacityMask物体和Opaque物体重叠的情况进行详细说明:

v2-374b0d3e6ed2a55e3a8f59f03d3f95e1_b.jpg

假设A为OpacityMask的物体,B为Opaque物体。A的黑色区域为OpacityMask的区域。首先进行PreDepthPass只写入深度,在PreDepthPass中会进行AlphaTest操作,最后可得一张深度图如下图所示(DA表示A物体的深度,DB表示B物体的深度)

v2-4d8a4294ba4db45b50fbf3ea464042d3_b.jpg

然后在BasePass中正常渲染A,B两个物体,深度写入关闭,深度测试模式设置为Equal。在进入PixleShader之前,因为此次渲染没有AlphaTest,也没有修改深度等,所以EarlyZ优化起效。EarlyZ会使用PrePass绑定的DepthBuffer进行比较,被阻挡的像素不会进入像素着色器(红色标注部分)

v2-1b634d38e05d57cf57634963b77c0f81_b.jpg

绿色部分的像素会进入像素着色器

v2-028a531d29124c17b0c20b4146765e4d_b.jpg

因为开启的深度测试模式是Equal,所以蓝色部分的像素会被丢弃掉,自然就形成了OpacityMask的效果

v2-3fc5974e900f23ed479623b85b58d7b8_b.jpg

最后完成渲染。

v2-bed8b323e1b72bb7dbb93e5dd78a9762_b.jpg

Enjoy it。


NEXT:

todo...

发布了384 篇原创文章 · 获赞 4 · 访问量 8041

猜你喜欢

转载自blog.csdn.net/cpongo10/article/details/100745176
UE4