OpenGL学习15——深度测试

2021-07-03  本文已影响0人  蓬篙人

深度测试(Depth Testing)

glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_FALSE);

1. 深度测试函数

glDepthFunc(GL_LESS);
函数 描述
GL_ALWAYS 深度测试总是通过
GL_NEVER 深度测试从不通过
GL_LESS 如果片元深度值小于存储的深度值则通过(默认
GL_EQUAL 如果片元深度值等于存储的深度值则通过
GL_LEQUAL 如果片元深度值小于或等于存储的深度值则通过
GL_GREATER 如果片元深度值大于存储的深度值则通过
GL_NOTEQUAL 如果片元深度值不等于存储的深度值则通过
GL_GEQUAL 如果片元深度值大于或等于存储的深度值则通过

下面我们创建一个场景来展示不同深度测试的效果。场景是一个平面上有两个立方体,平面和立方体分别设置不同的纹理。

float planeVertices[] = {
    // positions          // texture 
     5.0f, -0.5f,  5.0f,  2.0f, 0.0f,
    -5.0f, -0.5f,  5.0f,  0.0f, 0.0f,
    -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,

     5.0f, -0.5f,  5.0f,  2.0f, 0.0f,
    -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,
     5.0f, -0.5f, -5.0f,  2.0f, 2.0f
};
// cubes
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);
// floor
glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4(1.0f));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);

2. 深度值精度

3. 可视化深度缓冲区

FragColor = vec4(vec3(gl_FragCoord.z), 1.0);
float ndc = depth * 2.0 - 1.0;
float linearDepth = (2.0 * near * far) / (far + near - ndc * (far - near));
float near = 0.1;
float far = 100.0;

float LinearizeDepth(float depth)
{
    float z = depth * 2.0 - 1.0;
    return (2.0 * near * far) / (far + near - z * (far - near));
}

void main()
{    
    // 因为near和far之间深度值大部分大于1,会显示为白色,因此这里除以far,映射到[0, 1]
    float depth = LinearizeDepth(gl_FragCoord.z) / far;
    FragColor = vec4(vec3(depth), 1.0);
}

4. 深度冲突(Z-fighting)

上一篇下一篇

猜你喜欢

热点阅读