Hi All,
I am trying to implement SSAO as described here but it is not working as shown below:

The scene is just two planes and I'm hoping to get shadowing in the corner of them. I am unsure if the view space normals are correct, the output is not what I was expecting, here are the shaders generating the Position and Normal inputs.
//Vertex Shader to generate Position & Normal in viewspace.
#version 440
layout(location = 0)in vec4 vert;
layout(location = 1)in vec4 normal;
out vec3 positionFrg;
out vec3 normalFrg;
uniform mat4 projectionMtx;
uniform mat4 viewMtx;
uniform mat4 modelMtx;
void main()
{
positionFrg = (viewMtx * vec4(vert.xyz,1)).xyz;
normalFrg = (viewMtx * vec4(normal.xyz,0)).xyz;
gl_Position = projectionMtx * viewMtx * modelMtx * vert;
}
//Fragment Shader:
#version 440
in vec3 positionFrg;
in vec3 normalFrg;
void main()
{
gl_FragData[0] = vec4(positionFrg, 0.0f);
gl_FragData[1] = vec4(normalize(normalFrg), 0.0f);
}
I don't think I've done anything wrong above, unless I'm missing something obvious.
Below is the SSAO shader code, it is pretty much the same as in the article, adjusted to compile in GLSL and a few changed variable names.
//Vertex Shader
#version 440
layout(location = 0)in vec4 vert;
layout(location = 1)in vec4 texCoord;
out vec2 texCoordFrg;
void main()
{
texCoordFrg = texCoord.xy;
gl_Position = vert;
}
//Fragment Shader:
#version 440
uniform sampler2D posInput;
uniform sampler2D nmlInput;
uniform sampler2D rndInput;
float random_size = 64.0f;
float g_sample_rad = 0.5f;
float g_intensity = 3.0f;
float g_scale = 1.0f;
float g_bias = 0.5f;
vec2 g_screen_size = vec2(800.0f, 600.0f);
in vec2 texCoordFrg;
out vec3 frgCol;
vec3 getPosition(vec2 uv)
{
return texture2D(posInput,uv).xyz;
}
vec3 getNormal(vec2 uv)
{
return(normalize(texture2D(nmlInput, uv).xyz * 2.0f - 1.0f));
}
vec2 getRandom(vec2 uv)
{
vec2 coords = vec2(g_screen_size.x * uv.x, g_screen_size.y * uv.y);
return(normalize(texture2D(rndInput, coords / random_size).xy * 2.0f - 1.0f));
}
float doAmbientOcclusion(vec2 tcoord, vec2 uv, vec3 p, vec3 cnorm)
{
vec3 diff = getPosition(tcoord + uv) - p;
const vec3 v = normalize(diff);
const float d = length(diff)*g_scale;
return(max(0.0,dot(cnorm,v)-g_bias)*(1.0/(1.0+d))*g_intensity);
}
void main()
{
float o = 1.0f;
vec2 vec[4];
vec[0] = vec2(1.0f,0);
vec[1] = vec2(-1.0f,0);
vec[2] = vec2(0,1.0f);
vec[3] = vec2(0,-1.0f);
vec3 p = getPosition(texCoordFrg.xy);
vec3 n = getNormal(texCoordFrg.xy);
vec2 rand = getRandom(texCoordFrg.xy);
float ao = 0.0f;
float rad = g_sample_rad / p.z;
//**SSAO Calculation**//
int iterations = 4;
for (int j = 0; j < iterations; ++j)
{
vec2 coord1 = reflect(vec[j],rand)*rad;
vec2 coord2 = vec2( coord1.x * 0.707 - coord1.y * 0.707, coord1.x * 0.707 + coord1.y * 0.707 );
ao += doAmbientOcclusion( texCoordFrg.xy, coord1 * 0.25, p, n);
ao += doAmbientOcclusion( texCoordFrg.xy, coord2 * 0.5, p, n);
ao += doAmbientOcclusion( texCoordFrg.xy, coord1 * 0.75, p, n);
ao += doAmbientOcclusion( texCoordFrg.xy, coord2, p, n);
}
ao/= float(iterations*4.0);
//**END**//
//Do stuff here with your occlusion value âaoâ: modulate ambient lighting, write it to a buffer for later //use, etc.
frgCol = vec3(ao,ao,ao);
//frgCol = vec3(rand,0.0f);
}
I suspect I am missing some important difference between GLSL and the original article that I am not taking into account, however I don't know what it is.
Can anyone spot the problem or point me in the right direction? I've been making no progress for good half a day and any help would be greatly appreciated.