/*uniform sampler2D 	waveNormals0,
					waveNormals1,
					waveNormals2,
					waveNormals3,
					waveNormals4,
					waveNormals5;*/
					
uniform sampler2D	waveNormals0,
					waveHeights0,
					waveNormals1,
					waveHeights1,
					waveNormalsDetail;
					
uniform sampler2D 	bg,
					//depthBG,
					reflBG;

uniform float 		normalScale;
uniform float 		normalScale0;
uniform float 		normalScale1;

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 vec3		vdir;
varying vec4		pos;

uniform vec3 		campos;

float Pi=3.14159265359;

const float cHeightFallof=0.00001;	// inserire dall'esterno
float cVolFogHeightDensityAtViewer=exp( cHeightFallof * -campos.y);

// ------------------ 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 wavesNormal0=	texture2D(waveNormals0,(texcoord1.st)).xyz+
						texture2D(waveNormals0,(texcoord0.st)).xyz+
						texture2D(waveNormals1,(texcoord0.st*0.1)).xyz+
						texture2D(waveNormals2,(texcoord0.st*0.01)).xyz+
						texture2D(waveNormals3,(texcoord0.st*0.001)).xyz+
						texture2D(waveNormals4,(texcoord0.st*0.00025)).xyz+
						texture2D(waveNormals5,(texcoord0.st*0.0000625)).xyz;
	
	vec3 normal=normalize(wavesNormal0.xyz*normalBump);*/

	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 tvdir=normalize(vdir);
	
	vec2 UV=(pos.xy/pos.w)*0.5+0.5;
	vec2 reflectOffset=UV+normal.xz*reflbump;
	
	//float depth=texture2D(depthBG,UV).r;
	UV+=normal.xz*refrbump;
	
	float fresnelres=clamp(pow(1.0-dot(normal,tvdir),fresnelPow)*10.0,0.0,1.0);
	vec3 reflcolor=texture2D(reflBG,reflectOffset).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;
	// -------------------------------------------------------------------------------------
	
	vec3 refrBG=texture2D(bg,UV).rgb;//(1.0+clamp(-pos.z*0.01,0.0,1.0)*2.0)*texture2D(bg,UV).rgb*10.0;
	
	gl_FragColor.xyz=mix(refrBG,reflcolor*reflMul*2.0,fresnelres) + spec;//max(mix(texture2D(bg,UV).rgb , reflcolor*reflMul, fresnelres),0.0) + spec;
	gl_FragColor.w=1.0;
}
