MY BLOG DIRECTORY:
YivanLee:专题概述及目录INTRODUCTION:
前段时间和大家讨论起了PreZ和EarlyZ这个话题,发现我的理解并不全面,再经过几番讨论和我查找资料研究源码后,感觉对这块终于有了一些正确的了解。
MAIN CONTENT:
要讨论PreZ和EarlyZ这个话题的话还是要从渲染管线入手。
![v2-45a5f51fb22ee07d81d5703c8ba71b37_b.jpg](https://ss.csdn.net/p?https://pic4.zhimg.com/v2-45a5f51fb22ee07d81d5703c8ba71b37_b.jpg)
当我们使用各种方法把场景里的物体尽量剔除干净后,留下了一些我们必须要渲染的物体
![v2-a70ba3241bc2816ffc24109ffbfc6548_b.jpg](https://ss.csdn.net/p?https://pic1.zhimg.com/v2-a70ba3241bc2816ffc24109ffbfc6548_b.jpg)
这些物体的数据就会被送到渲染管线进行渲染。
多数情况会有如下重叠的情况出现
![v2-58dbe07bd9a30dae489ea0e8bf26978f_b.jpg](https://ss.csdn.net/p?https://pic4.zhimg.com/v2-58dbe07bd9a30dae489ea0e8bf26978f_b.jpg)
在最原始的渲染流程中,会先渲染A。再渲染B,在渲染B的时候会比较当前渲染的像素的深度和深度Buffer的值,如果通过深度测试则保留,没有通过深度测试则会被丢弃,这时就会带来浪费。当PixleShader计算量越大的时候,这个浪费就会越明显,所以显卡商把深度比较这个事情放到PixleShader前面进行,这个新的阶段取名叫EarlyZ(当然还有其它方法技术名字就是其它的了),如果这个像素一开始就无法通过深度测试,那PixleShader根本就不会计算它,使用这个EarlyZ机制来节省大量性能。(下图中红色部分的像素不会跑PS计算,绿色的会计算)
![v2-abb38acf03114584e9403a7277bcde20_b.jpg](https://ss.csdn.net/p?https://pic1.zhimg.com/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](https://ss.csdn.net/p?https://pic4.zhimg.com/v2-e8fa39a33c98147cb127ceae10544b0f_b.jpg)
首先先渲染一次PreDepthPass,这个Pass只渲染深度关闭颜色写入。在渲染Depth的时候就用AlphaTest把OpacityMask的区域像素的深度剔除掉。PrePass写深度的时候因为使用了AlphaTest,所以EarlyZ这个时候失效。
![v2-cfd7640d2cbad6a14a8ea4d736b64c7a_b.jpg](https://ss.csdn.net/p?https://pic3.zhimg.com/v2-cfd7640d2cbad6a14a8ea4d736b64c7a_b.jpg)
![v2-0b7da3f42f770854be9710c793bd274d_b.jpg](https://ss.csdn.net/p?https://pic2.zhimg.com/v2-0b7da3f42f770854be9710c793bd274d_b.jpg)
然后再正常渲染,深度测试设置为Equal模式,正常渲染的时候没有使用AlphaTest,所以EarlyZ在这个时候起效,涂红部分的像素会直接跳过不会进入PixleShader计算。
![v2-ab485f86bac7552ca698f6fc25cce1a1_b.jpg](https://ss.csdn.net/p?https://pic2.zhimg.com/v2-ab485f86bac7552ca698f6fc25cce1a1_b.jpg)
所以当有大量重叠物体,使用PrePass+EarlyZ优化的方案能节省大量性能,比如绝地求生中的大量草丛。
SUMMARY AND OUTLOOK:
下面再来对整个OpacityMask物体和Opaque物体重叠的情况进行详细说明:
![v2-374b0d3e6ed2a55e3a8f59f03d3f95e1_b.jpg](https://ss.csdn.net/p?https://pic2.zhimg.com/v2-374b0d3e6ed2a55e3a8f59f03d3f95e1_b.jpg)
假设A为OpacityMask的物体,B为Opaque物体。A的黑色区域为OpacityMask的区域。首先进行PreDepthPass只写入深度,在PreDepthPass中会进行AlphaTest操作,最后可得一张深度图如下图所示(DA表示A物体的深度,DB表示B物体的深度)
![v2-4d8a4294ba4db45b50fbf3ea464042d3_b.jpg](https://ss.csdn.net/p?https://pic4.zhimg.com/v2-4d8a4294ba4db45b50fbf3ea464042d3_b.jpg)
然后在BasePass中正常渲染A,B两个物体,深度写入关闭,深度测试模式设置为Equal。在进入PixleShader之前,因为此次渲染没有AlphaTest,也没有修改深度等,所以EarlyZ优化起效。EarlyZ会使用PrePass绑定的DepthBuffer进行比较,被阻挡的像素不会进入像素着色器(红色标注部分)
![v2-1b634d38e05d57cf57634963b77c0f81_b.jpg](https://ss.csdn.net/p?https://pic2.zhimg.com/v2-1b634d38e05d57cf57634963b77c0f81_b.jpg)
绿色部分的像素会进入像素着色器
![v2-028a531d29124c17b0c20b4146765e4d_b.jpg](https://ss.csdn.net/p?https://pic2.zhimg.com/v2-028a531d29124c17b0c20b4146765e4d_b.jpg)
因为开启的深度测试模式是Equal,所以蓝色部分的像素会被丢弃掉,自然就形成了OpacityMask的效果
![v2-3fc5974e900f23ed479623b85b58d7b8_b.jpg](https://ss.csdn.net/p?https://pic1.zhimg.com/v2-3fc5974e900f23ed479623b85b58d7b8_b.jpg)
最后完成渲染。
![v2-bed8b323e1b72bb7dbb93e5dd78a9762_b.jpg](https://ss.csdn.net/p?https://pic3.zhimg.com/v2-bed8b323e1b72bb7dbb93e5dd78a9762_b.jpg)
Enjoy it。
NEXT:
todo...