uniform sampler2D 	waves,
					foam;
varying vec2 		texcoord;
varying vec2 		texcoord2;
varying vec2 		texcoord3;
varying vec2 		texcoord4;
varying vec2 		texcoord5;
uniform vec3		sundir;
varying vec3		vdir;
uniform vec3  		SUN; 	// = colore del sole
uniform float 		sunpower;
uniform sampler2D 	bg,
					depthBG,
					reflBG;
varying vec4		pos;
varying vec4		eyepos;
//varying float 	h;

uniform vec3		horizonColor;
uniform vec3		zenithColor;
uniform vec3 		fogColor; 
uniform vec3		ambientColor;
uniform vec3		waterColor;

uniform float 		inScatter;
uniform float       extintion;
uniform vec3		campos;

uniform float		fogMultiplier;
uniform float		reflMul;
uniform float		reflLevel;
uniform float		specPow;
uniform float		specMul;

uniform float		density;
uniform float		refrbump;
uniform float		reflbump;

uniform float		waterY;

// costanti passate allo shader
uniform vec3  cBr; 	// = RayLeigh
uniform vec3  cBm; 	// = Mie	
uniform	vec3  C0; 	// = cBr+cBm;	
uniform vec3  C1; 	// = 1.0/(cBr+cBm);
uniform float C2;	// = log(e)
uniform float C4;	// = (1-g)^2
uniform float C5;	// = 1+g^2
uniform float C6;	// = 2*g
uniform float C7;	// = 3/2

uniform float cHeightFallof;//=0.0005;
float cVolFogHeightDensityAtViewer=exp( cHeightFallof * -campos.y);

float ComputeVolumetricFog( vec3 cameraToWorldPos )
{
	float fogInt = length( cameraToWorldPos )* cVolFogHeightDensityAtViewer;
	
	if( abs( cameraToWorldPos.y) > 0.01)
	{
		float t = cHeightFallof * cameraToWorldPos.y;
		fogInt*= ( 1.0-exp( -t ) ) / t;
		
	}
	return exp( -extintion/*0.001*/ * fogInt);
}

float ComputeScatter( vec3 cameraToWorldPos, float L, float ext )
{
	vec3 dir=normalize(cameraToWorldPos);
	return ( ( exp((dir.y-1.0)*ext*L) - 1.0 ) / ((dir.y-1.0) * ext))*0.01;
}

////////////////////////////
void main()
{
	vec4 wavesNormal=texture2D(waves,texcoord.st);
	vec3 normal=(wavesNormal.xyz*2.0-1.0);
	
	wavesNormal=texture2D(waves,texcoord2.st);
	vec3 normal2=(wavesNormal.xyz*2.0-1.0);

	wavesNormal=texture2D(waves,texcoord3.st);
	vec3 normal3=(wavesNormal.xyz*2.0-1.0);
	
	vec3 N=normal;
	N.y=normal.z;
	N.z=-normal.x;
	N.x=-normal.y;
	
	vec3 N2=normal2;
	N2.y=normal2.z;
	N2.z=-normal2.x;
	N2.x=-normal2.y;
	
	vec3 N3=normal3;
	N3.y=normal3.z;
	N3.z=-normal3.x;
	N3.x=-normal3.y;
	
	N=normalize(N+N2+N3);
	
	/*normal.z=N.y;
	normal.x=-N.z;
	normal.y=-N.x;
	normal=normalize(normal);*/
	
	//float distance=length(vdir.xyz);
	float fogdist=clamp(ComputeVolumetricFog(-vdir),0.0,1.0);
	
	vec3 tvdir=normalize(vdir);
	float cos=dot(sundir,tvdir.xyz);
	
	float F1=(1.0 + cos*cos);
	float F2=(C4/pow(C5-C6*cos,C7));

	vec3 Br = cBr*F1;
	vec3 Bm = cBm*F2;

	// PROVA DIFFUSO ////////////
	float NdotL=clamp(dot(sundir,N),0.0,1.0);
	
	vec3 halfv = sundir+tvdir;
	halfv=normalize(halfv);
	float spec = clamp(dot(halfv,N),0.0,1.0);
	spec = pow(spec,specPow)*specMul;
	
	vec2 UV=(pos.xy/pos.w)*0.5+0.5;
	vec2 reflectOffset=UV+normal.xy*reflbump;
	
	float depth=texture2D(depthBG,UV).z;
	UV+=normal.xy*refrbump;
	
	float d=abs(depth-eyepos.z);
	float d2=exp(-d*0.005);
	float att=/*1.0-*/(clamp(exp(-d*density),0.0,1.0));
	float fdist=1.0-(clamp(d2,0.0,1.0));
	
	// WATER COLOR //////////////////////////////////
	/*vec3 wLinMul;
	wLinMul=C1*(1.0-exp(-C0*5000.0*(1.0-d)));
	vec3 wfogLin = (Br)*wLinMul;
	vec3 WaterFinalColor=wfogLin*inScatter + waterColor;//*fogMultiplier;	// FOG COLOR*/
	float wScatter=/*clamp(*/ComputeScatter(-vdir,d,density);//,0.0,1.0);
	/////////////////////////////////////////////////
	
	float fresnelres=pow(1.0-abs(dot(N,tvdir)),5.5)*reflLevel;
	vec3 reflcolor=texture2D(reflBG,reflectOffset).xyz;
	
	////////////////////////////////
	///////////////////////////// FOG ////////////////////////////////
	vec3 LinMul;
	LinMul=C1*(1.0-exp(-C0*10000.0*(1.0-fogdist)));
	vec3 fogLin = (Br+Bm*0.1)*LinMul;
	vec3 scatterFogColor=fogLin*inScatter + fogColor*fogMultiplier;
	//////////////////////////////////
	
	float foamDensity=0.0;
	vec3 foamColor=vec3(0.25,0.25,0.25);
	if(-eyepos.z<7500.0)
	{
		float foamdata=1.0-texture2D(foam,texcoord2.st*0.5).a;
		foamDensity=foamdata*texture2D(foam,texcoord5.st*1.5).a*texture2D(foam,texcoord.st).a*5.0*clamp(pow((1.0-fdist),5.0),0.0,1.0)*clamp(fdist*10.0,0.0,1.0);
		foamDensity=clamp(foamDensity,0.0,1.0);
		foamColor=mix(scatterFogColor,/*foamColor**/(ambientColor*foamColor+NdotL*SUN),fogdist);
	}

	vec3 waterFinalColor=mix(waterColor*wScatter/*NdotL*/,reflcolor*reflMul,clamp(fresnelres,0.0,1.0));
	gl_FragColor.xyz=( texture2D(bg,UV*0.25).rgb*att + mix( scatterFogColor,spec*SUN + waterFinalColor, fogdist ) * (1.0-att) ) * (1.0-foamDensity) + foamColor*foamDensity;
	gl_FragColor.w=1.0;
}
