阴影贴图:整个网格处于阴影中,根据深度图,它应该在的地方没有光线



第一次尝试使用openGL ang glsl着色器语言实现阴影贴图。我认为我渲染到纹理的第一遍是正确的,但是当我比较深度值时,它似乎会掩盖一切。

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

我的透视投影矩阵如下所示:

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

初始化帧缓冲区的函数

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

每个网格的绘制功能。模型矩阵作为参数从转换类绘制函数传递

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

我的渲染循环

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

传递 1 个顶点着色器

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

传递 1 个片段着色器

#version 330 core
//Render to texture
// Ouput data
layout(location = 0) out float depthValue;
void main(void)
{
    depthValue = gl_FragCoord.z;
}

通道 2 顶点着色器

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

通道 2 片段着色器

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

禁用纹理比较。这仅在与sampler2DShadow一起使用时才有效,并且您显然没有在代码中使用它,因为您的纹理坐标是 2D 的。

这意味着替换以下代码:

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->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);

同样,对非sampler2DShadow纹理使用GL_LINEAR过滤也是一个坏主意。这将平均 4 个最近的深度值并返回一个深度。但这不是消除锯齿阴影的正确方法;您实际上希望平均 4 个深度测试的结果,而不是对 4 个深度的平均结果进行一次测试。

相关内容

  • 没有找到相关文章

最新更新