openglgraphicsssao

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


Most of the shader codes are follow the instruction of LearnOpenGL. I could make sure that the g-buffer and noise data pass into the shader are correct. It seems like some kind of dislocation, but But I really can't figure out why this happened.

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

Solution

  • transform the g_postion and g_normal into model space

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