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 10 of 22

Thread: Omnidirectional Shadow Maps

Hybrid View

  1. #1
    Junior Member Regular Contributor
    Join Date
    Mar 2012
    Posts
    120

    Omnidirectional Shadow Maps

    I am attempting to create omnidirectional point lights that cast shadows using a depth cube map. However, when sampling the cube map, I seem to get a value of 1 in every case (making everything look black).

    Here is how I generate the depth cube map and associated FBO:

    Code :
    glGenTextures(1, &m_cubeMapID);
     
        // Bind as cube map and set default settings
        glBindTexture(GL_TEXTURE_CUBE_MAP, m_cubeMapID);
     
     
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
        //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
     
        // Generate textures for faces
        for(int f = 0; f < 6; f++)
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, 0, GL_DEPTH_COMPONENT, m_resolution, m_resolution, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
     
     
        // Generate mipmaps for the color texture
        //glGenerateMipmap(GL_TEXTURE_2D);
     
     
        GL_ERROR_CHECK();
     
     
        // ------------------------------ FBO ------------------------------
     
     
        glGenFramebuffers(1, &m_fboID);
        glBindFramebuffer(GL_FRAMEBUFFER, m_fboID);
     
     
        // Not using color buffer
        glDrawBuffer(GL_NONE);
        glReadBuffer(GL_NONE);
     
     
        // Attach at least on part of cube map so completeness check succeeds. Attach and detach sides later when rendering
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_cubeMapID, 0);
     
        GL_ERROR_CHECK();
     
     
    #ifdef DEBUG
        if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            std::cerr << "Could not created FBO!" << std::endl;
    #endif
     
     
        // Unbind FBO, revert to main framebuffer
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
     
     
        // Unbind texture
        glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
     
     
        GL_ERROR_CHECK();

    I then render to it like this:

    Code :
    // For each face, render the scene    
        glBindFramebuffer(GL_FRAMEBUFFER, m_fboID);
     
     
        // Set up viewport for the map side
        glViewport(0, 0, m_resolution, m_resolution);
     
     
        // Set projection to 90 degrees
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(90.0f, 1.0f, 0.01f, distance);
        glMatrixMode(GL_MODELVIEW);
     
     
        glColorMask(false, false, false, false);
     
     
        // Side +X
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_cubeMapID, 0);
        glClear(GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        gluLookAt(position.x, position.y, position.z, position.x + 1.0f, position.y, position.z, 0.0f, 1.0f, 0.0f);
        pScene->ExtractFrustum();
        pScene->Render(distance);
     
     
        // Side -X
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, m_cubeMapID, 0);
     
     
        glClear(GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        gluLookAt(position.x, position.y, position.z, position.x - 1.0f, position.y, position.z, 0.0f, 1.0f, 0.0f);
        pScene->ExtractFrustum();
        pScene->Render(distance);
     
     
        // Side +Y
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, m_cubeMapID, 0);
     
     
        glClear(GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        gluLookAt(position.x, position.y, position.z, position.x, position.y + 1.0f, position.z, 0.0f, 1.0f, 0.0f);
        pScene->ExtractFrustum();
        pScene->Render(distance);
     
     
        // Side -Y
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, m_cubeMapID, 0);
     
     
        glClear(GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        gluLookAt(position.x, position.y, position.z, position.x, position.y - 1.0f, position.z, 0.0f, 1.0f, 0.0f);
        pScene->ExtractFrustum();
        pScene->Render(distance);
     
     
        // Side +Z
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, m_cubeMapID, 0);
     
     
        glClear(GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        gluLookAt(position.x, position.y, position.z, position.x, position.y, position.z + 1.0f, 0.0f, 1.0f, 0.0f);
        pScene->ExtractFrustum();
        pScene->Render(distance);
     
     
        // Side -Z
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, m_cubeMapID, 0);
     
     
        glClear(GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        gluLookAt(position.x, position.y, position.z, position.x, position.y, position.z - 1.0f, 0.0f, 1.0f, 0.0f);
        pScene->ExtractFrustum();
        pScene->Render(distance);
     
     
        glColorMask(true, true, true, true);
     
     
        glFlush();
     
     
        // Unbind the FBO
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
     
     
        GL_ERROR_CHECK();

    Rendering to the cube map worked when using color textures, but I am not sure that it is rendering properly when using the textures as depth attachments.

    Here is the shader I use for rendering the shadows:

    Vertex:

    Code :
    uniform vec3 light_position;
     
    // Used for shadow lookup
    varying vec4 shadowDir;
     
     
    void main()
    {
        shadowDir = gl_Vertex * gl_ModelViewMatrix - vec4(light_position, 1.0);
     
     
        gl_Position = ftransform();
     
     
        gl_FrontColor = gl_Color;
    }

    Fragment:

    Code :
    uniform samplerCube shadowMap;
     
    varying vec4 shadowDir;
     
     
    void main()
    {
        float frag_depth = length(shadowDir.xyz);
     
     
        vec3 norm_shadowDir = normalize(shadowDir).xyz;
     
     
        float shadow_map_depth = textureCube(shadowMap, norm_shadowDir).r;
     
     
        float light = 0.0;
     
     
        if(shadow_map_depth > frag_depth + 0.0005)
            light = 1.0;
     
        gl_FragColor = gl_Color;
        gl_FragColor.rgb *= light;
    }

    What am I doing wrong here? Thanks for any help you can offer!

  2. #2
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171
    Are you sure you have set near and far correctly?
    // Set projection to 90 degrees
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.0f, 1.0f, 0.01f, distance);

  3. #3
    Junior Member Regular Contributor
    Join Date
    Mar 2012
    Posts
    120
    I am pretty sure they are right. distance is 2000.0f. It renders fine when I use normal color textures.

  4. #4
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171
    Have you read back the depth buffers/textures to check they contain something valid?

  5. #5
    Junior Member Regular Contributor
    Join Date
    Mar 2012
    Posts
    120
    How would I go about doing that?

  6. #6
    Senior Member OpenGL Pro sqrt[-1]'s Avatar
    Join Date
    Jun 2002
    Location
    Australia
    Posts
    1,007
    Perhaps grab an XML frame with http://code.google.com/p/glintercept/ ?

Posting Permissions

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