为阴影贴图计算的纹理坐标不正确

时间:2014-03-17 17:16:10

标签: c++ opengl opengl-4 shadow-mapping

我在获取正确的纹理坐标以获取阴影贴图时遇到问题。查看我的代码,问题似乎来自不正确的矩阵。这是我做阴影的渲染过程的片段着色器:

in vec2 st;

uniform sampler2D colorTexture;
uniform sampler2D normalTexture;
uniform sampler2D depthTexture;
uniform sampler2D shadowmapTexture;

uniform mat4 invProj;
uniform mat4 lightProj;

uniform vec3 lightPosition;

out vec3 color;

void main () {
    vec3 clipSpaceCoords;
    clipSpaceCoords.xy = st.xy * 2.0 - 1.0;
    clipSpaceCoords.z = texture(depthTexture, st).x * 2.0 - 1.0;
    vec4 position = invProj * vec4(clipSpaceCoords,1.0);
    position.xyz /= position.w;
    //At this point, position.xyz seems to be what it should be, the world space coordinates of the pixel. I know this because it works for lighting calculations.

    vec4 lightSpace = lightProj * vec4(position.xyz,1.0);
    //This line above is where I think things go wrong.
    lightSpace.xyz /= lightSpace.w;
    lightSpace.xyz = lightSpace.xyz * 0.5 + 0.5;
    float lightDepth = texture(shadowmapTexture, lightSpace.xy).x;
    //Right here lightDepth seems to be incorrect. The only explanation I can think of for this is if there is a problem in the above calculations leading to lightSpace.xy.

    float shadowFactor = 1.0;
    if(lightSpace.z > lightDepth+0.0005) {
         shadowFactor = 0.2;
    }
    color = vec3(lightDepth);
}

我已从此着色器(照明等)中删除了与阴影无关的所有代码。这是我用来渲染最终传递的代码:

glCullFace(GL_BACK);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

postShader->UseShader();
postShader->SetUniform1I("colorTexture", 0);
postShader->SetUniform1I("normalTexture", 1);
postShader->SetUniform1I("depthTexture", 2);
postShader->SetUniform1I("shadowmapTexture", 3);
//glm::vec3 cp = camera->GetPosition();
postShader->SetUniform4FV("invProj", glm::inverse(camera->GetCombinedProjectionView()));
postShader->SetUniform4FV("lightProj", lights[0].camera->GetCombinedProjectionView());
//Again, if I had to guess, these two lines above would be part of the problem.
postShader->SetUniform3F("lightPosition", lights[0].x, lights[0].y, lights[0].z);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, frameBuffer->GetColor());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, frameBuffer->GetNormals());
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, frameBuffer->GetDepth());
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, lights[0].shadowmap->GetDepth());

this->BindPPQuad();
glDrawArrays(GL_TRIANGLES, 0, 6);

如果它与我的问题有关,这就是我如何为深度和阴影贴图生成深度帧缓冲附件:

void FrameBuffer::Init(int textureWidth, int textureHeight) {
    glGenFramebuffers(1, &fbo);
    glGenTextures(1, &depth);

    glBindTexture(GL_TEXTURE_2D, depth);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, textureWidth, textureHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

我的数学或代码中的问题在哪里,我该怎么做才能解决它?

1 个答案:

答案 0 :(得分:0)

经过一些实验,我发现我的问题不在于我的矩阵,而是在我的钳制中。当我使用GL_CLAMP或GL_CLAMP_TO_EDGE时,我似乎得到了奇怪的值,但是当我使用GL_CLAMP_TO_BORDER时,我得到几乎正确的值。还有更多的问题,但它们似乎并没有像我想的那样与矩阵相关。