Ambient Occlusion : Problem of comprehension of screen space??

Hello there !

I’m sorry for my bad english, but I’m going do the maximum to you can understand a maximum of thing.

So, I begin with the screen space algorithm.
I want to realize a ambient occlusion with screen space.

When I search on the internet, I found only difficult paper (for me it’s difficult, perhaps, one day I can read and understand everything ^_^) or algorithm with linear Depth and spaceView and normalView…

But, for my deferred light, I use a world space coordinate because when I move my camera, if I use, for the normal for example, normal = inverse(transpose(view * model)) * in_Normal, the result is not good (like lights move and normally they are static), therefore, I use normal = model * in_Normal.

So, I try to adapt this tutorial http://blog.evoserv.at/index.php/2012/12/hemispherical-screen-space-ambient-occlusion-ssao-for-deferred-renderers-using-openglglsl/
with my world space coordinate.

But the occlusionmap is not good

[ATTACH=CONFIG]765[/ATTACH]

and

[ATTACH=CONFIG]766[/ATTACH]

Maybe can you explain me these issues, or maybe can you explain to me how can I use normalView in my deferred lighting too.

Now, I post my differents codes for my shaders, and I begin with the most important : AmbientOcclusionShaderFragment.

After, you are going to see other shaders : gBuffer and light for exemple ^^

#version 440 core

layout(std140, binding = 0) readonly buffer DeviceSize
{
    uvec4 size;
};

layout(binding = 0) uniform sampler2D normalMap;
layout(binding = 1) uniform sampler2D positionMap;

const vec2 poisson16[] = vec2[](    // These are the Poisson Disk Samples
                                vec2( -0.94201624,  -0.39906216 ),
                                vec2(  0.94558609,  -0.76890725 ),
                                vec2( -0.094184101, -0.92938870 ),
                                vec2(  0.34495938,   0.29387760 ),
                                vec2( -0.91588581,   0.45771432 ),
                                vec2( -0.81544232,  -0.87912464 ),
                                vec2( -0.38277543,   0.27676845 ),
                                vec2(  0.97484398,   0.75648379 ),
                                vec2(  0.44323325,  -0.97511554 ),
                                vec2(  0.53742981,  -0.47373420 ),
                                vec2( -0.26496911,  -0.41893023 ),
                                vec2(  0.79197514,   0.19090188 ),
                                vec2( -0.24188840,   0.99706507 ),
                                vec2( -0.81409955,   0.91437590 ),
                                vec2(  0.19984126,   0.78641367 ),
                                vec2(  0.14383161,  -0.14100790 )
                               );

out vec4 out_Color;

void main(void)
{
    vec2 texCoord = gl_FragCoord.xy / size.xy;
    vec3 normal = texture(normalMap, texCoord).xyz;
    vec3 position = texture(positionMap, texCoord).xyz;

    float AO = 0.0;

    vec2 filterRadius = vec2(10.0 / float(size.x), 10.0 / float((size.y)));
    float distanceThreshold = 5.0;

    int i;

    for(i = 0; i < 16; ++i)
    {
        vec2 texCoordSample = texCoord + poisson16[i] * filterRadius;

        vec3 samplePos = texture(positionMap, texCoordSample).xyz;
        vec3 sampleDir = normalize(samplePos - position);

        float nDotS = max(dot(normal, sampleDir), 0.0);
        float dist = distance(position, samplePos);

        float a = 1.0 - smoothstep(distanceThreshold, distanceThreshold * 2, dist);

        AO += (a * nDotS);
    }

    out_Color = vec4(AO);
}

VertexShader : Model

#version 440 core
#extension GL_ARB_shader_draw_parameters : enable

struct MVPandM
{
    mat4 MVP;
    mat4 M;
};

layout(std140, binding = 1) readonly buffer MatrixMVPandM
{
    MVPandM mat[];
};

layout(location = 0) in vec4 in_Pos;
layout(location = 1) in vec4 in_Norm;
layout(location = 2) in vec4 in_TexCoord;

out Block
{
    vec4 texCoord;
    vec4 norm;
    vec4 pos;
    flat int drawID;
}Out;

void main(void)
{
    Out.drawID = gl_DrawIDARB; // glMultiDraw...

    Out.texCoord = in_TexCoord;
    Out.norm = mat[gl_InstanceID].M * vec4(in_Norm.xyz, 0.0); /* mat[gl_InstanceID].MV * vec4(in_Norm.xyz, 0.0) don't work*/
    Out.pos = mat[gl_InstanceID].M * vec4(in_Pos.xyz, 1.0);

    gl_Position = mat[gl_InstanceID].MVP * vec4(in_Pos.xyz, 1.0);
}

Fragment Shaders put diffuseTexture, normalize(norm) and pos in three textures.

M is the model matrix(own translation, rotation and scaling)
MVP is the Projection * View * Model matrix.

and lightFragment

#version 440 core

layout(std140, binding = 0) readonly buffer DeviceSize
{
    uvec4 size;
};

struct PointLightStruct
{
    vec4 posRadius;
    vec4 color;
};

layout(std140, binding = 3) readonly buffer PointLight
{
    PointLightStruct pl[];
};

flat in int drawID;

// layout(binding = 0) uniform sampler2D diffuseTex;
layout(binding = 1) uniform sampler2D normalTex;
layout(binding = 2) uniform sampler2D positionTex;

layout(location = 0) out vec3 fragColor;

void main(void)
{
    vec3 normal = texture(normalTex, gl_FragCoord.xy / size.zw).xyz;
    vec3 position = texture(positionTex, gl_FragCoord.xy / size.zw).xyz;

    vec3 vertexToLight = pl[drawID].posRadius.xyz - position;
    float attenuation = max(0.0, 1.0 - length(vertexToLight) / pl[drawID].posRadius.w);

    vertexToLight = normalize(vertexToLight);
    float lambertCoeff = max(0.0, dot(normal, vertexToLight));

    fragColor = lambertCoeff * attenuation * pl[drawID].color.rgb;
}

thank you very much :slight_smile:

And sorry again for my english…