More SSAO tweaks
Sun, 24 Aug 2014 16:56:13 +0100
I had to come back to the Ambient Occlusion. I tried rotating the camera, and the depth difference created a too thick shadow. Also, I didn't like the self-shadowing of the floor. I decided to clear the planet's depth to 0, so self-shadowing problem disappeared, but the from the character now looks even thicker,

Removing the blur, and just using the shrink buffer looks a bit better. The shrinking itself acts as a convolution, so there are still some lines, but of course thinner. They are also visibly aliased, due to the reduced size of the buffer (it's the same size as before, but of course the Gaussian filter and bilinear interpolation helped disguise it),

However, the details inside the objects are gone as well. So what I decided to do is applying a kind of anisotropic filter on the depth. The bigger the difference between adjacent pixels, the smaller the sigma of the Gaussian. In one extreme, we'll have no filter at all (so the result will look like just using the unfiltered shrink buffer), and in the other extreme we have a normal averaging operator. This is the result,

We still have aliased lines around the character, but I don't mind a bit of a toonish look. The important thing is that objects have now some AO, and they look rooted to the floor. Here's the code of the Blur shader. Notice that the alpha channel is blurred normally because I have the projected shadow from the sun there.

    mediump vec4 a_1 = texture2D(texAlbedo, vfTexCoord.xy + vUVTransform.xy);
    mediump vec4 a0 = texture2D(texAlbedo, vfTexCoord.xy);
    mediump vec4 a1 = texture2D(texAlbedo, vfTexCoord.xy +;
    // weights
    mediump float dw = 1.0/3.0;
    mediump vec4 w = vec4(0.4, 0.4, 0.2, 0.2);
    mediump float z0 = dw*(a0.x + a0.y + a0.z);
    mediump float zDiff_1 = abs(dw*(a_1.x + a_1.y + a_1.z)-z0);
    mediump float zDiff1 = abs(dw*(a1.x + a1.y + a1.z)-z0);
    mediump float zDiff = 1.0 - 8.0 * (zDiff_1 + zDiff1);
    // the more different, the less blur
    w.x *= clamp(zDiff, 0.0, 1.0) ;
    w.z = 1.0 - 2.0 * w.x;
    gl_FragColor = w.xxxy * a_1 + w.zzzw * a0 + w.xxxy * a1;

This is how the depth buffer would look if blurred normally (as in the first screenshot),

and this is with the anisotropic blur,

This is how the difference (8 * (zDiff_1+zDiff1)) looks like; the brightest the color, the less blur,

After adding the ambient light I think it looks alright,

Without the AO,

Another shot,

Now I need to fix the ambient light!


Previous year

Next year