参考:
Rendering学习:Early-Z与Z-PrePass - 技术专栏 - Unity官方开发者社区
通过深度测试后会写入深度值,EarlyZ在片元着色器之前执行,如果片元着色器中有影响最终像素是否写入的操作,比如手动修改插值后的深度值,或者启用AlphaTest,则无法提前判断最终写入的深度值。
进一步,如果通过了EarlyZ,但是并没有通过AlphaTest,则不能写入深度值,所以此时EarlyZ不能生效,否则会把不该写入的深度写入进去,导致遮挡关系出错。
比如渲染启用了AlphaTest的树木,不透明对象从近往远渲染,但是由于树木并不能使用EarlyZ,即使被遮挡也要执行完片元着色器才能决定是否渲染到FrameBuffer中。
ZPrepass的使用
在场景不方便进行从近到远排序的时候,先渲染一遍不透明对象的深度,配合Early-Z避免后续无效的执行片元着色器。
prepass优点,主要就是移除overdraw,降低fragment shading的workload;结合depth prepass的做法,我们知道,它需要将物体的渲染拆分为两步(在同一个render pass内),第一步,渲染depth,第二步,渲染颜色,所以物体的geometry部分(指pipeline中光栅化之前的部分)是需要做两遍的,这是主要的缺点。
这里稍微提一下,渲染depth的时候,对于完全不透明的物体,fragment shader是完全可以不执行的;对于那种要做alpha test的物体(比如树,草),由于只能部分更新depth,仍然需要在fragment shading的时候根据texture的alpha值选择性的discard掉一些fragment位置的depth 更新,所以这时候仍然需要fragment shader,不过此时的fragment可以很简单,采样texture的alpha通道,不满足条件discard即可。对于需要blend的半透明物体,一般是不会用depth prepass的,原因很简单,半透明的物体一般不会写depth。
缺点:增加geometry部分的workload。所以对于那些,overdraw比较多而且它的fragment shader比较复杂导致fragment shading成为瓶颈的物体的渲染,更推荐使用depth prepass。花草和树叶由于数量繁多、相互交错,很难按照从前到后进行排序,这时候early z test很难起到作用,导致overdraw很重,是比较典型的推荐使用depth prepass的案例。