首先,再次上一下这个图
深度测试
-
在所有对应颜色值确定以后,最终的对象将会被传到最后一个阶段,我们叫做Alpha测试和混合(Blending)阶段。这个阶段检测片段的对应的深度(和模板(Stencil))值(后面会讲),用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。(混合我们之后再说)
-
OpenGL存储它的所有深度信息于一个Z缓冲(Z-buffer)中,也被称为深度缓冲(Depth Buffer)。GLFW会自动为你生成这样一个缓冲(就像它也有一个颜色缓冲来存储输出图像的颜色)。深度值存储在每个片段里面(作为片段的z值),当片段想要输出它的颜色时,OpenGL会将它的深度值和z缓冲进行比较,如果当前的片段在其它片段之后,它将会被丢弃,否则将会覆盖。这个过程就被称为深度测试(Depth Testing)。
在openGL中我们可以直接使用GLSL内建变量gl_FragCoord.z来直接拿到该片段的深度值
在openGL中,深度测试默认是禁用的,我们可以用以下代码来配置
//开启深度写入
glEnable(GL_DEPTH_TEST);
//配置比较运算符 用来进行片段深度值和深度缓冲的比较
//当片段深度值小于深度缓冲就通过测试
glDepthFunc(GL_LESS);
当我们开启深度测试后,还应注意在渲染迭代清空深度缓冲的值,否则你会仍在使用上一次渲染迭代中写入的深度值
//清空颜色缓冲和深度缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
模板测试
模板测试(Stencil Test)和深度测试一样,它也可能会丢弃片段。接下来,被保留的片段会进入深度测试,它可能会丢弃更多的片段。模板测试是根据又一个缓冲来进行的,它叫做模板缓冲(Stencil Buffer),我们可以在渲染的时候更新它来获得一些很有意思的效果。
首先我们也要开启模板测试
glEnable(GL_STENCIL_TEST);
清除模板缓冲跟上面相似
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
设置位掩码(它会与将要写入缓冲的模板值进行与(AND)运算。默认情况下设置的位掩码所有位都为1(0xFF),不影响输出,但如果我们将它设置为0x00,就是所有写入都不通过,默认写入就是0了)
glStencilMask(0xFF); // 每一位写入模板缓冲时都保持原样
glStencilMask(0x00); // 每一位在写入模板缓冲时都会变成0(禁用写入)
和深度测试一样,我们对模板缓冲应该通过还是失败,以及它应该如何影响模板缓冲,也是有一定控制的。一共有两个函数能够用来配置模板测试:glStencilFunc和glStencilOp
glStencilFunc(GL_EQUAL, 1, 0xFF)
以上会告诉openGL当片段模板值等于1的时候才通过测试
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
以上告诉opengl当片段通过测试时,就把缓冲更新为glStencilFunc函数的ref值