空(白色)帧缓冲区 - 阴影映射

问题描述:

请参阅编辑因为问题的第一部分已解决。空(白色)帧缓冲区 - 阴影映射

我想用我自己的框架从http://learnopengl.com/#!Advanced-Lighting/Shadows/Shadow-Mapping复制阴影映射演示,但有趣的是我没有得到任何阴影。第一个重要的问题是我的深度图不正确。我已经调试并且双重检查了每一行,但没有成功。也许另一双眼睛会有更多的成功。

见(左上,第5行 - 图像完全是白色): enter image description here

我会写第二渲染过程,因为它似乎是第一个不工作。顺便说,对象为中心在0,0,被用于第一渲染过程0以下代码:

/// 1. render target is the depth map 
glViewport(0, 0, SHADOW_MAP_WIDTH_u32, SHADOW_MAP_HEIGHT_u32); 
m_frameBufferObject.bind(); // set the depth map as render target 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
/// place the camera where the light is positioned and render the scene 
math::Matrix4D l_lightViewMatrix = math::Matrix4D::lookAt(m_light_p->getPosition(), math::Vector3D(0, 0, 0), math::Vector3D(0, 1, 0)); 
const math::Matrix4D& l_orthographicLightMatrix_r = m_light_p->getShadowInformation().getProjectionMatrix(); 
math::Matrix4D lightSpaceMatrix = l_orthographicLightMatrix_r * l_lightViewMatrix; 

m_depthMapShader_p->bind(); 
m_depthMapShader_p->setUniformMat4("lightSpaceMatrix", lightSpaceMatrix); 

renderNodes(); 

m_depthMapShader_p->printShaderInfoLog(); 
m_depthMapShader_p->unbind(); 
m_frameBufferObject.unbind(); 

我已经测试该视图矩阵和投影矩阵生成提供完全相同的结果如GLM(opengl的数学库)。然而,我的正交矩阵被定义为:

left = -10.0f 
right = 10.0f 
bottom = -10.0f 
top = 10.0f 
near = -1.0f 
far = 7.5f 

帧缓冲区对象的初始化和纹理如下:

// - Create depth texture    
glGenTextures(1, &m_shadowTextureBuffer_u32); 
glBindTexture(GL_TEXTURE_2D, m_shadowTextureBuffer_u32); 

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_MAP_WIDTH_u32, SHADOW_MAP_HEIGHT_u32, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

m_frameBufferObject.bind(); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowTextureBuffer_u32, 0); 
glDrawBuffer(GL_NONE); 
glReadBuffer(GL_NONE); 

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
{ 
    fprintf(stderr, "Error on building shadow framebuffer\n"); 
    exit(EXIT_FAILURE); 
} 
m_frameBufferObject.unbind(); 

片段和顶点着色器看起来像的下方。

#version 430 
// Fragment shader for rendering the depth values to a texture. 

out vec4 gl_FragColor; 

void main() 
{ 
    gl_FragColor = vec4 (gl_FragCoord.z); 
} 



#version 430 

// Vertex shader for rendering the depth values to a texture. 

in layout (location = 0) vec3 position; 
in layout (location = 1) vec4 color; 
in layout (location = 2) vec3 normal; 
in layout (location = 3) vec2 uv; 
in layout (location = 4) vec3 tangent; 
in layout (location = 5) int materialId; 

uniform mat4 pr_matrix; 
uniform mat4 vw_matrix; 
uniform mat4 ml_matrix; 
uniform mat4 lightSpaceMatrix; 

void main() 
{ 
    gl_Position = lightSpaceMatrix * ml_matrix * vec4(position, 1.0); 
} 

编辑:

睡觉后,我发现了一个小错误在我的渲染和着色器绘制一个“好”深度图。 enter image description here 但是,看起来像纹理映射(深度比较)是在同一个坐标系中。

但第二个渲染步骤仍然不正确:

的顶点和第二渲染过程的片段着色器看起来像

#version 430 

in layout (location = 0) vec3 position; 
in layout (location = 1) vec4 color; 
in layout (location = 2) vec3 normal; 
in layout (location = 3) vec2 uv; 
in layout (location = 4) vec3 tangent; 
in layout (location = 5) int materialId; 

uniform mat4 pr_matrix = mat4(1.0); 
uniform mat4 vw_matrix = mat4(1.0); 
uniform mat4 ml_matrix = mat4(1.0); 
uniform mat4 lightSpaceMatrix = mat4(1.0); 

out VS_OUT 
{ 
    vec4 color; 
    vec2 texture_coordinates; 
    vec3 normal; 
    vec3 tangent; 
    vec3 binormal; 
    vec3 worldPos; 
    vec4 shadowProj; 
    flat int materialIdOut; 
} vs_out; 

void main() 
{ 
    vs_out.color = color; 
    vs_out.texture_coordinates = uv; 

    mat3 normalMatrix = transpose (inverse (mat3 (ml_matrix))); 
    vs_out.normal = normalize (normalMatrix * normalize (normal)); 
    vs_out.tangent = normalize (normalMatrix * normalize (tangent)); 
    vs_out.binormal = normalize (normalMatrix * normalize (cross (normal , tangent))); 
    vs_out.worldPos = (ml_matrix * vec4 (position, 1)).xyz; 
    vs_out.materialIdOut = materialId; 
    vs_out.shadowProj = (lightSpaceMatrix * ml_matrix * vec4 (position, 1.0)); 

    gl_Position = (pr_matrix * vw_matrix * ml_matrix) * vec4 (position, 1.0); 
} 

#version 430 

#define MAX_NUM_TEXTURES 5 
#define MAX_NUM_MATERIALS 12 

struct SMaterial 
{ 
    vec3 m_ambient_v3; 
    vec3 m_diffuse_v3; 
    vec3 m_specular_v3;  
    float m_shininess_f32; 
    int m_textureIds[MAX_NUM_TEXTURES]; 
}; 

in VS_OUT 
{ 
    vec4 color; 
    vec2 texture_coordinates; 
    vec3 normal; 
    vec3 tangent; 
    vec3 binormal; 
    vec3 worldPos; 
    vec4 shadowProj; 
    flat int materialIdOut; 
} fs_in; 

uniform vec3 cameraPos; 
uniform mat4 ml_matrix; 
uniform mat4 vw_matrix; 
uniform sampler2D texSlots[32]; 

uniform SMaterial material[MAX_NUM_MATERIALS]; 
uniform SLight light; 

out vec4 gl_FragColor; 

float shadowCalculation(vec4 fragPosLightSpace) 
{ 
    // perform perspective divide 
    vec3 projCoords = fragPosLightSpace.xyz/fragPosLightSpace.w; 
    // Transform to [0,1] range 
    projCoords = projCoords * vec3(0.5) + vec3(0.5); 
    // Get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) 
    float closestDepth = texture(texSlots[31], projCoords.xy).r; 
    // Get depth of current fragment from light's perspective 
    float currentDepth = projCoords.z; 
    // Check whether current frag pos is in shadow 
    float shadow = currentDepth > closestDepth ? 1.0 : 0.0; 

    return shadow; 
} 

void main() 
{ 
    if ((fs_in.materialIdOut >= 0) && (fs_in.materialIdOut < MAX_NUM_MATERIALS)) 
    { 
     int ambientTextureId = material[fs_in.materialIdOut].m_textureIds[0]; 
     int diffuseTextureId = material[fs_in.materialIdOut].m_textureIds[1]; 
     int specularTextureId = material[fs_in.materialIdOut].m_textureIds[2]; 
     int alphaTextureId = material[fs_in.materialIdOut].m_textureIds[3]; 
     int bumpTextureId = material[fs_in.materialIdOut].m_textureIds[4]; 

     vec3 diffTexColor = vec3(0.6,0.6,0.6); 
     if ((diffuseTextureId >= 0) && (32 > diffuseTextureId)) 
     { 
      diffTexColor = texture (texSlots[diffuseTextureId], fs_in.texture_coordinates).rgb; 
     } 

     // Calculate shadow 
     float shadow = 1.0 - shadowCalculation(fs_in.shadowProj);  
     gl_FragColor = vec4(diffTexColor, 1.0) * vec4(shadow, shadow, shadow, 1.0); 
    } 
    else 
    { 
     gl_FragColor = vec4(fs_in.normal,1.0); 
    } 
} 

在我体验一张深度图几乎总是全白的,因为离灯光超过1的距离已经使得t帽子像素白色。如果你的整个场景超过1个单位,那么整个地图都是白色的。

要渲染地图,就像它们在教程中显示的一样,您需要将场景变得非常小或在深度图上执行操作。我总是喜欢通过将深度值除以相机的zFar距离来检查我的地图。尝试找到可以看到对比的最佳值。

+1

默认深度范围是[0.0,1.0]。深度缓冲区中的任何内容都不会超过1.我所得到的印象是您正在讨论的是存储实际的空间z而不是深度。 –