
The following are darker to show the GI


OK, this shader is for DEFERRED PIPELINES because I dont really see anyone using 2 passes to have a depth and normal texture
This SSAO technique is superior to any you may have seen like the one in XEffects, because it uses normals to calculate occlusion (it may be a bit slower, but it does SSAO on parallax mapped flat surfaces
I have coded my normals, depth and color in a particular way. The ambient texture(tex0) contains ambient rgb + the x coord of a normal(alpha) (32 bit 8 bit per channel), the other texture (tex2) contains the depth (red) + the y coord of a normal(green) (16 bit float *2). You may have to rework the shader to fit your GBuffer layout.
LASTLY, the OCCLUSION is NOT CONSISTENT YET. Because I haven't paid any attention to position reconstruction (depending on the FoV and aspect ratio), the occlusion is "stretched" in the y direction (darker at the top and bottom of the screen).
Code: Select all
"uniform sampler2D tex0;"\
"uniform sampler2D tex1;"\
"uniform sampler2D tex2;"\
"uniform sampler2D tex3;"\
"uniform vec2 screenSz;"\
"uniform float camFar;"\
"float rand(vec2 co){"\
" return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * vec2(43758.5453,43458.5734));"\
"}\n"\
"#define smplsz 7.05\n"\
"#define jitter 8.95\n"\
"#define range 10.0\n"\
"#define gi_scale 6.85\n"\
"#define ao_scale 1.55\n"\
"#define gi_mul_ao 0.45\n"\
"void main() {"\
" vec2 UV = gl_TexCoord[0].xy;"\
" vec2 sample3 = texture2D(tex2,UV).xy;"\
" if (sample3.x==1.0)"\
" discard;"\
" float mult = camFar/range;"\
" vec4 col = texture2D(tex0,UV);"\
" col.w = col.w*2.0-1.0;"\
" vec3 n = vec3(col.w,sample3.y,sqrt(max((1.0-sample3.y*sample3.y-col.w*col.w),0.0)));"\
" vec3 p = (vec3(UV*2.0-1.0,1.0)*sample3.x*mult);"\
" vec2 fres = UV*screenSz*vec2(5.0/128.0);"\
" vec2 jitterSz = jitter/screenSz;"\
" float ao = 0.0;"\
" vec3 gi = vec3(0.0,0.0,0.0);"\
" vec2 inc = vec2(smplsz)/screenSz;"\
" vec2 UVoff;"\
" float Adiv = 4.0/(screenSz.x*screenSz.y);"\
" for(float i=1.0; i<4.0; ++i) {"\
" float samples = i*3.0;"\
" for(float j=0.0; j<samples; ++j) {"\
" float angle = j*6.283185308/samples;"\
" UVoff = clamp(UV+vec2(sin(angle),cos(angle))*i*inc+rand(fres+UVoff)*jitterSz,0.000386,0.999614);"\
" vec2 sample4 = texture2D(tex2, UVoff).rg;"\
" float sampleDepth = mult*sample4.r;"\
" vec3 ddiff = vec3(UVoff*2.0*sampleDepth-vec2(sampleDepth),sampleDepth)-p;"\
" float rd = dot(ddiff,ddiff)*3.141592654;"\
" ddiff = normalize(ddiff);"\
" vec4 colSmp = texture2D(tex0,UVoff);"\
" colSmp.w = colSmp.w*2.0-1.0;"\
" vec3 nmlE = vec3(colSmp.w,sample4.y,sqrt(max((1.0-sample4.y*sample4.y-colSmp.w*colSmp.w),0.0)));"\
" float A = sampleDepth*sampleDepth*Adiv;"\
" float cosE = max(dot(nmlE,-ddiff),0.0);"\
" float cosR = dot( n,ddiff );"\
" ao += cosE*max(cosR*4.0,0.0)/sqrt(A/rd + 1.0);"\
" gi += colSmp.rgb*max(cosR,0.0)*cosE*(A/rd+1.0);"\
" }"\
" }"\
" ao *= ao_scale/30.0;"\
" gi *= gi_scale/30.0;"\
" gl_FragColor = vec4((col.rgb+gi*gi_mul_ao)*vec3(max(-pow(ao,0.936),-1.0))+col.rgb+gi,1.0);"\
"}"