使用GLSL着色器进行阴影贴图的奇怪行为

时间:2013-09-06 17:39:29

标签: opengl glsl shader vertex-shader shadow-mapping

我已经集成了基本的阴影贴图。但是我注意到渲染的奇怪行为。总而言之,阴影贴图技术需要2个步骤。第一个从光源角度渲染场景(填充深度纹理),第二个从摄像机角度渲染场景。这是第一步的C ++代码:

void Basic::GLSLRenderSystem::renderSceneFromLight(void)
{
    SceneNodeList::iterator nodeListIt = this->m_pScene->getRootNode()->begin();

    for (; nodeListIt != this->m_pScene->getRootNode()->end(); ++nodeListIt)
    {
        EntityList::const_iterator  Ite = (*nodeListIt)->getListEntity().begin();

        (*nodeListIt)->beginTransformations();
        (*nodeListIt)->applyTransformations();

        for (; Ite != (*nodeListIt)->getListEntity().end(); ++Ite)
        {
            //Send matrix

            glm::mat4 modelMatrix = (*nodeListIt)->getModelMatrix();
            glm::mat4 modelViewMatrix = this->m_ViewMatrix * modelMatrix;
            glm::mat4 MVPMatrix = this->m_ProjectionMatrix * modelViewMatrix;

            this->m_pShadowProgram->setUniform("MVP", MVPMatrix);

            (*Ite)->getMesh()->getVertices()->lock();

            //Send vertice positions

            glEnableVertexAttribArray(0);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), OFFSET_BUFFER(0));

            (*Ite)->getMesh()->getVertices()->unlock();

            //Draw primitive

            if ((*Ite)->getMesh()->getVertices()->getCount() == 2)
                glDrawArrays(GL_LINES, 0, (*Ite)->getMesh()->getVertices()->getSize());
            else if ((*Ite)->getMesh()->getVertices()->getCount() == 3)
                glDrawArrays(GL_TRIANGLES, 0, (*Ite)->getMesh()->getVertices()->getSize());
            else if ((*Ite)->getMesh()->getVertices()->getCount() == 4)
                glDrawArrays(GL_QUADS, 0, (*Ite)->getMesh()->getVertices()->getSize());
        }
        (*nodeListIt)->endTransformations();
    }
}

这是输出:

enter image description here

地板上有蚂蚁。但现在如果我删除对应于将顶点发送到程序着色器的部分下面的代码:

void Basic::GLSLRenderSystem::renderSceneFromLight(void)
{
    SceneNodeList::iterator nodeListIt = this->m_pScene->getRootNode()->begin();

    for (; nodeListIt != this->m_pScene->getRootNode()->end(); ++nodeListIt)
    {
        EntityList::const_iterator  Ite = (*nodeListIt)->getListEntity().begin();

        (*nodeListIt)->beginTransformations();
        (*nodeListIt)->applyTransformations();

        for (; Ite != (*nodeListIt)->getListEntity().end(); ++Ite)
        {
            //Send matrix

            glm::mat4 modelMatrix = (*nodeListIt)->getModelMatrix();
            glm::mat4 modelViewMatrix = this->m_ViewMatrix * modelMatrix;
            glm::mat4 MVPMatrix = this->m_ProjectionMatrix * modelViewMatrix;

            this->m_pShadowProgram->setUniform("MVP", MVPMatrix);

            //Draw primitive

            if ((*Ite)->getMesh()->getVertices()->getCount() == 2)
                glDrawArrays(GL_LINES, 0, (*Ite)->getMesh()->getVertices()->getSize());
            else if ((*Ite)->getMesh()->getVertices()->getCount() == 3)
                glDrawArrays(GL_TRIANGLES, 0, (*Ite)->getMesh()->getVertices()->getSize());
            else if ((*Ite)->getMesh()->getVertices()->getCount() == 4)
                glDrawArrays(GL_QUADS, 0, (*Ite)->getMesh()->getVertices()->getSize());
        }
        (*nodeListIt)->endTransformations();
    }
}

我有以下输出(没有acnee):

enter image description here

这是顶点着色器:

#version 400

layout (location = 0) in vec3 VertexPosition;

uniform mat4 MVP;

void main(void)
{
    gl_Position = MVP * vec4(VertexPosition, 1.0f);
}

正如您所见,我在光(视图)位置转换顶点。所以在我的C ++代码中,如果我不发送(在第二种情况下)顶点,我想知道它是如何工作的! (我只是发送光MVP矩阵!)最令人惊奇的是没有更多的acnee!你怎么解释这种行为?我是否像第一种情况一样将顶点发送到着色器(并找到解决方法以擦除地板上的acnee)?

0 个答案:

没有答案