关于 OpenGL 中的 ssao,有没有人和我有过同样的经历?

Have any guys experienced the same occasion with me about ssao in OpenGL?

大部分着色器代码都遵循 LearnOpenGL 的说明。我可以确保传递到着色器的 g 缓冲区和噪声数据是正确的。好像有点错位,但是我真的想不通为什么会这样。

misplace ssao

#version 450 core
out float OUT_FragColor;

in vec2 TexCoords;

uniform sampler2D g_position;
uniform sampler2D g_normal;
uniform sampler2D noise_texture;

struct CameraInfo
{
    vec4 position;
    mat4 view;
    mat4 projection;
};
layout(std140, binding = 0) uniform Camera
{
    CameraInfo camera;
};


float radius = 0.5;
float bias = 0.025;

uniform int noise_tex_size;

void main()
{
    const vec2 noise_scale = vec2(1280.0/noise_tex_size, 720.0/noise_tex_size); 

    vec3 frag_pos = texture(g_position, TexCoords).xyz;
    vec3 normal = normalize(texture(g_normal, TexCoords).xyz);
    vec3 random_vec = normalize(texture(noise_texture, TexCoords * noise_scale).xyz);   

    vec3 tangent = normalize(random_vec - normal * dot(random_vec, normal));   
    vec3 bitangent = cross(normal, tangent);    
    mat3 TBN = mat3(tangent, bitangent, normal);

    float occlusion = 0.f;

    for(int i = 0; i < sample_array.length(); ++i)
    {
        vec3 sample_pos = TBN * sample_array[i].xyz;
        sample_pos = frag_pos + sample_pos * radius;    
        
        vec4 offset = vec4(sample_pos, 1.0);
        offset = camera.projection * offset; // from view to clip-space
        offset.xyz /= offset.w; // perspective divide ?????
        offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
        float sample_depth = texture(g_position, offset.xy).z;

        float range_check = smoothstep(0.f, 1.f, radius / abs(frag_pos.z - sample_depth));  
        occlusion += (sample_depth >= sample_pos.z + bias ? 1.0 : 0.0) * range_check; //ignore sample points that too near the origin point
    }

    

    occlusion = 1.f - (occlusion / sample_array.length());  
    OUT_FragColor = occlusion;
}

将 g_postion 和 g_normal 转换为模型 space

FragPos = (camera.view * vec4(WorldPos, 1.0)).xyz;
mat4 normal_matrix = camera.view * mat4(transpose(inverse(mat3(model))));   
FragNormal = mat3(normal_matrix) * normal;