1.什么是深度?
深度其实就是该像素点在3D世界中距离摄像机的距离,z值
油画算法无法解决重叠的图层,而且在绘制有阻挡的图形的时候,会浪费很多的性能
为什么需要深度缓冲区?
在不使用深度测试的时候,如果我们绘制一个有重叠的图形,先绘制距离较近的物体,再绘制距离较远的物体,则距离远的位图因为后绘制
使用深度测试后,距离观察者较远的位图的深度值和颜色值会被丢弃
深度值的范围是0-1,(OpenGL ES里面,想要开启深度测试,同样是调用glEnable)
我们可以通过glDepthFunc(GLenum func)来修改深度测试的测试规则:
只用深度测试,不用背面剔除也可以解决甜甜圈问题:不管有多少图层,只显示你能看到的,即使两个图层重叠了,背面的颜色已经从深度缓冲区里丢弃了
2.深度测试并不是万能的
深度测试的风险:Z-fighting(Z冲突、闪烁)问题
由于深度缓冲区的精度是有限的,在深度相差非常小的情况下,可能会出现判断错误(深度测试结果不可预测)的情况,就会出现本应该显示在后面,结果显示到前面去了的情况
3.解决Z-fighting问题:
在两个图层之间加一个微妙的间隔。手动修改深度值的方法并不可取,OpenGL为我们提供了一个解决方案:多边形偏移
启用方式,glEnable(GL_Polygon_OFFSET_FILL),需要两个参数
Offset = (m * factor) + (r * units),好吧,这个公式并不需要记,factor和units一般都设置为-1,-1,就可以满足效果
如果想从根源上避免:
a.不要让两个物体靠的太近;
b.近裁剪平面设置的离观察者远一些
c.使用更高精度位数的深度缓冲区(所以现代设备很少出现Z-fighting问题)
4.颜色混合
固定着色器/可编程着色器->使用开关的方式->颜色混合(单纯的两个图层重叠的时候混合)
可编程着色器里的片元着色器,如果需要图片的原始颜色上添加一层薄薄的绿色,需要进行颜色混合方程式的计算(套用公式)
默认情况下,混合方程式如下:
Cf = (Cs * S) + (Cd * D)
其中Cf是最终计算产生的颜色,Cs是源颜色,Cd是目标颜色,S和D分别是源和目标混合因子
原文:https://www.cnblogs.com/hadyt/p/13281597.html