本章谈论与深度有关的话题,分别是深度缓冲,深度测试,以及earlyZ,preZ
首先深度存在的价值:
为了正确展示物体的前后遮挡关系,我们用深度来确定,而深度测试正是比较深度信息来计算颜色。而这也就是画家算法

画家算法指的是先画距离我们远的物体,再画更近的,不断拉近,这样的话我们就得到了物体的正确遮挡关系
而深度测试正是类似的想法
对于Z-Buffer, 他不断更新对应像素的深度,总是记录最小值,与此同时更新frame buffer
需要提醒的是:深度总是在0-1范围,尽管NDC空间的z是-1~1,我们也会映射到0-1


深度图中越黑意味着越近

深度测试算法


EarlyZ
我们注意到,画家算法在某些情况下极为浪费性能,如一叶障目的情况下,这个时候我们用画家算法的话,还是会渲染叶子后面的所有物体,但我们只看到了叶子。那么我们有什么方法优化吗,earlyZ就应运而生


首先回忆渲染管线,我们原本在光栅化后计算片元的着色后进行深度测试,那我完全可以在计算着色前就判断啊!
因此一般的显卡硬件都有相应的算法在计算偏远之前进行EarlyZ测试
在下列条件earlyZ失效:
开启Alpha测试
关闭深度测试
开启Alpha Blend
存在clip/discard操作
失效的原因都是因为在earlyZ就进行了深度写入,那么如果后续该片元被剔除了意味着错误写入。
preZ
就是使用两个pass
在第一个Pass即Z-Prepass中仅仅只进行深度测试渲染得到一张深度纹理,不计算输出任何颜色,
在第二个Pass中关闭深度写入,并且将深度比较函数设置为相等。
一般preZ配合earlyZ使用
也就是说,preZ先算好最小的深度,earlyZ快速剔除深度大的片元
然而这又出现了另一个问题,多pass会终止动态批处理,因此对于这种情况,我们可以把这两个pass分为2个shader
Unity的渲染队列

顺带一提unity的渲染队列,它将会将不透明物体按照深度先从小到大排序,然后渲染,这样充分利用了earlyZ剔除片元,对于透明物体,只能从后往前遵从画家算法进行排序计算。
参考:
unity shader 入门精要
Games101 课程