2017-12-27 326 views
0

我正在尝试为我正在处理的项目实现简单的阴影贴图。我可以将深度纹理渲染到屏幕上,所以我知道它在那里,问题是当我使用阴影纹理坐标对阴影贴图进行采样时,看起来好像坐标已关闭。使用带延迟渲染的阴影贴图的问题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->方向是一个归一化的向量,所以我乘以一个常量来获得位置。

播放器 - > 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); 

回答

0

我发现了什么问题,我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

+0

在gbuffer存储世界空间postition是内存带宽的巨大浪费。您所需要的只是窗口空间z(深度缓冲区,您仍然可以使用),您可以轻松地将其重新投影到世界空间。 – derhass

+0

我在研究如何解决问题的同时阅读了一些关于它的内容,但从来没有想过。感谢你提到它,我将尽快实施它。 – Gicla