前言OpenGL存储它的所有深度信息于一个Z缓冲(Z-buffer)中,也被称为深度缓冲(Depth Buffer)。GLFW会自动为你生成这样一个缓冲(就像它也有一个颜色缓冲来存储输出图像的颜色)。深度值存储在每个片段里面(作为片段的z值),当片段想要输出它的颜色时,OpenGL会将它的深度值和z缓冲进行比较,如果当前的片段在其它片段之后,它将会被丢弃,否则将会覆盖。这个过程称为深度测试(Depth Testing),它是由OpenGL自动完成的。
上图结果是已开启深度测试的状态。
下图未开启Z轴缓存,会出现重叠区域被清理
//glEnable(GL_DEPTH_TEST);把这段直接注释掉,直接关闭
关闭深度测试后,出现大量覆盖现象。
通过上图观察可以看到,多个平台直接被覆盖。
深度测试函数GL_ALWAYS 一直通过深度测试,不丢弃
GL_NEVER 从不通过深度测试,全部丢弃
GL_LESS 如果小于缓冲中的深度值就通过,大于等于的就直接丢弃
GL_EQUAL 如果等于缓冲中的深度值就通过,不等于就丢弃
GL_LEQUAL 如果小于等于......
GL_GREATER 如果大于......
GL_NOTEQUAL 如果不等于.....
GL_GEQUAL 如果大于等于.....
默认情况下,都是使用 GL_LESS
下图使用 GL_ALWAYS
glDepthFunc(GL_ALWAYS); //设定GL_ALWAYS
下图使用 GL_LESS
深度冲突
两个图形在设定上,我们让它们处在同一个平面,如平行于XY轴的平面
结果出现下图现象,这个现象叫做深度冲突,两个图形在每一帧的争夺 “最前方”设置偏移
// 立方体glBindVertexArray(cubeVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
//设置一个偏移量glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, 0.0f);
// 地板绘制glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4(1.0f));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
//关闭GL_POLYGON_OFFSET_FILLglDisable(GL_POLYGON_OFFSET_FILL);
上面代码的关键就在于
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, 0.0f);
结果如下高精度深度缓冲
更高精度的计算可以减少深度冲突,但也会牺牲掉部分性能。