/**
 *
 * Diplomova prace
 * Stinove techniky na dnesnim hardware a jejich porovnani
 *
 * Michal Toth
 *
 * Fakulta informacnich technologii
 * Vysoke uceni technicke v Brne
 *
 * 2013/2014
 *
 */

/**
 * Screen space ambient occlusion
 * vyuziva dve vrstvy hloubky k odstraneni artefaktu
 */

#version 420

in vec2 tc;

//uniform sampler2D texPosition;
uniform sampler2D texNormal;
uniform sampler2D texMaterial;
uniform sampler2D texDepth;
uniform sampler2D texDepth2;

uniform sampler2D texRand;

uniform mat4 imvp;
uniform float power = 1;
uniform float range = 10;
uniform float radius = 0.02;
uniform int samples = 64;
uniform float bias = 0.0;

uniform vec2 rand[256];

layout(location=0)out float AO;

float check(vec3 a, vec3 b, vec3 norm){

    vec3 d=b-a;
    vec3 nd=normalize(d);
    float l = length(d);
    return max(0,dot(norm,nd)-bias)*(1/(1+l));

}

void main() {
    float depth = texture(texDepth,tc).x;
    vec3 normal = texture(texNormal,tc).xyz;
    //vec4 pos = texture(texPosition,tc);
    vec4 pos = imvp*vec4(tc*2-1,depth*2-1,1);
    pos/=pos.w;

    float occluded=0;
    int skipped=0;

    for(int i=0;i<samples;i++){
	vec2 r = rand[i];

	r*=radius;
	r*=clamp(depth,0.1,1.0);

	vec2 tc2 = tc+r.xy;
	float depth2= texture(texDepth,tc2).x;

	if(depth2<1.0){
	    vec4 pos2 = imvp*vec4(tc2*2-1,depth2*2-1,1);
	    pos2/=pos2.w;

	    if(length(pos2-pos)>range){
		depth2= texture(texDepth2,tc2).x;
		if(depth2<1.0){
		    pos2 = imvp*vec4(tc2*2-1,depth2*2-1,1);
		    pos2/=pos2.w;
		    if(length(pos2-pos)>range){
			skipped++;
			continue;
		    }
		}
	    }

	    occluded+=power*check(pos.xyz,pos2.xyz,normal);
	}else{
	    skipped++;
	}
    }

    AO = 1-occluded/max(1.0,float(samples-skipped));
}
