使用 GL_LESS 但没有使用 GL_GREATER 或 GL_ALWAYS 的阴影贴图为空白?

Posted

技术标签:

【中文标题】使用 GL_LESS 但没有使用 GL_GREATER 或 GL_ALWAYS 的阴影贴图为空白?【英文标题】:Shadowmap blank with GL_LESS but not with GL_GREATER or GL_ALWAYS? 【发布时间】:2020-08-13 15:58:27 【问题描述】:

我已经在我的自定义 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);

【问题讨论】:

您是否在绑定到 fbo 后清除了 depth_texture。 glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); 将其设置为 1.0 而不是 0.0 非常重要 解决了我的问题——我在绑定到 fbo 之前清除了 depth_texture,而不是之后。 【参考方案1】:

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

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

glClearDepth(1.0); 
glClear(GL_DEPTH_BUFFER_BIT);

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

【讨论】:

以上是关于使用 GL_LESS 但没有使用 GL_GREATER 或 GL_ALWAYS 的阴影贴图为空白?的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL:Radeon 驱动程序似乎与深度测试混为一谈

在 OpenGL 中,(如何)我可以在两个深度缓冲区之间进行深度测试?

AVKit 与 Swift 一起使用,但没有创建文件。为啥?

Selenium 尽管没有使用或调用 WebElement,但没有此类元素异常 [重复]

使用 Facebook PHP SDK 4,但没有存储会话

尽管使用了工作区,但 Azure Pipeline '没有这样的模块'