ssao implementation

Posted by Irbis on Game Development See other posts from Game Development or by Irbis
Published on 2012-11-12T19:05:26Z Indexed on 2012/11/12 23:15 UTC
Read the original article Hit count: 270

I try to implement a ssao based on this tutorial: link I use a deferred rendering and world coordinates for shading calculations. When saving gbuffer a vertex shader output looks like this:

worldPosition = vec3(ModelMatrix * vec4(inPosition, 1.0));
normal = normalize(normalModelMatrix * inNormal);
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(inPosition, 1.0);

Next for a ssao calculations I render a scene as a full screen quad and I save an occlusion parameter in a texture. (Vertex positions in the world space: link Normals in the world space: link)

SSAO implementation:

subroutine (RenderPassType)
void ssao()
{
     vec2 texCoord = CalcTexCoord();
     vec3 worldPos = texture(texture0, texCoord).xyz;
     vec3 normal = normalize(texture(texture1, texCoord).xyz);
     vec2 noiseScale = vec2(screenSize.x / 4, screenSize.y / 4);
     vec3 rvec = texture(texture2, texCoord * noiseScale).xyz;
     vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
     vec3 bitangent = cross(normal, tangent);
     mat3 tbn = mat3(tangent, bitangent, normal);

     float occlusion = 0.0;
     float radius = 4.0;

     for (int i = 0; i < kernelSize; ++i) 
     {
         vec3 pix = tbn * kernel[i];
         pix = pix * radius + worldPos;
         vec4 offset = vec4(pix, 1.0);
         offset = ProjectionMatrix * ViewMatrix * offset;
         offset.xy /= offset.w;
         offset.xy = offset.xy * 0.5 + 0.5;
         float sample_depth = texture(texture0, offset.xy).z; 
         float range_check = abs(worldPos.z - sample_depth) < radius ? 1.0 : 0.0;
         occlusion += (sample_depth <= pix.z ? 1.0 : 0.0);
     }

     outputColor = vec4(occlusion, occlusion, occlusion, 1);
}

That code gives following results:

  • camera looking towards -z world space: link
  • camera looking towards +z world space: link

I wonder if it is possible to use world coordinates in the above code ? When I move camera I get different results because world space positions don't change. Can I treat worldPos.z as a linear depth ? What should I change to get a correct results ? I except the white areas in place of occlusion, so the ground should has the white areas only near to the object.

© Game Development or respective owner

Related posts about opengl

Related posts about shaders