C++ 阴影贴图产生不正确的结果
我试图在延迟渲染管道中实现阴影映射,但实际上我遇到了一些问题,即生成阴影映射,然后对像素进行阴影处理——我认为应该进行阴影处理的像素根本不存在 我有一个单向光,它是我引擎中的“太阳”。我已经推迟了灯光的渲染设置,到目前为止效果良好。我使用以下代码生成视图矩阵,再次将场景渲染为阴影贴图的仅深度FBO:C++ 阴影贴图产生不正确的结果,c++,opengl,glsl,shadow-mapping,C++,Opengl,Glsl,Shadow Mapping,我试图在延迟渲染管道中实现阴影映射,但实际上我遇到了一些问题,即生成阴影映射,然后对像素进行阴影处理——我认为应该进行阴影处理的像素根本不存在 我有一个单向光,它是我引擎中的“太阳”。我已经推迟了灯光的渲染设置,到目前为止效果良好。我使用以下代码生成视图矩阵,再次将场景渲染为阴影贴图的仅深度FBO: glm::vec3 position = r->getCamera()->getCameraPosition(); // position of level camera glm::ve
glm::vec3 position = r->getCamera()->getCameraPosition(); // position of level camera
glm::vec3 lightDir = this->sun->getDirection(); // sun direction vector
glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20); // ortho projection
glm::mat4 depthViewMatrix = glm::lookAt(position + (lightDir * 20.f / 2.f), -lightDir, glm::vec3(0,1,0));
glm::mat4 lightSpaceMatrix = depthProjectionMatrix * depthViewMatrix;
然而,这并不能真正让我明白我在追求什么。以下是阴影处理后的输出截图,以及在Photoshop中半自动转换为图像的阴影贴图:
渲染输出
阴影贴图
由于平行光是着色器中的唯一灯光,因此阴影贴图的渲染似乎非常接近正确,因为透视/方向大致匹配。然而,我不明白的是,为什么没有一个茶壶会给其他茶壶投下阴影
如果有人指点我可能做错了什么,我将不胜感激。我认为我的问题要么在于光空间矩阵的计算(我不确定如何正确地计算,给定一个移动的摄影机,以便视图中的内容将被更新),要么在于我确定延迟渲染器着色的纹理是否在阴影中。(FWIW,我从深度缓冲区确定世界位置,但我已经证明此计算是正确的。)
谢谢您的帮助。调试阴影问题可能很棘手。让我们从以下几点开始:
如果阴影贴图投影正确,则您知道在深度比较中存在问题。希望这有帮助 调试阴影问题可能很棘手。让我们从以下几点开始:
如果阴影贴图投影正确,则您知道在深度比较中存在问题。希望这有帮助 谢谢-当我为阴影贴图分配深度纹理时,我向OpenGL传递了错误的值,这导致着色器在读取纹理时错误地解释了纹理。奇怪,但它现在可以工作了。谢谢-当我将深度纹理分配给阴影贴图时,我将错误的值传递给了OpenGL,这导致着色器在读取纹理时错误地解释了纹理。很奇怪,但现在可以用了。
// lightSpaceMatrix is the same as above, FragWorldPos is world position of the texekl
vec4 FragPosLightSpace = lightSpaceMatrix * vec4(FragWorldPos, 1.0f);
// multiply non-ambient light values by ShadowCalculation(FragPosLightSpace)
// ... do more stuff ...
float ShadowCalculation(vec4 fragPosLightSpace) {
// perform perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// vec3 projCoords = fragPosLightSpace.xyz;
// Transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5;
// Get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
float closestDepth = texture(gSunShadowMap, projCoords.xy).r;
// Get depth of current fragment from light's perspective
float currentDepth = projCoords.z;
// Check whether current frag pos is in shadow
float bias = 0.005;
float shadow = (currentDepth - bias) > closestDepth ? 1.0 : 0.0;
// Ensure that Z value is no larger than 1
if(projCoords.z > 1.0) {
shadow = 0.0;
}
return shadow;
}
closestDepth = texture(gSunShadowMap, projCoords.xy).r