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 vec3 		lightpos;
uniform float		lightrange,
					lightfallof;
uniform vec3 		eyeLightpos;

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);
	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 world space
	vec3 ldir=eyeLightpos-pos.xyz;
	float vDist=length(ldir)*lightrange;
	float att = clamp((1.0 - vDist)*lightfallof,0.0,1.0);
	
	if(att>0.0)
	{
		// read all other textures
		vec4 ambient = texture2D(colorTex,texcoord.st);
		vec4 encoded=texture2D(normalTex,texcoord.st);
		vec4 normal = decode(encoded);
		vec4 mat = texture2D(matTex,texcoord.st);
		mat.y=sqrt(mat.y);
		
		// get refl power
		float reflPow=encoded.z*16.0;
	
		// convert all in world space
		pos=eyeToWorld*pos;
		vec4 N=eyeToWorld*vec4(normal.xyz,0.0);

		vec4 diffuse = RGBMDecode(textureCubeLod(envCube,-N.xyz,6.0));
		diffuse = (diffuse+vec4(mat.x))/vec4(1+mat.x);
		
		vec3 vdir=normalize(campos-pos.xyz);
		vec3 reflection = reflect(vdir,N.xyz);
		reflection= ((lightpos-pos.xyz)*lightrange) + reflection;
		float glossLod=(1.0-mat.y)*7.0;
		float F=min(reflPow,0.2)+(1.0-reflPow)*pow((1.0-dot(vdir,N.xyz)),5.0);
		vec4 specular = RGBMDecode(textureCubeLod(envCube,reflection.xyz,glossLod))*F;
			
		finalcolor = ambientColor*(ambient*diffuse+specular*reflMul*mat.y/*reflPow*/); 
	}
	gl_FragColor=max(vec4(0.0),vec4(finalcolor.xyz,att));
}
