本文正在参加「金石方案」
什么是深度测验?
前面咱们在讲解屏幕坐标的时分,运用的是3D坐标,包含:x,y,z三个轴,其中x和y表明屏幕的x和y坐标,z坐标是当时片段Fragment离屏幕的间隔,由于咱们平时运用的都是右手坐标系:则z值越大,片段越接近屏幕,z轴越小,片段离屏幕的间隔就越远,而这儿的远和近在OpenGL的概念里边便是深度的意思。
这儿需求留意的一点便是,深度范围是在[0,1]之间的,深度值越大,则说明当时片段离屏幕间隔越远,而此刻z轴的值就越小。
深度测验是指在片段着色器运行之后在屏幕空间中履行的操作:意在对当时片段的深度值和深度缓冲区的值进行比较,然后决议是否丢掉的进程。
什么是深度缓冲区?
深度缓冲就像颜色缓冲区一样用来存储每个片段的信息,只是其是用来存储当时片段的深度信息,深度能够运用16,24,32位为精度,大多数系统选择折中的24位。
当敞开深度缓冲之后,OpenGL会主动测验当时片段的深度值,然后根据对应的战略来决议片段的丢掉。
怎么完成深度测验?
要启用深度测验,咱们需求用GL_DEPTH_TEST
选项来翻开它:
glEnable(GL_DEPTH_TEST);
一旦启用深度测验,假如片段经过深度测验,OpenGL主动在深度缓冲区存储片段的 z 值,假如深度测验失败,那么相应地丢掉该片段。假如启用深度测验,那么在每个渲染之前还应运用GL_DEPTH_BUFFER_BIT
铲除深度缓冲区,不然深度缓冲区将保存上一次进行深度测验时所写的深度值
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
当然在某些特殊情况下,咱们在敞开深度测验之后,需求丢掉片段,但是又不去更新缓冲区,可运用函数glDepthMask设置为GL_FALSE禁用深度缓冲区的写入。
glDepthMask(GL_FALSE);
上面只是敞开深度测验的几个办法,默许情况下敞开深度测验后,在深度测验进程中,会主动丢掉深度值越小的片段。那可不能够自己定义深度测验的战略呢?
咱们能够经过调用glDepthFunc
来设置比较运算符 (或叫做深度函数(depth function)):
glDepthFunc(GL_LESS);
该函数接受在下表中列出的几个比较运算符:
运算符 | 描述 |
---|---|
GL_ALWAYS | 永久经过测验 |
GL_NEVER | 永久不经过测验 |
GL_LESS | 在片段深度值小于缓冲区的深度时经过测验 |
GL_EQUAL | 在片段深度值等于缓冲区的深度时经过测验 |
GL_LEQUAL | 在片段深度值小于等于缓冲区的深度时经过测验 |
GL_GREATER | 在片段深度值大于缓冲区的深度时经过测验 |
GL_NOTEQUAL | 在片段深度值不等于缓冲区的深度时经过测验 |
GL_GEQUAL | 在片段深度值大于等于缓冲区的深度时经过测验 |
默许情况下运用GL_LESS
,这将丢掉深度值高于或等于当时深度缓冲区的值的片段。
下面咱们来比较下,不同深度测验战略下的图像比较:
-
默许情况下:GL_LESS
-
GL_ALWAYS
-
GL_NEVER
能够看到:
在GL_NEVER形式下:显现的是黑屏,这是因为每次都不经过,所有片段都会被丢掉。
在GL_LESS的形式下:3D作用更加真实。
在GL_ALWAYS:每次都经过测验,后面的片段会掩盖之前的片段。
深度抵触现象
深度测验中,深度抵触现象需求值得留意。深度抵触(Z-fighting)是指两个平面(或三角形)相互平行且接近的过于紧密,模板缓冲区不具有足够的精度确认哪一个平面靠前,导致这两个平面的内容不断交替显现,看上去像平面内容抢夺顶靠前的方位。
防止深度抵触的办法:
- 不要让物体之间靠得过近,避免它们的三角形面片发生重叠;
- 把近平面设置得远一些(越接近近平面的方位精度越高);
- 献身一些功能,运用更高精度的深度值。