uniform sampler2D Normal;     // light first's gbuffer
uniform sampler2D Reflection; // for reflection
uniform sampler2D Color0;     // previous scene color vals

uniform float ScreenWidth;
uniform float ScreenHeight;

varying vec3 eyeToScreen;

vec2 resolution  = vec2( ScreenWidth / 4.0, ScreenHeight / 4.0 );
vec2 offset = vec2( 1.0 / ScreenWidth, 1.0 / ScreenHeight );

void main()
{
  // read this pixels info from buffer
  vec4 buff = texture2D(Normal, gl_TexCoord[1].st); // TexCoord1 for hi res

  // normal is first three components, depth in alpha
  vec3 norm   = 2.0 * buff.xyz - 1.0;
  float depth = buff.a;
  float attenuation = 1.0 - (depth / 6000.0);

  float totalVisibility = 0.5;

  if( attenuation > 0.0 )
  {
    // Offset for texture look ups
    vec3 offsetBase = texture2D(Reflection, gl_TexCoord[0].st * resolution).xyz;
    offsetBase.xy = normalize(offsetBase.xy);
    vec4 offsetA = vec4(offsetBase.x, offsetBase.y, offsetBase.x - 1.0, offsetBase.y);
    vec4 offsetB = vec4(offsetBase.x - 1.0, offsetBase.y - 1.0, offsetBase.x, offsetBase.y - 1.0);
    vec2 offsetScale = 20.0 * offset;
    offsetA *= offsetScale.xyxy;
    offsetB *= offsetScale.xyxy;

    // Take samples
    vec4 occluderDepth;
    vec4 delta;
    vec4 visibility;
    vec4 visibility2;
    vec4 accessibility;

    vec2 normOffset = 20.0/*/(norm.z+1.0)*/ * norm.xy * offset;//vec2(0.0);//

    occluderDepth.x = texture2D(Normal, gl_TexCoord[0].st + normOffset + offsetA.xy).w;
    occluderDepth.y = texture2D(Normal, gl_TexCoord[0].st + normOffset + offsetA.zw).w;
    occluderDepth.z = texture2D(Normal, gl_TexCoord[0].st + normOffset + offsetB.xy).w;
    occluderDepth.w = texture2D(Normal, gl_TexCoord[0].st + normOffset + offsetB.zw).w;

    delta         = (depth - occluderDepth);
    visibility    = clamp((delta / occluderDepth), 0.0, 1.0);
    accessibility = mix(step(vec4(depth), occluderDepth), vec4(0.5), 2.0 * visibility);//1.0 - (delta / (delta + 1.0));//

    offsetA *= 0.5;
    offsetB *= 0.5;

    occluderDepth.x = texture2D(Normal, normOffset + gl_TexCoord[0].st - offsetA.yx).w;
    occluderDepth.y = texture2D(Normal, normOffset + gl_TexCoord[0].st - offsetA.wz).w;
    occluderDepth.z = texture2D(Normal, normOffset + gl_TexCoord[0].st - offsetB.yx).w;
    occluderDepth.w = texture2D(Normal, normOffset + gl_TexCoord[0].st - offsetB.wz).w;
/*
    delta          = (depth - occluderDepth);
    visibility     = clamp((delta / occluderDepth), 0.0, 1.0);
    delta          = max(delta, 0.0);
    //visibility2    = smoothstep(0.0, 20.0, delta);
    //visibility     = max(visibility, visibility2);
    accessibility = delta / (delta + 1.0);//accessibility += mix(greaterThan(occluderDepth, vec4(depth)), vec4(0.5), visibility);
*/
    delta         = (depth - occluderDepth);
    visibility    = clamp((delta / occluderDepth), 0.0, 1.0);
    accessibility+= mix(step(vec4(depth), occluderDepth), vec4(0.5), 2.0 * visibility);//1.0 - (delta / (delta + 1.0));//

    // Average results
    totalVisibility = dot(accessibility, vec4(0.125, 0.125, 0.125, 0.125));
  }

  gl_FragColor = vec4(totalVisibility, totalVisibility, totalVisibility, 0.0);
}