This is 'kinda' ok, cause it is obvious that effect will fail when a fog is applied to the scene, as SSAO is going to be 'blended' with the fog.
Additionaly, it looks v.ugly especially on the trees that are high above player and their background is a clouds/sky mainly (bright) - again ssao parts look max ugly.
Just take a look:
SSAO results
SCENE without SSAO
SCENE with SSAO
I was thinking if there is any better 'idea' cruising around guys, or any suggestion to make this look 'optimal' .. can't find any possible solution,
many thanks for anything that can force this whole scene with ssao - look more realistic.
SSAO is n effect of the ambient lighting, so SSAO should only be applied to the ambient part of the lighting.
You have to apply it at an early stage of your lighting calculation.
My rendering looks as below - all on Framebuffers, main scene rendered with Multisampled FBO then finally blitted.
1. RTT shadowmap (ARB0)
2. RTT water reflections (ARB3)
3. RTT (Multisampled) full scene (terrain, foliage, sky, clouds,... MODELS)
MODELS render
|_run shader
|_pass color texture (ARB1) (generated at model loading step)
|_pass normal texture (ARB2) (generated at model loading step)
|_pass shadow texture (ARB0) (generated at step 1)
|_pass SSAO_texture (ARB7) (generated by SSAO_shader below)
| Normal/Color texcoords are passed via VBO/IBO - as GL_TEXTURE1
| Tangents passed via VBO/IBO - as GL_TEXTURE2
\
|
Calculate shadowmap projection
Compute lighting
Apply textures (color+normal go with coords gl_MultiTexCoord1)
Apply shadowmap texture
apply fog
4. Blit to FBO - color+depth buffer
5. end of render - time to run the final shaders
6.
HIGHPASS/BLOOM/...
|
SSAO shader
|_ takes input from depthtexture
|_ performs ssao
|_ returns ssao_texture
POSTPROCESSING shaders
7. Final draw onto the screen
Now - i made previously a bad assumption that to have a SSAO running it is enough to blend it over the final scene, surely that's a mistake.
To do it properly, as you mentioned my model ambient colour should be multiplied by the actual SSAO_texture.
This is why SSAO_texture is now passed to my models shader, but to multiply by SSAO_texture i need to know which UV coord of this texture should
be taken into consideration, and here is the actual problem i believe. I don't pass any texcoords for SSAO_texture, as they should be somehow calculated
for every pixel that is being computed by the shader.
Here is the model shader, that is running for every model i draw on the scene(batched of course).
/*
* Store fog info in color
*/
gl_FrontColor.a = clamp( ( gl_Position.z-gl_Fog.start ) / ( gl_Fog.end - gl_Fog.start ) , 0.0 , 1.0 );
}
[FRAGMENT SHADER]
uniform sampler2D colorMap; //comes in with vbo texture1
uniform sampler2D normalMap; //comes in with vbo texture2
uniform sampler2D shadowMap; //comes in as texture0
uniform sampler2D ssaoMap; //comes in as texture7
varying vec2 ssao_texcoord; //calculated in vx shader
/*
* SM
*/
vec4 ShadowCoordPostW;
float chebyshevUpperBound( float distance,float SHADOWPOWER)
{
// We retrive the two moments previously stored (depth and depth*depth)
vec2 moments = texture2D(shadowMap,ShadowCoordPostW.xy).rg;
// Surface is fully lit. as the current fragment is before the light occluder
if (distance <= moments.x)
return 1.0 ;
// The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check
// How likely this pixel is to be lit (p_max)
float variance = moments.y - (moments.x*moments.x);
variance = max(variance,SHADOWPOWER);
float d = distance - moments.x;
float p_max = variance / (variance + d*d);
return p_max;
}
void main()
{
vec3 n;
vec4 color;
//NORMALMAP non NORMALMAP render
if(useBumpMap==1)
{
n = normalize(texture2D(normalMap, gl_TexCoord[1].st).xyz * 2.0 - 1.0);