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