uniform sampler2D 	bmp;
uniform sampler2D 	bmp1;				
uniform sampler2D 	bmp2;					
uniform sampler2D 	bg;
uniform samplerCube	reflBG;

uniform float 		normalScale;

uniform float		specMul;
uniform float		reflMul;
uniform float		fresnelPow;

uniform float		refrbump;
uniform float		reflbump;
uniform float 		reflSaturation;

uniform vec3 		sundir;
uniform float		specPow;

varying vec2 		texcoord0;
varying vec2 		texcoord1;
varying vec2 		texcoord2;
varying vec2 		texcoord3;
varying vec3		viewDir;
varying vec4		pos;
varying vec4 		vpos;

varying mat3		TBN;
uniform float 		invAmbientRange;
uniform vec3 		ambientPos;

float Pi=3.14159265359;

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

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

vec3 fresnel_factor(vec3 f0, float product)
{
	return f0 + (vec3(1.0) - f0) * pow(1.0 - product, 5.0);
	//return mix(f0, vec3(1.0), pow(1.01 - product, 5.0));
}

float D_GGX(float roughness, float NdH)
{
	float m = roughness * roughness;
	float m2 = m*m;
	float d = (NdH * m2 - NdH) * NdH + 1.0;
	return m2 / (Pi*d*d);
}

float G_schlick(float roughness, float NdV, float NdL)
{
	float r=(roughness+1.0)/2.0;
	float k=r*r*0.5;//0.125;
	float V = NdV * (1.0 - k) + k;
	float L = NdL * (1.0 - k) + k;
	return /*0.25/*/(V*L);
}

vec3 CookTorrance(float NdL, float NdV, float NdH, vec3 F, float roughness)
{
	float D = D_GGX(roughness, NdH);
	float G = G_schlick(roughness, NdV, NdL);
	return (D*F*G) / mix(1.0-(roughness*0.9),1.0,4*NdL*NdV);
} 
// -----------------------------------------------------------------

////////////////////////////
void main()
{
	/*vec3 normalBump=vec3(normalScale,-1.0,normalScale);
	vec3 normalBump0=vec3(normalScale0,-1.0,normalScale0);
	vec3 normalBump1=vec3(normalScale1,-1.0,normalScale1);

	float t=clamp((-pos.z-10000.0)/50000.0,0.0,1.0);
	normalBump1=mix(normalBump1,vec3(0.0,-1.0,0.0),t);
	
	
	vec3 macroNormal=texture2D(waveNormals1,((texcoord2.st*0.125))).xyz;
	macroNormal=mix(macroNormal,texture2D(waveNormals1,((texcoord2.st*0.0125))).xyz,t);
	vec3 wavesNormal0=	texture2D(waveNormals0,(texcoord0.st)).xyz*normalBump0+macroNormal*normalBump1;

	vec3 normal=vec3(0.0,0.0,0.0);	
	//normal.xz=texture2D(waveNormalsDetail,texcoord1.st).xz*normalBump0.xz*2.0;
	normal=normalize(normal+wavesNormal0.xyz);*/
	
	vec3 normalBump=vec3(normalScale,1.0,normalScale);

	vec4 normalColor=texture2D(bmp,texcoord1.st);
	vec3 normal;
	normal.xy=(normalColor.xy*2.0)-1.0;
	normal.z=sqrt(1.0-normal.x*normal.x-normal.y*normal.y);
	
	vec4 normalColor1=texture2D(bmp1,texcoord2.st);
	vec3 normal1;
	normal1.xy=(normalColor1.xy*2.0)-1.0;
	normal1.z=sqrt(1.0-normal1.x*normal1.x-normal1.y*normal1.y);
	
	vec4 normalColor2=texture2D(bmp2,texcoord3.st);
	vec3 normal3;
	normal3.xy=(normalColor2.xy*2.0)-1.0;
	normal3.z=sqrt(1.0-normal3.x*normal3.x-normal3.y*normal3.y);
	
	vec3 normal2=normal;
	normal=(normal2 + normal1)*0.5;
	normal=(normal3 + normal)*0.5;
	normal=normalize(normal);
	
	vec3 tvdir=normalize(viewDir);
	
	vec2 UV=(pos.xy/pos.w)*0.5+0.5;
	UV+=normal.xy*refrbump;
	//vec2 reflectOffset=UV+normal.xz*reflbump;
	
	//float depth=texture2D(depthBG,UV).r;

	vec3 N;
	N=TBN*normal;
	N*=-normalBump;
	N=normalize(N);
	
	float fresnelres=clamp(pow(1.0-dot(N,tvdir),fresnelPow)*10.0,0.0,1.0);
	//vec3 reflcolor=texture2D(reflBG,reflectOffset).xyz;
	
	vec3 reflection = reflect(tvdir,N);
	reflection= ((ambientPos-vpos.xyz)*invAmbientRange) + reflection;
//	float glossLod=(1.0-E)*cubeLod2;	
	vec3 reflcolor = RGBMDecode(textureCubeLod(reflBG,reflection.xyz,0.0)).xyz;
	
	// DESATURATE SPEC
	float lum=dot(reflcolor.rgb,vec3(0.3,0.59,0.11));
	reflcolor.rgb=mix(vec3(lum),reflcolor.rgb,reflSaturation);
						
	vec3 H = sundir+tvdir;
	H=normalize(H);
	
	float NdotH = clamp(dot(H,normal),0.0,1.0);
	float EdotH = clamp(dot(tvdir,H),0.0,1.0);
	float NdotE = clamp(dot(normal,tvdir),0.0,1.0);
	float NdotL = clamp(dot(sundir,normal),0.0,1.0);
/*	float NdotH = (dot(H,normal));
	float EdotH = dot(tvdir,H);
	float NdotE = dot(normal,tvdir);
	float F=0.5+0.5*pow((1.0-EdotH),5.0)*1.5;
	float spec=max((0.0397436*specPow+0.0856832)*(F*pow(NdotH,specPow)/max(NdotL,NdotE)),0.0);//*0.25;*/
	
	// --------------------------------------- COOK TORRANCE --------------------------------------
	vec3 REFL=vec3(specMul);
	float rough=sqrt(specPow);
			
	// specular
	vec3 specfresnel=vec3(0.0,0.0,0.0);
	vec3 spec=vec3(0.0,0.0,0.0);		
	
	specfresnel=fresnel_factor(REFL, EdotH)*specMul;
	spec = CookTorrance(NdotL, NdotE, NdotH, specfresnel, rough) * NdotL;
	// -------------------------------------------------------------------------------------
	
	gl_FragColor.xyz=mix(texture2D(bg,UV).rgb,reflcolor*reflMul,fresnelres);//mix(texture2D(bg,UV).rgb,reflcolor*reflMul,fresnelres) + spec;//max(mix(texture2D(bg,UV).rgb , reflcolor*reflMul, fresnelres),0.0) + spec;
	gl_FragColor.w=1.0;
}
