【问题标题】:Shadow mapping does not work correctly using GLSL and OpenGL使用 GLSL 和 OpenGL 阴影映射无法正常工作
【发布时间】:2013-12-27 05:09:21
【问题描述】:

我有一个由 2 个网格(平面、立方体)、一个灯光和一个相机组成的场景。我想使用带有 GLSL 着色器和 OpenGL 的阴影映射技术在我的场景中显示阴影。

这是我得到的结果(为简单起见,我的立方体和我的飞机都是蓝色和颜色):

这是 FBO 和深度纹理初始化:

GLfloat border[] = {1.0f, 1.0f, 1.0f, 1.0f};

    glGenTextures(1, &this->m_TextId);
    glBindTexture(GL_TEXTURE_2D, this->m_TextId);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24,
        this->m_Width, this->m_Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);

    glBindTexture(GL_TEXTURE_2D, 0);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, this->m_TextId, 0);

    glDrawBuffer(GL_NONE);
    glReadBuffer(GL_NONE);

    GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if( result == GL_FRAMEBUFFER_COMPLETE) {
        printf("Framebuffer is complete.\n");
    } else {
        printf("Framebuffer is not complete.\n");
    }

这是我的顶点着色器的内容:

#version 400
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexture;

uniform mat4 MVP;
uniform mat4 ShadowMatrix;

out vec4 ShadowCoords;

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

还有我的片段着色器:

#version 400

in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;
in vec4 ShadowCoords;

layout (location = 0) out vec4 FragColor;

uniform sampler2DShadow ShadowMap;

void main(void)
{
    vec4 ModelColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);

    float shadow = textureProj(ShadowMap, ShadowCoords);

    FragColor = ModelColor * shadow;
}

如您所见,模型上有一些文物,我不知道如何撤回它们。但是阴影似乎是正确的,所以我的着色器中输入的变量也应该是正确的(我认为是这样)。

我在片段着色器中尝试了另一种技术,如下所示:

#version 400

in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;
in vec4 ShadowCoords;

layout (location = 0) out vec4 FragColor;

uniform sampler2D ShadowMap;

void main(void)
{
    vec4 ModelColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);

    vec4 shadowCoordinateWdivide = ShadowCoords / ShadowCoords.w;

    shadowCoordinateWdivide.z += 0.0005;

    float distanceFromLight = texture2D(ShadowMap,shadowCoordinateWdivide.st).z;

    float shadow = 1.0;
    if (ShadowCoords.w > 0.0)
        shadow = (distanceFromLight < shadowCoordinateWdivide.z) ? 0.5 : 1.0 ;

    FragColor = shadow * ModelColor;
}

您会注意到我没有使用 sampler2DShadow,但现在使用的是 sampler2D。但正如您所见,没有显示任何阴影:

有人可以帮助我吗?

【问题讨论】:

    标签: opengl glsl glsles shadow-mapping


    【解决方案1】:

    您的第一张图片可以用浮点问题来解释。当您通过阴影矩阵变换顶点时,您将获得一个点,其与灯光的距离几乎等于灯光深度缓冲区中的深度(因为该点位于几何体上)。对于其中一些点,变换将在几何体前面一点点给出光空间深度,而对于其他点,深度将在几何体后面一点点。因此,其中一半最终会根据某种奇怪的模式被遮挡。

    你想要做的是扰动你的ShadowCoords'Z坐标一点点朝向光线以避免这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      • 2014-12-11
      • 2015-02-04
      • 1970-01-01
      • 1970-01-01
      • 2013-06-30
      • 2014-01-16
      相关资源
      最近更新 更多