Mel.. I've downloaded terrabytes of stuff on things like "Horizon Based AO", but havent had time to read it.
The AO I tried to implement here is a heavily changed version from a while ago for Blender by a guy
called Martins Upitus (who was inspired by work from a guy called Arkano). All very old stuff, but tops in the searches..
So..
The first thing I did was to change the depth that was used from 8 bit to 24 bit (could go 32 bit as Irrlicht buffers support Alpha too).
I added a Unpacker in the GPU code itself.. see "GL_0420_FRAG_PP_SSAO_INTERNAL_DEPTH.glsl"
You'll see I have a "Non Linear Inter Buffer Rendering system going" (experimental, but a good tool)
Now, to one of these Buffers I rendered the Geometry using a Geo Shader that produces Packed 24 Bit Depth..
See "GL_0410_F_GEO_DEPTH_RGB_A_CLIPPED.glsl"..
It uses a Texture Image with alpha so that objects could have Alpha Ref clip maps too. (The RGB wasted, but Ill fit it in somewhere sometime)
(packers got interesting when I saw yours dealing with Multi-Tex-Coords and Tangents remember?)
Anyhow, so I used the SSAO shader with this New 24 bit depth and found that it upped the quality a WHOLE LOT!
Now that I have a higher resolution depth I thought if I Multiplied the "Depth Delta" (now much finer by nature) inside the Shadeer
then Maybe I'd have a bit more latitude.. I did..
See the "500.0" in:
Code: Select all
//--------------------------------------------------------
float compareDepths(in float depth1, in float depth2,inout int far)
{float garea = 2.0; // gauss bell width
// WHEN USING "24 Bit Unpacked Depth" the Depth-Delta alue can be multiplied by MUCH MORE!!
float diff = (depth1 - depth2) * 500.0 ; // depth difference (0-500) and even more..
//reduce left bell width to avoid self-shadowing
if (diff < gdisplace) {garea = diffarea;} // Lots can still be done here once grasped properly..
else {far = 1;}
float gauss = pow(2.7182,-2.0*(diff-gdisplace)*(diff-gdisplace)/(garea*garea));
return gauss;
}
//--------------------------------------------------------
I also scaled the "Radius" (inversely) by the (now linearized) depth so that "Far" areas don't get treated the same as "Near" areas..
Code: Select all
// I added this because I thought that having the AO darkness
// distance scaled by inverse depth would add a bit of realism..
float dd = (1.0 - depth) * radius * (1.0 - UnpackedDepth );
O.K.