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 2 of 2

Thread: Shadow mapping with moving object

  1. #1
    Newbie Newbie
    Join Date
    May 2013
    Posts
    1

    Shadow mapping with moving object

    Hi community,

    I'm trying to implement shadow mapping in a small project. The scenario is as follow:

    I have an object which is moving on a ground. My camera is above and behind this object which leads to a bird's eye perspective. Now i want the object to throw a real-time shadow on the ground-surface.

    I created a FBO which should render my shadowmap, call it shadowMapFBO. When i try to render to my shadowMapFBO I have to move my camera to the light's position. For that I'm trying to use a glm::lookAt matrix (see below).
    After that I do my rendering and active my screen FBO (FBO 0). During my debugging I tried many other "boxing configuration" for the depthProjectionMatrix, but I could't fix it.
    Note: As you can see I'm using something like point light, but since actually my object is just moving in 1 direction (minus z-axis) I didn't implement a shadow cubemap.

    renderShadowMap.cc
    Code :
    void renderShadowMap ( void ) {
            // First render pass
            shadowMapFBO->bind();
            shadowMapFBO->clearDepthBuffer();      //glClear(GL_DEPTH_BUFFER_BIT);
     
            glViewport( 0, 0, shadowMapResolution.x, shadowMapResolution.y );
     
            createShadowMapShader->use();
            glm::vec3 position = glm::vec3(objectPosition);
            glm::vec3 lightPosition = glm::vec4(0, 5, 0);
     
            glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,100);
            glm::mat4 depthViewMatrix = glm::lookAt( glm::vec3(lightPosition) , objectPosition , glm::vec3(0,1,0) );
            glm::mat4 depthModelMatrix = glm::mat4(1.0);
            glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;
     
            glm::mat4 scaleBiasMatrix(
                        0.5, 0.0, 0.0, 0.0,
                        0.0, 0.5, 0.0, 0.0,
                        0.0, 0.0, 0.5, 0.0,
                        0.5, 0.5, 0.5, 1.0
                        );
            shadowMatrix = scaleBiasMatrix * depthMVP;
     
     
            shadowShader->setUniform( "depthMVP", depthMVP );
            shadowShader->setUniform( "shadowMatrix", shadowMatrix );
     
            [ ... render objects ... ]
    }

    Vertex shader for creating the shadow map
    Code :
    #version 330 core
    // Input
    in vec3 aPosition;
     
    // Matrices
    uniform mat4 depthMVP;
     
    void main(){
        gl_Position =  depthMVP * vec4( aPosition, 1.0 );
    }

    Fragment shader for creating the shadow map
    Code :
    #version 330 core
     
    // Output data
    out float depthValues;
     
    void main(){
        // Not really needed, OpenGL does it anyway
        depthValues = gl_FragCoord.z;
    }


    After that i hand over the shadow map to the shaders. Now here is how I'm trying to use the shadow map in the fragment shader:


    Vertex shader when using the shadow map
    Code :
    #version 330
    // Matrices
    uniform mat4 uModelMatrix;
    uniform mat4 shadowMatrix;
    uniform mat4 uMVPMatrix;
     
    in vec3 aPosition;
     
    out vec4 objPos;
    out vec4 shadowCoord;
     
    void main()
    {
        gl_Position  = uMVPMatrix * vec4(aPosition, 1.0);
        objPos       = uModelMatrix * vec4(aPosition, 1.0);
        shadowCoord  = shadowMatrix * vec4(aPosition, 1.0);
    }


    Fragment shader when using the shadow map
    Code :
    #version 330
     
    // Light Data
    uniform vec4 uLightPos[6];
    uniform vec4 uLightAmb[6];
    uniform vec4 uLightDif[6];
    uniform vec4 uLightSpec[6];
     
    // Informations
    uniform int shaderLevel;
    uniform float portalRadius;
    uniform vec3 uEyePos;
    uniform vec3 portalPosition;
     
    // Samplers
    uniform sampler2D shadowMapTexture;
    //uniform sampler2DShadow shadowMapTexture;
     
    in vec4 objPos;
    in vec4 shadowCoord;
     
    out vec4 oColor;
     
    vec3 shadowMapping(){
     
        float attenuation   = computeAttenuation(objPos, (uLightPos[0]), 1.0, 0.0, 0.0);
        vec3 ambientLight   = computeAmbience(uLightAmb[0]);
     
        vec3 fNormal        = computeNormals(true);
        vec3 fLightD        = computeLightDirection();
     
        vec3 diffuseLight   = computeDiffuseLight(fNormal, fLightD);
        vec3 specularLight  = computeSpecularLight(fNormal, fLightD);
     
        float bias = 0.005;
        float visibility = 1.0;
     
        //visibility = textureProj(shadowMapTexture, shadowCoord);
     
        /*
        if ( textureProj( shadowMapTexture, shadowCoord.xy ).z  <  shadowCoord.z-bias) {  // < (shadowCoord.z-bias)/shadowCoord.w
            visibility = 0.5;
        }
        float visibility = texture( shadowMapTexture, shadowCoord.xy ).z;
        visibility = texture( shadowMapTexture, vec3(shadowCoord.xy, (shadowCoord.z)/shadowCoord.w) );
        //*/
     
        if ( texture( shadowMapTexture, shadowCoord.xy ).z  <  shadowCoord.z){
            visibility = 0.5;
        }
     
        return ((ambientLight + visibility*(diffuseLight + specularLight)) * attenuation);
    }
     
    void main(){
            oColor = vec4(shadowMapping(), 1.0);
    }

    Actually I'm completely lost on the debugging. I tried to visualize the shadow map using 2 triangles, but it does not work as expected (I commented the texture compare mode and func out). The code for that lookis like this:
    Code :
                //Initialisation
            // The quad's FBO. Used only for visualizing the shadowmap.
            glGenVertexArrays(1, &quad_VertexArrayID);
            glBindVertexArray(quad_VertexArrayID);
     
            static const GLfloat g_quad_vertex_buffer_data[] = {
                -1.0f, -1.0f, 0.0f,
                 1.0f, -1.0f, 0.0f,
                -1.0f,  1.0f, 0.0f,
                -1.0f,  1.0f, 0.0f,
                 1.0f, -1.0f, 0.0f,
                 1.0f,  1.0f, 0.0f,
            };
     
            glGenBuffers(1, &quad_vertexbuffer);
            glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
            glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);
    Code :
                //Rendering pass
                glEnableVertexAttribArray(12);
     
                glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
                glVertexAttribPointer(
                    12,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                    3,                  // size
                    GL_FLOAT,           // type
                    GL_FALSE,           // normalized?
                    0,                  // stride
                    (void*)0            // array buffer offset
                );
     
                // Draw the triangle !
                // You have to disable GL_COMPARE_R_TO_TEXTURE above in order to see anything !
                glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles
                glDisableVertexAttribArray(12);
    Code :
    //Vertex shader
    #version 330 core
     
    // Input
    in vec3 aPosition;
     
    uniform mat4 uModelMatrix;
     
    // Output
    out vec2 uv;
     
    void main(){
            gl_Position =  vec4(aPosition , 1.0);
            uv = ( aPosition.xy + vec2(1.0 , 1.0) ) / 2.0;
    }
     
     
    //Fragment shader
    #version 330 core
     
    // Ouput
    out vec4 oColor;
     
    uniform sampler2D shadowMapTexture;
     
    in vec2 uv;
     
    void main(){
        oColor = texture2D(shadowMapTexture, uv);
        //oColor = vec4(1.0,0,0,1.0);
    }



    For the sake of completeness: I created my FBO as follow :
    Code :
        //Create unset depth texture from where we render shadow depth into FBO
        glGenTextures(1, &shadowMapTexture);
        glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
     
        //Alloc storage for texture data -> later filled with depth values
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadowMapResolution.x, shadowMapResolution.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
     
        //Choose filtering mode
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     
        //Choose wrapping mode
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     
        //Choose depth comparison mode in order to leverage shadow textures
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
     
        //Create FBO and RBO for depth rendering
        glGenFramebuffers(1, &shadowMapFBO);
     
        glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO);
     
        //Attach depth texture to it
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowMapTexture, 0);
     
        //Disable color rendering <- no colors to attach
        glDrawBuffer(GL_NONE);


    HOPEFULLY there is someone who can help us with our problem and tell us what we did wrong!

    Thank you in anticipation!

    Sincerely M2h

  2. #2
    Intern Newbie
    Join Date
    Mar 2013
    Posts
    34
    As i can see, your problem is really simple!

    You have to uniform your depth mvp before every single object rendering pass, because the right position of the rendered object
    is in the model matrix. So you must calculate the right mvp before rendering the object to get the right mvo matrix.

    Code :
    Matrix mode MODELVIEW
    Push matrix
    Translate and Rotate... (And do simple matrix calculations...)
     
    Calculate the new MVP matrix                                  //Very important!
    Uniform the mvp matrix as depthMVP in your case       //Very important!
     
    Render the object
     
    Pop matrix

    I used the same tutorial for shadow mapping as you and had exactly the same problem ^^


    -- Daniel

Posting Permissions

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