首页 > 解决方案 > 使用 GL_LESS 但没有使用 GL_GREATER 或 GL_ALWAYS 的阴影贴图为空白?

问题描述

几天来,我一直在我的自定义 OpenGL 引擎中研究阴影映射。在阅读了一些指南之后,我尝试尽可能地坚持基本方法:为阴影贴图本身创建一个带有 GL_TEXTURE_2D 的阴影贴图帧缓冲区,使用帧缓冲区和基本着色器从灯光的角度进行渲染,然后正常渲染我的主要着色器。

但是,我遇到了一些奇怪的事情:当我使用默认深度函数进行渲染或手动将其设置为 GL_LESS 时,阴影贴图似乎只填充了 0。(我通过在我的着色器中将 shadowmmap 值与 0 进行比较来进行测试,所以我相信它们实际上是 0 而不仅仅是非常小的数字。)

当我将深度函数设置为 GL_GREATER 或 GL_ALWAYS 时,阴影贴图包含非 0 值,尽管我无法判断这些非 0 值是否是我想要实现的值。

作为参考,这是我正在使用的一些代码:

要设置我的光相关矩阵:

glm::vec3 lightPos(100, 200, 0);
glm::mat4 lightProjection, lightView;
glm::mat4 lightSpaceMatrix;
float near_plane = 0.1f, far_plane = 1000.0f;
lightProjection = glm::ortho(-1000.0f, 1000.0f, -1000.0f, 1000.0f, near_plane, far_plane);
lightView = glm::lookAt(lightPos, glm::vec3(0.0f, 32.0f, 0.0f), glm::vec3(0, 1, 0));
lightSpaceMatrix = lightProjection * lightView;
shader.setMat4("lightSpaceMatrix", lightSpaceMatrix);

测试阴影贴图的代码——我渲染的对象使用 GL_GREATER 深度函数显示为红色,但使用 GL_LESS 没有红色:

vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
// transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5;
...
float closestDepth = texture(shadowMap, projCoords.xy).r; 
if (closestDepth > 0) {
    FragColor = vec4(1, 0, 0, 1);
}

标签: c++openglglslglm-mathshadow-mapping

解决方案


我的猜测是您忘记清除深度缓冲区。

您需要在每个帧的开头用最大深度填充它

glClearDepth(1.0); 
glClear(GL_DEPTH_BUFFER_BIT);

将其设置为 1.0 而不是 0.0 非常重要,否则不会绘制任何内容


推荐阅读