Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Issues with Shadow Mapping in GLSL

  1. #1
    Newbie Newbie
    Join Date
    May 2017
    Posts
    2

    Issues with Shadow Mapping in GLSL

    Howdy all, I've been trying to implement shadow mapping in GLSL for a few days now and I'm tantalisingly close.

    I believe I have an issue transforming world space positions into my light's view space.

    The shadow appears to work perfectly for a quarter of the scene through the world y axis, but the other 270 degrees are borked up.

    If I rotate my point light around the scene, the quadrant oposite my lights works, rotating with it and projecting the correct shadows.

    Here's a video better explaining my problem.

    https://www.youtube.com/watch?v=4VOT...ature=youtu.be

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,124
    You might post some details about how you are building your world-space-to-light-space transform, including how you are determining the bounds of your world-space and light-space frusta.

    That we apparently see shadows "striping" across the scene suggests to me that possibly your shadow frusta doesn't encompass the world-space bounds of your scene, so there we may be seeing texture border behavior. What do you have your GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T on your shadow map set to? GL_CLAMP_TO_EDGE? Just for grins try changing them to REPEAT. This isn't going to fix anything, but does it stop your shadows from "striping" across the scene. Alternatively, what if in the shader you treat shadow map tex coordinates outside of (0..1,0..1) as "no shadow". That should allow you to more easily see where in your scene your shadow map is projecting to, given your world-to-light-space transform. Alternatively, color your scene by the shadow map texcoords, with areas outside the shadow map bounds being black or grey.

  3. #3
    Newbie Newbie
    Join Date
    May 2017
    Posts
    2
    Quote Originally Posted by Dark Photon View Post
    Alternatively, what if in the shader you treat shadow map tex coordinates outside of (0..1,0..1) as "no shadow". That should allow you to more easily see where in your scene your shadow map is projecting to, given your world-to-light-space transform. Alternatively, color your scene by the shadow map texcoords, with areas outside the shadow map bounds being black or grey.
    -Could you elaborate on what you mean by the shadow map tex coords?


    My instinct was to clamp/repeat the clamping, but it doesn't appear to be making any visible difference whatsoever -

    Code :
     
     glm::mat4 lightProjection, lightView;
     glm::mat4 lightSpaceMatrix;
     GLfloat near_plane = 1.0;
     GLfloat far_plane = 8.5f;
     lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
     
     lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(0.0, 1.0, 0.0));
     
     lightSpaceMatrix = lightProjection * lightView; //light mvp

    This is my set up for constructing the world to lightspace matrix.

    Shadow_Frag
    Code :
     
    #version 330 core
    out vec4 FragColor;
     
    in vec3 FragPos;
    in vec3 Normal;
    in vec2 TexCoords;
     
    uniform mat4 MV;
     
    uniform mat4 lightSpaceMatrix;
     
    uniform sampler2D colourTex;
    uniform sampler2D shadowTex;
    uniform sampler2D positionTex;
     
    uniform vec3 lightPos;
    uniform vec3 viewPos;
     
    float ShadowCalculation()
    {
     
        //view space position
        vec4 wpos = vec4(texture(positionTex, TexCoords).rgb,1.0);
     
        FragColor = wpos;//just for visualizing the "light space coords"
     
        //NDC-space (not a problem with ortho projections)
        vec3 projCoords = wpos.xyz / wpos.w;
     
        // Transform to [0,1] range
        projCoords = projCoords * .5 + .5;
     
        // Get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
        float closestDepth = texture(shadowTex, projCoords.xy).r;
     
        //       return vec3(texture(shadowTex, closestDepth).r);
        // Get depth of current fragment from light's perspective
        float currentDepth = projCoords.z;
     
     
        // Check whether current frag pos is in shadow
        vec3 lightDir = normalize(lightPos - FragPos);
     
        float bias = max(0.05 * (1.0 - dot(Normal, lightDir)), 0.005);
        //float bias = .01;
     
        float shadow = 0.0;
        vec2 texelSize = 1.0 / textureSize(shadowTex, 0);
        for(int x = -1; x <= 1; ++x)
        {
            for(int y = -1; y <= 1; ++y)
            {
                float pcfDepth = texture(shadowTex, projCoords.xy + vec2(x, y) * texelSize).r;
                shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
            }
        }
        shadow /= 9.0;
     
       // keep the shadow at 0.0 when outside the far_plane region of the light's frustum.
        if(projCoords.z > 1.0)
            shadow = 0.0;
     
        return shadow;
    }
     
    void main()
    {
     
        float shadow = ShadowCalculation();
        FragColor = vec4(texture(colourTex, TexCoords).rgb * (1-(shadow)),1.0);
        //FragColor = lightSpaceMatrix*vec4(1);
    }
    }

    Shadow_Vert
    Code :
    layout (location = 0) in vec3 position;
    layout (location = 1) in vec2 texCoords;
    layout (location = 2) in vec3 normal;
     
     
    out vec3 FragPos;
    out vec3 Normal;
    out vec2 TexCoords;
     
    uniform mat4 P;
    uniform mat4 V;
    uniform mat4 M;
    uniform mat3 N; // This is the inverse transpose of the mv matrix
     
    uniform mat4 MV;
    uniform mat4 MVP;
     
    void main()
    {
        gl_Position = MVP * vec4(position, 1.0);;
     
        Normal = normalize(N * normal);
     
        TexCoords = texCoords;
    }

    and when writing my position to lightspace to my sampler texture I perform the output:

    Code :
        // Compute the position of the vertex
        gl_Position = MVP * vec4(VertexPosition,1.0);

    Appologies for the large code dump.

    I would be trustful of my shader however I'm doing the lightspace transformation on the vertex shader where I grab my positions from instead of the shadow vertex shader - this might be a mistake.

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,124
    Quote Originally Posted by Catch2 View Post
    -Could you elaborate on what you mean by the shadow map tex coords?
    The texture coordinates you use to lookup into the shadow map with. The first occurrance in your fragment shader is: projCoords.xy

    Until you have basic shadow mapping working, I'd comment out all that multi-sampling the shadow map stuff (PCF) you've got going on in your frag shader. Just sample it once, and then display the result of that on-screen. You can get fancy later.

    Also, don't have much time right now, but just scanning your shader I don't see any reasonable logic to transform the input position from WORLD or CAMERA-EYE space to LIGHT-CLIP space to perform the shadow lookup. Unless I'm missing it, you need to add that.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •