uniform sampler2D 	heightmap,
					colormap,
					depthmap,
					normalmap;

uniform mat4		eyeToWorld;
uniform vec3		campos;
					
uniform vec3 invTerrainDim;
uniform float terrainMaxHeight;
uniform float maxRadius;
uniform float occScale;
uniform float terrainNormOrg;

varying vec4	VPOS;
varying vec2 	texcoord;

vec4 decode(vec4 enc)
{
    vec2 fenc = enc.xy*4.0-2.0;
    float f = dot(fenc,fenc);
    float g = sqrt(1.0-f/4.0);
    vec4 n;
    n.xy = fenc.xy*g;
    n.z = 1.0-f/2.0;
	n.w=enc.w;
    return n;
}

void main()
{
	/*vec4 pos;
	pos.z = texture2D(depthmap,texcoord.st).r;*/
	vec4 normal = decode(texture2D(normalmap,texcoord.st));
	
	// compute world position
	vec3 Wpos;
	Wpos=(VPOS.xyz*-texture2D(depthmap,texcoord.st).r)+campos;
	
	// convert normal to world space
	normal.w=0.0;
	vec4 WSnormal=eyeToWorld*normal;
	
	float facing=dot(normal.xyz,vec3(0,0,1));
	
	// get distance from terrain
	vec2 heigthmapCoord = (Wpos.xz*invTerrainDim.xz)+vec2(0.5,0.5);
	float tHeight=(texture2D(heightmap,heigthmapCoord.st).x-terrainNormOrg)*terrainMaxHeight;
	float tDistance=Wpos.y-tHeight;
	
	// get terrain sky visibility value from terrain
	float skyVisibility=texture2D(colormap,heigthmapCoord.st).a;

	// compute ambient occlusion basing on distance
	float d=clamp(tDistance/maxRadius,0.0,1.0);
	float nd=max(0.0,((WSnormal.y*facing)+d)*d);
	float visibility=mix(skyVisibility,1.0,nd/*d*d*/);	//0 max occlusion, 1 - no occlusion
	
	gl_FragColor=vec4(min(visibility+occScale,1.0));
}
