SSAO 和阴影贴图 | 阴影不适用于 SSAO

查理·惠特

我们引擎中的 SSAO 似乎正在工作,但是我无法让 SSAO 与阴影贴图一起工作。这是我目前在应用阴影时遇到的错误的屏幕截图....

应用了阴影
应用了阴影

而且,根据相机视图和相机位置,有时会出现随机阴影......

随机阴影取决于相机视图和位置
随机阴影取决于相机视图和位置

这是 gbuffer 顶点着色器..

#version 330 core

layout (location = 0) in vec3 positions;
layout (location = 1) in vec2 texCoords;
layout (location = 2) in vec3 normals;

out vec3 FragPos;
out vec3 ShadowFragPos;
out vec2 TexCoords;
out vec3 Normal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main()
{
    vec4 viewPos = view * model * vec4(positions, 1.0);
    FragPos = viewPos.xyz; 
    TexCoords = texCoords;

    mat3 normalMatrix = transpose(inverse(mat3(view * model)));
    Normal = normalMatrix * normals;

    gl_Position = proj * viewPos;
}

这是照明着色器..

#version 330 core

out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedoSpec;
uniform sampler2D gShadowmap;
uniform sampler2D gSsao;

uniform vec3 cameraPos;

uniform mat4 lightSpaceMatrix;

vec3 Normal;
vec3 FragPos;

uniform vec3 lightPos;

float calculate_shadows(vec4 light_space_pos)
{
    // perform perspective divide
    vec3 projCoords = light_space_pos.xyz / light_space_pos.w;

    // transform to [0,1] range
    projCoords = projCoords * 0.5 + 0.5;

    // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
    float closestDepth = texture(gShadowmap, projCoords.xy).r; 

    // get depth of current fragment from light's perspective
    float currentDepth = projCoords.z;

    // check whether current frag pos is in shadow
    vec3 lightDir = normalize(vec3(2.0f, 4.0f, 1.0f) - FragPos);
    float bias = max(0.05 * (1.0 - dot(Normal, lightDir)), 0.005);
    float shadow = 0.0;

    vec2 texelSize = 1.0 / textureSize(gShadowmap, 0);

    // 8x8 kernel PCF
    float x;
    float y;

    for (y = -3.5; y <= 3.5 ; y += 1.0)
    {
        for (x = -3.5; x <= 3.5 ; x += 1.0)
        {
            float pcfDepth = texture(gShadowmap, projCoords.xy + vec2(x, y) * texelSize).r; 
            shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;        
        }
    }

    shadow /= 64.0; 

    return shadow;
}

void main(void)
{
    FragPos = texture(gPosition, TexCoords).rgb;
    Normal = texture(gNormal, TexCoords).rgb;
    vec3 Diffuse = texture(gAlbedoSpec, TexCoords).rgb;
    float Specular = texture(gAlbedoSpec, TexCoords).a; 
    float AmbientOcclusion = texture(gSsao, TexCoords).r;

    vec3 lighting = vec3(0.3 * Diffuse * AmbientOcclusion);
    vec3 viewDir = normalize(-FragPos);
    vec3 lightDir = normalize(lightPos - FragPos);
    vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * vec3(1.0f, 0.5f, 0.3f);

    vec3 halfwayDir = normalize(lightDir + viewDir);
    float spec = pow(max(dot(Normal, halfwayDir), 0.0), 8.0);
    vec3 specular = vec3(1.0f, 0.5f, 0.3f) * spec * Specular;

    float shadow = calculate_shadows(lightSpaceMatrix * vec4(FragPos, 1.0));    

    lighting += ((1.0 - shadow) * (diffuse + specular)); 

    FragColor = vec4(lighting, 1.0f);
}

纹理在光通道中绑定如下..

// bind the positions texture and store in the first texture slot/unit
        glActiveTexture(GL_TEXTURE0); // texture unit 0
        glBindTexture(GL_TEXTURE_2D, gbuffer.gPositions); // geometry positions

        // bind the normals texture and store in the second texture slot/unit
        glActiveTexture(GL_TEXTURE1); // texture unit 1
        glBindTexture(GL_TEXTURE_2D, gbuffer.gNormals); // geometry normals

        // bind the albedo & specular texture and store in the third texture slot/unit
        glActiveTexture(GL_TEXTURE2); // texture unit 2
        glBindTexture(GL_TEXTURE_2D, gbuffer.gAlbedoSpec); // geometry albedospec
                                                           // bind the albedo & specular texture and store in the third texture slot/unit

        glActiveTexture(GL_TEXTURE3); // texture                         unit 3
        glBindTexture(GL_TEXTURE_2D, gbuffer.gShadowmap); // geometry albedospec

        glActiveTexture(GL_TEXTURE4); // texture unit 2
        glBindTexture(GL_TEXTURE_2D, gbuffer.ssaoColorBuffer); // geometry albedospec

最后,这里是lightSpaceMatrix的计算。。

light_projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 7.5f);
        light_view = glm::lookAt(glm::vec3(0.0f, 4.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
        light_space_matrix = light_projection * light_view;

任何想法为什么会发生这种情况?如何让阴影与 SSAO 一起使用?

任何帮助深表感谢。

疯兔76

FragPos 是相机视图空间位置。

light_space_pos,输入参数 tocalculate_shadows必须是从光源看到的剪辑空间坐标。

这意味着当你做

float shadow = calculate_shadows(lightSpaceMatrix * vec4(FragPos, 1.0)); 

lightSpaceMatrix 必须是从相机视图空间到光源剪辑空间的转换。

为此,您必须进行 3 次转换:

  1. 相机视图空间到世界空间。这可以通过逆view矩阵来完成。

  2. 世界空间到光空间,这是由light_view.

  3. 灯光视图空间到灯光剪辑空间,是由light_projection.

所以设置light_space_matrix = light_projection * light_view;是不够的,它必须是

light_space_matrix = light_projection * light_view * glm::inverse(view);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用OpenSceneGraph进行SSAO,优化和管道

来自分类Dev

使用OpenGL和GLSL的SSAO算法的奇怪性能行为

来自分类Dev

Flexbox:元素阴影不适用于order属性

来自分类Dev

引导阴影不适用于网格系统

来自分类Dev

Flexbox:元素阴影不适用于order属性

来自分类Dev

框阴影不适用于该部分

来自分类Dev

阴影不适用于指定面色的色块吗?

来自分类Dev

使SSAO着色器与SkinnedMesh一起使用

来自分类Dev

为什么SSAO仅在某些角度/距离下工作?

来自分类Dev

SSAO随相机角度发生巨大变化

来自分类Dev

阴影贴图和深度值混淆

来自分类Dev

阴影贴图的位置和分辨率

来自分类Dev

阴影贴图和深度值混淆

来自分类Dev

换行前单词阴影文本不适用于空格

来自分类Dev

使用SSAO着色器在场景上产生奇怪的正方形

来自分类Dev

阴影贴图工件

来自分类Dev

OpenGL中的阴影贴图

来自分类Dev

GLSL 1.20阴影贴图,使阴影变形

来自分类Dev

OpenGL阴影贴图-阴影位置错误

来自分类Dev

适用于Android的xml中的梯形阴影

来自分类Dev

jQuery if和语句不适用于and

来自分类Dev

将2D和3D阴影贴图发送到着色器

来自分类Dev

OpenGL阴影贴图几乎可以正常工作

来自分类Dev

OpenGL Variance阴影贴图倒置衰减

来自分类Dev

级联阴影贴图不太正确

来自分类Dev

具有延迟渲染的阴影贴图

来自分类Dev

巴比伦JS中的阴影贴图

来自分类Dev

级联阴影贴图无法正常工作

来自分类Dev

如何使用phong阴影实现凹凸贴图