Проблемы с использованием карты теней при отложенном рендеринге Opengl 3.3

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

Вот мой расчет матрицы светового пространства

mat4x4 lightViewMatrix;

vec3 sun_pos = {SUN_OFFSET  * the_sun->direction[0],
                SUN_OFFSET  * the_sun->direction[1],
                SUN_OFFSET  * the_sun->direction[2]};

mat4x4_look_at(lightViewMatrix,sun_pos,player->pos,up);

mat4x4_mul(lightSpaceMatrix,lightProjMatrix,lightViewMatrix);

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

the_sun-> direction - это нормализованный вектор, поэтому я умножаю его на константу, чтобы получить позицию.

player-> pos - положение камеры в мировом пространстве.

матрица проекции света рассчитывается следующим образом:

 mat4x4_ortho(lightProjMatrix,-SHADOW_FAR,SHADOW_FAR,-SHADOW_FAR,SHADOW_FAR,NEAR,SHADOW_FAR);

Вершинный шейдер тени:

uniform mat4 light_space_matrix;

 void main()
 {
     gl_Position = light_space_matrix * transfMatrix * vec4(position, 1.0f); 
 }

Шейдер фрагмента тени:

out float fragDepth;
void main()
{
    fragDepth = gl_FragCoord.z;
}

Я использую отложенный рендеринг, поэтому все мои мировые позиции находятся в буфере g_positions

Мой расчет тени в отложенном фрагментном шейдере:

float get_shadow_fac(vec4 light_space_pos)
{
    vec3 shadow_coords = light_space_pos.xyz / light_space_pos.w;
    shadow_coords      = shadow_coords * 0.5 + 0.5;

    float closest_depth = texture(shadow_map, shadow_coords.xy).r;
    float current_depth = shadow_coords.z;

    float shadow_fac = 1.0;

    if(closest_depth < current_depth)
       shadow_fac   = 0.5;

    return shadow_fac;
 }

Я вызываю функцию так:

get_shadow_fac(light_space_matrix * vec4(position,1.0));

Где позиция - это значение, которое я получил от выборки буфера g_position

Вот моя текстура глубины (я знаю, что она будет давать тени низкого качества, но пока я просто хочу, чтобы она работала):

извините из-за сжатия, черные пятна - это деревья ... https://i.stack.imgur.com/T43aK.jpg

РЕДАКТИРОВАТЬ: Присоединение текстуры глубины:

glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT24,fbo->width,fbo->height,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fbo->depthTexture, 0);

person Gicla    schedule 27.12.2017    source источник


Ответы (1)


Я выяснил, в чем проблема, моя текстура буферов g_positions имеет внутренний формат GL_RGBA8 и слишком мала, чтобы удерживать позиции в мировом пространстве.

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,fbo->width,fbo->height,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);

поэтому, когда я перешел на

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32F,fbo->width,fbo->height,0,GL_RGB,GL_FLOAT,NULL);

появились тени: D

person Gicla    schedule 06.01.2018
comment
Хранение постиций мирового пространства в буфере - это огромная трата пропускной способности памяти. Все, что вам нужно, это пространство окна z (буфер глубины, который вы все равно используете), вы можете легко спроецировать обратно в мировое пространство. - person derhass; 06.01.2018
comment
Ха, я что-то читал об этом, пока искал, как решить проблему, но никогда не думал об этом. Спасибо, что упомянули об этом, я реализую это как можно скорее. - person Gicla; 06.01.2018