Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

Edit

I moved vertex positions and normals from world space to view space. Next I rewrote the code:

subroutine (RenderPassType)
void ssao()
{
    vec2 texCoord = CalcTexCoord();
    vec3 camPos = 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 + camPos;
        vec4 offset = vec4(pix, 1.0);
        offset = ProjectionMatrix * 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(camPos.z - sample_depth) < radius ? 1.0 : 0.0;
        occlusion += (-sample_depth <= -pix.z ? 1.0 : 0.0);
    }

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

Now I get the white areas in place of occlusion, but also the ground plane get a lot of occlusion which is incorrect. When I move the camera artifacts also change their position. What is wrong ?

Here are screens: screen1 screen2

share|improve this question
    
I'm sorry, I don't understand your problem. Why do you feel occlusion on the ground plane is incorrect? It looks fairly decent. –  drxzcl Nov 16 '12 at 10:40
1  
The above ssao implementation is based on a normal-oriented hemisphere link, so the ground plane should receive some occlusion only near to the object - especially for a small radius. Here is a screen from the other ssao method link which I implemented link That looks correct. –  Irbis Nov 16 '12 at 16:42
add comment

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.