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.