uniform sampler2D 	colorTex,
					normalTex,
					matTex,
					posTex;
uniform sampler2D	brdfLUT;

uniform samplerCube	envCube;

varying vec2 		texcoord;
uniform vec4		ambientColor;		
varying vec2		VPOS;
uniform mat4		eyeToWorld;
uniform vec3		campos;
uniform	float		reflMul;
uniform	float		saturation;

uniform vec3 		lightpos;
uniform float		lightrange,
					lightfallof;
uniform vec3 		eyeLightpos;
uniform float		maxdist;
uniform float		cubeLod;


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

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);
	float att=0.0;
	
	if(reflMul>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);
		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)
		{
			vec4 encoded=texture2D(normalTex,texcoord.st);

			// get refl power
			float reflPow=encoded.z;//*16.0;
			vec3 specular=vec3(0.0,0.0,0.0);

			vec4 mat = texture2D(matTex,texcoord.st);
				
			/*if(reflPow>0.0 || mat.x>0.0)
			{*/
				// read all other textures
				vec4 normal = decode(encoded);
				vec4 metalColor=texture2D(colorTex,texcoord.st);
				float metal=mat.x*step(metalColor.a,0.0);	// if(scatter=metalColor.a > 0) metal = 0
			
				// IBL specular /////////////////////////////////////////
				float rough=sqrt(mat.y);

				pos=eyeToWorld*pos;
				vec4 N=eyeToWorld*vec4(normal.xyz,0.0);
				vec3 vdir=normalize(campos-pos.xyz);
						
				vec3 reflection = reflect(vdir.xyz,N.xyz);
				reflection= ((lightpos-pos.xyz)*lightrange) + reflection;
				
				float NdotV=max(dot(vdir,N.xyz),0.0);
				vec3 REFL=mix(vec3(0.04)*reflPow*reflPow/*reflPow*/,metalColor.xyz/*reflPow*/,metal);
				float rmax = max(max(REFL.r, REFL.g), REFL.b);
				float REFL90 = clamp(rmax*25.0,0.0,1.0);
				
				float glossLod=rough*cubeLod;
				vec4 IBLspecular = RGBMDecode(textureCubeLod(envCube,reflection.xyz,glossLod));
				
				vec2 brdf = texture2D(brdfLUT, vec2(NdotV, rough)).xy;
				vec3 IBL=REFL*brdf.x+brdf.y*REFL90;
				//IBL=mix((IBL*(reflPow-0.5)*2.0)+brdf.y,IBL+brdf.y,metal);
				
				specular=IBL*IBLspecular.xyz;
				//////////////////////////////////////////////////////////
			//}
			finalcolor.rgb = specular.rgb*reflMul;//*ambientColor.rgb;
				
			// DESATURATE
			//=0.5;
			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));
}
