概述
- 深度缓冲是一个与屏幕像素对应的缓冲区,用于存储每个像素的深度值(距离相机的距离);
- 深度测试的主要目的是确保在渲染时,像素按照正确的深度(距离摄像机的距离)顺序进行绘制,从而创建正确的遮挡关系和透视效果。
基本步骤
深度缓冲
ZWrite On // 写入深度缓冲
ZWrite Off // 不写入深度缓冲
不设置的话,默认为写入;
一般在做透明等特殊效果时会设置为不写入;
深度测试
在渲染场景之前,深度缓冲被初始化为最大深度值,表示所有像素都在相机之外;
在渲染过程中,对于每个像素,深度测试会将当前像素的深度值与深度缓冲中对应位置的值进行比较;
一般情况下:
- 如果当前像素的深度值小于深度缓冲中的值,说明当前像素在其他物体之前,它会被绘制,并更新深度缓冲;
- 如果当前像素的深度值大于等于深度缓冲中的值,说明当前像素在其他物体之后,它会被丢弃,不会被绘制,并保持深度缓冲值不变;
ZTest Less // 小于当前深度缓冲中的值,就通过测试,写入到深入缓冲中
ZTest Greater // 大于当前深度缓冲中的值,就通过测试,写入到深入缓冲中
ZTest LEqual // 小于等于当前深度缓冲中的值,就通过测试,写入到深入缓冲中
ZTest GEqual // 大于等于当前深度缓冲中的值,就通过测试,写入到深入缓冲中
ZTest Equal // 等于当前深度缓冲中的值,就通过测试,写入到深入缓冲中
ZTest NotEqual // 不等于当前深度缓冲中的值,就通过测试,写入到深入缓冲中
ZTest Always // 始终通过测试,写入到深入缓冲中
不进行设置的话,默认为LEqual
深度测试和深度写入的好处
让我们不需要关心不透明物体的渲染顺序;
如果关闭深度写入
那么物体的渲染顺序会变得非常重要,谁先被渲染,谁后被渲染都会影响最终的呈现效果;
想要得到正确的半透明混合效果,需要先渲染不透明物体,再渲染透明物体;
如果先渲染没有开启深度写入的前面的物体,之后渲染后面的物体就会将前面物体的颜色覆盖,或出现错误前后关系表现;
如何解决渲染顺序带来的问题
大部分的渲染引擎采取的方式都是先对场景上的物体进行排序,然后再渲染;
常规方法为:
- 先渲染所有不透明物体,开启它们的深度测试和深度写入;
- 将半透明物体按照离摄像机远近进行排序,然后从后往前的顺序渲染它们,开启深度测试关闭深度写入;
这样做的目的是保证靠后的物体颜色能先直接进入颜色缓冲区或混合后进入颜色缓冲区,就不会出现由于先渲染前面的物体导致结果出现问题;
特殊情况
由于排序是基于物体的不是基于片元的,这种情况下会出现问题;
解决方式:
- 忍一忍,接受部分细节的小瑕疵
- 从模型入手,拆分模型
- 使用开启深度写入的半透明效果来模拟半透明(性能消耗较高)