Пустой (белый) фреймбуфер — отображение теней

См. EDIT, так как первая часть проблемы решена.

Я пытаюсь воспроизвести демо-карту теней с сайта http://learnopengl.com/#!Advanced-Lighting/Shadows/Shadow-Mapping с моей собственной структурой, но, что интересно, я не получил никаких теней. Первая существенная проблема заключается в том, что моя карта глубины работает некорректно. Я отлаживал и дважды проверял каждую строку без успеха. Может быть, другая пара глаз будет иметь больший успех.

См. (вверху слева, 5-й ряд — изображение полностью белое): введите здесь описание изображения

Напишу о втором проходе рендера, так как первый похоже не работает. Кстати, объекты центрированы по 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);
}

ИЗМЕНИТЬ:

После некоторого сна я обнаружил небольшую ошибку в моем рендерере, и шейдер рисует «хорошую» карту глубины. введите изображение  описание здесь Однако похоже, что наложение текстуры (сравнение глубины) происходит в одной системе координат.

Но второй шаг рендеринга по-прежнему неверен: введите здесь описание изображения

Вершинный и фрагментный шейдер для второго прохода рендеринга выглядят так:

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

person bobby    schedule 09.08.2015    source источник


Ответы (1)


По моему опыту, карта глубины почти всегда полностью белая, потому что расстояние более 1 от источника света уже делает этот пиксель белым. Если вся ваша сцена дальше 1 единицы, то вся карта белая.

Чтобы визуализировать карту так, как показано в туториале, вам нужно, чтобы ваша сцена была очень маленькой, или чтобы выполнить операцию на вашей карте глубины. Я всегда люблю проверять свои карты, разделив их значения глубины на расстояние zFar камеры. Попробуйте найти наилучшее значение, при котором вы можете увидеть контраст.

person Taylee    schedule 09.08.2015
comment
Диапазон глубины по умолчанию — [0,0, 1,0]. Ничто в буфере глубины не будет › 1. У меня сложилось впечатление, что вы говорите о сохранении фактического пространства глаза z, а не о глубине. - person Andon M. Coleman; 09.08.2015