-1

First time trying to implement shadow map using openGL ang glsl shader language. I think the first pass where I render to a texture is correct but when I compare the depth values it seems to shadow everything.

https://www.dropbox.com/s/myxenx9y41yz2fc/Screenshot%202014-12-09%2012.18.53.png?dl=0

My perspective projection matrix looks like this:

FOV = 90
Aspect = According to the programs window size. (I also tried to put different values here)
Near = 2;
Far= 10000;

Function to initialize the frame buffer

void OpenGLWin::initDepthMap()
{
    //Framebuffer
    m_glFunctions->glGenFramebuffers(1, &m_frameBuffer);
    m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);

    //////////////////////////////////////////////////////////////////////////
    //Texture to render scene to
    m_glFunctions->glGenTextures(1, &m_renderToTexture);
    //Bind created texture to make it current
    m_glFunctions->glBindTexture(GL_TEXTURE_2D, m_renderToTexture);

    //Creates an empty texture of specified size.
    //m_glFunctions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 768, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    m_glFunctions->glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

    m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);

    m_glFunctions->glDrawBuffer(GL_NONE);
    m_glFunctions->glReadBuffer(GL_NONE);

    // Always check that our framebuffer is ok
    if (m_glFunctions->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
        qDebug() << "FrameBuffer not OK";
        return;
    }

    m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, 0);   
}

Draw function for each mesh. Model matrix is passed as argument from a Transform class draw function

void Mesh::draw(const Matrix4x4& projection, const Matrix4x4& view, const Matrix4x4& model)
{
    //Shadow map pass 1
    if (m_shadowMapFirstpass){
        //Pass 1 Shaders
        m_glFunctions->glUseProgram(m_depthRTTShaderProgram);

        //Light view matrix 
        m_depthMVP = projection*view*model;
        //Get the location of the uniform name mvp
        GLuint depthMVPLocation = m_glFunctions->glGetUniformLocation(m_depthRTTShaderProgram, "depthMVP");
        m_glFunctions->glUniformMatrix4fv(depthMVPLocation, 1, GL_TRUE, &m_depthMVP[0][0]);

        m_shadowMapFirstpass = false;
    }
    //Shadow map pass 2
    else if(m_shadowMapFirstpass == false){
        //Pass 2 Shader
        m_glFunctions->glUseProgram(m_shaderProgram);
        //Gets the model matrix which is then multiplied with view and projection to form the mvp matrix
        Matrix4x4 mvp = projection * view * model;

        //Get the location of the uniform name mvp
        GLuint mvpLocation = m_glFunctions->glGetUniformLocation(m_shaderProgram, "mvp");

        //Send the mvp matrix to the vertex shader
        m_glFunctions->glUniformMatrix4fv(mvpLocation, 1, GL_TRUE, &mvp[0][0]);

        Matrix4x4 depthBiasMVP = m_depthMVP;// biasMatrix*m_depthMVP;
        GLuint depthBiasMVPLocation = m_glFunctions->glGetUniformLocation(m_shaderProgram, "depthBiasMVP");

        m_glFunctions->glUniformMatrix4fv(depthBiasMVPLocation, 1, GL_TRUE, &depthBiasMVP[0][0]);

        m_shadowMapFirstpass = true;
    }

    //Bind this mesh VAO
    m_glFunctions->glBindVertexArray(m_vao);
    //Draw the triangles using the index buffer(EBO)
    glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, 0);

    //Unbind the VAO
    m_glFunctions->glBindVertexArray(0);

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    //Calls the childrens' update
    if (!m_children.empty())
    {
        for (int i = 0; i < m_children.size(); i++)
        {
            if (m_children[i] != NULL)
            {
                m_children[i]->draw(frustumCheck, projection, view, bvScaleFactor, model);
            }
        }
    }
}

My render loop

void OpenGLWin::paintGL()
{
//      m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);
        m_glFunctions->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_frameBuffer);

        glViewport(0, 0, 1024, 1024);
        // Clear the buffer with the current clearing color
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //Light View Matrix
        Matrix4x4 lightView;
        lightView.lookAt(Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(0, 1, 0));

        //Draw scene to Texture
        m_root->draw(m_projection, lightView);


        ///////////////////////////////////////////////////////////////////
        //Draw to real scene
        m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, 0);    
//      m_glFunctions->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

        // Clear the screen
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //Bind Pass 2 shader
        m_glFunctions->glUseProgram(m_shadowMapShaderProgram->getShaderProgramID());

        GLuint shadowMapLocation = m_glFunctions->glGetUniformLocation(m_shadowMapShaderProgram->getShaderProgramID(), "shadowMap");

        //Shadow Texture
        m_glFunctions->glActiveTexture(GL_TEXTURE0);
        m_glFunctions->glBindTexture(GL_TEXTURE_2D, m_renderToTexture);
        m_glFunctions->glUniform1i(shadowMapLocation, 0);

        //Updates matrices and view matrix for player camera
        m_root->update(m_view);

        //Render scene to main frame buffer
        m_root->draw(m_projection, m_view);

}

Pass 1 Vertex Shader

#version 330 core
//Passthrough vertex shader

uniform mat4 depthMVP;

//Vertex received from the program
layout(location = 0) in vec3 vertexPosition_modelspace;

void main(void)
{
    //Output position of vertex in clip space
    gl_Position = depthMVP * vec4(vertexPosition_modelspace, 1);
}

Pass 1 Fragment Shader

#version 330 core
//Render to texture

// Ouput data
layout(location = 0) out float depthValue;

void main(void)
{
    depthValue = gl_FragCoord.z;
}

Pass 2 Vertex Shader

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;

out vec4 ShadowCoord;

// Values that stay constant for the whole mesh.
uniform mat4 mvp;
uniform mat4 depthBiasMVP;


void main(){

    // Output position of the vertex, in clip space : MVP * position
    gl_Position =  mvp * vec4(vertexPosition_modelspace,1);

    ShadowCoord = depthBiasMVP * vec4(vertexPosition_modelspace,1);

}

Pass 2 Fragment Shader

#version 330 core

in vec4 ShadowCoord;

// Ouput data
layout(location = 0) out vec3 color;

// Values that stay constant for the whole mesh.
uniform sampler2D shadowMap;


void main(){

    float visibility=1.0;


    vec3 ProjCoords = ShadowCoord.xyz / ShadowCoord.w;
    vec2 UVCoords;
    UVCoords.x = 0.5 * ProjCoords.x + 0.5;
    UVCoords.y = 0.5 * ProjCoords.y + 0.5;
    float z = 0.5 * ProjCoords.z + 0.5;
    float Depth = texture(shadowMap, UVCoords).z;//or x
    if (Depth < (z + 0.00001)){
        visibility = 0.1;
    }


    color = visibility*vec3(1,0,0);

}

1 Answers1

0

Disable texture comparison for one thing. That's only valid when used with sampler2DShadow and you clearly are not using that in your code because your texture coordinates are 2D.

This means replacing the following code:

m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);

With this instead:

m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);

Likewise, using GL_LINEAR filtering on a non-sampler2DShadow texture is a bad idea. That is going to average the 4 nearest depth values and give you a single depth back. But that's not the proper way to anti-alias shadows; you actually want to average the result of 4 depth tests instead of doing a single test on the average of 4 depths.

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • Changed to GL_NONE. Does my "ShadowCoord" in the shader look allright? I think the problem lies there when I'm trying to transform it to the depth texture's space. – FlowerPower1990 Dec 09 '14 at 20:13
  • Found the issue. Texture comparison enabled was one of the issues along with how i sampled the shadow map Changed .z to .x. I believe i need .x because depth value is only one component and not a vector. `float Depth = texture(shadowMap, UVCoords).x;` – FlowerPower1990 Dec 10 '14 at 09:39
  • To be honest, in core GL 3.3, even though there's only 1 component to a depth texture it is supposed to effectively return this: `(r,r,r,1)`. That would mean that `texture(shadowMap, UVCoords).x` should give the same value as `texture(shadowMap, UVCoords).z`. There is a depth texture mode that affects this behavior in *compatibility* profiles, but in core it should always behave the way I described. – Andon M. Coleman Dec 10 '14 at 17:11