简体   繁体   中英

Incorrect texture coordinate calculated for shadow map

I am having problems getting the correct texture coordinate to sample my shadow map. Looking at my code, the problem appears to be from incorrect matrices. This is the fragment shader for the rendering pass where I do shadows:

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);
}

I have removed all the code irrelevant to shadowing from this shader (Lighting, etc). This is the code I use to render the final pass:

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);

In case it is relevant to my problem, here is how I generate the depth framebuffer attachments for the depth and shadow maps:

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);
}

Where is the problem in my math or my code, and what can I do to fix it?

After some experimentation, I have found that my problem does not lie in my matrices, but in my clamping. It seems that I get strange values when I use GL_CLAMP or GL_CLAMP_TO_EDGE, but I get almost correct values when I use GL_CLAMP_TO_BORDER. There are more problems, but they do not seem to be matrix related as I thought.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM