uniform sampler2D 	colorTex,
					normalTex,
					matTex,
					posTex;

uniform samplerCube	envCube;

varying vec2 		texcoord;
uniform vec4		ambientColor;		
varying vec2		VPOS;
uniform mat4		eyeToWorld;

uniform vec3 		lightpos;
uniform float		lightrange, // 1.0/light range
					lightfallof;
uniform vec3 		eyeLightpos;
uniform float		ambientScatter;
uniform float		maxdist;
uniform float		cubeLod;
uniform float 		saturation;

float Pi=3.14159265359;

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;
}

float phong_diffuse()
{
	return (1.0 / Pi);
}

vec4 RGBMDecode( vec4 rgbm ) {
  return vec4(6.0 * rgbm.rgb * rgbm.a,1.0);
}

void main()
{
	vec4 finalcolor=vec4(0.0,0.0,0.0,0.0);
	vec4 pos;
	pos.z = texture2D(posTex,texcoord.st).r;
	
	// get pos int eye space
	pos.xy=VPOS.xy*-pos.z;
	pos.w=1.0;
	
	// compute attenuation distance in eye space
	vec3 ldir=eyeLightpos-pos.xyz;
	float vDist=min(length(ldir)*lightrange,1.0);
	float att = clamp(1.0 - pow(vDist,lightfallof),0.0,1.0);
	
	float mindist=maxdist-1000.0;
	float t=1.0-( clamp( (length(pos)-mindist)/(maxdist-mindist),0.0,1.0) );
	att*=t;

	if(att>0.0)
	{
		// read all other textures
		vec4 ambient = texture2D(colorTex,texcoord.st);
		vec4 encoded=texture2D(normalTex,texcoord.st);
		vec4 normal = decode(encoded);
		float metal = texture2D(matTex,texcoord.st).r*step(ambient.a,0.0);	// if(scatter=ambient.a > 0) metal = 0
	
		// convert all in world space
		pos=eyeToWorld*pos;
		vec4 N=eyeToWorld*vec4(normal.xyz,0.0);
	
		/*vec4 diffuse = RGBMDecode(textureCubeLod(envCube,-N.xyz,cubeLod));
		diffuse = (diffuse+vec4(ambient.a+ambientScatter))/vec4(1+ambient.a+ambientScatter);
			*/
		
		// IBL diffuse
		vec4 IBLdiffuse = RGBMDecode(textureCubeLod(envCube,-N.xyz,cubeLod));
		//vec4 diffuse =  IBLdiffuse * phong_diffuse();	
		vec4 diffuse = /*mix(*/IBLdiffuse*(phong_diffuse()+vec4(ambient.a+ambientScatter))/vec4(1+ambient.a+ambientScatter)/*,diffuse,metal)*/;
		
		finalcolor = mix(ambient,vec4(0.0),metal)*ambientColor*diffuse;//ambientColor*ambient*diffuse*(1.0-metal); 
	}
	
	// DESATURATE
	float lum=dot(finalcolor.rgb,vec3(0.3,0.59,0.11));
	finalcolor.rgb=mix(vec3(lum),finalcolor.rgb,saturation);
	
	gl_FragColor=max(vec4(0.0),vec4(finalcolor.xyz,att));
}
