uniform sampler2D 	depthTex,
			colorTex;
uniform vec3		sundir;
varying vec2 		texcoord;
varying vec2		VPOS;
uniform float		inScatter;
uniform float      	extintion;
uniform float 		sunpower;

uniform mat4		eyeToWorld;
uniform vec3		campos;

// costanti passate allo shader
uniform vec3  SUN; 	// = colore del sole
uniform	vec3  C0; 	// = cBr+cBm;	
uniform vec3  C1; 	// = 1.0/(cBr+cBm) * SUN;
uniform vec3  cBr; 	// = RayLeigh
uniform vec3  cBm; 	// = Mie

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 vec3		horizonColor;
uniform vec3		zenithColor;
uniform vec3 		fogColor; 
//uniform float		fogMultiplier;
uniform float 		waterY;
//uniform vec3		waterColor;
uniform float		waterDensity;

uniform vec3		oceanDeepColor;
uniform vec3		oceanShallowColor;

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

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

float ComputeLinearFog( vec3 wpos, vec3 cameraToWorldPos )
{
	float fogInt;
	float Y=waterY-campos.y;
	
	//if(cameraToWorldPos.y
	if(wpos.y>waterY)
		fogInt=(length( cameraToWorldPos ) * Y) / cameraToWorldPos.y; 
	else
		fogInt=length( cameraToWorldPos );
		
	return /*sqrt(*/ exp( -waterDensity * (fogInt) );// );
}

float ComputeScatter( vec3 wpos, vec3 cameraToWorldPos )
{
	float L=0.0;
	float Y=waterY-campos.y;
	vec3 dir=vec3(0.0,0.0,0.0);
	
	if(Y <= 0.0)
		Y=0.0;
	
	if(wpos.y>waterY )
		L=(length( cameraToWorldPos ) * Y) / cameraToWorldPos.y; 
	else
		L=length( cameraToWorldPos );
			
	if(L>0.0)
		dir=normalize(cameraToWorldPos);
		
	return exp( -waterDensity * Y * 0.1 ) * ( ( exp((dir.y-1.0)*waterDensity*L) - 1.0 ) / ((dir.y-1.0) * waterDensity)) * 0.01;
}

void main()
{
	vec4 pos=texture2D(depthTex,texcoord.st);
	vec4 color=texture2D(colorTex,texcoord.st);

	// compute position
	pos.xy=VPOS*-pos.z;
	pos.w=1.0;
	vec4 Wpos=eyeToWorld*pos;
	
	vec3 Cam2WorldPos=Wpos.xyz-campos.xyz;
	float distance=length(Cam2WorldPos);

	vec3 vdir=normalize(pos.xyz);
	float cos=dot(sundir,vdir.xyz);
	float F1=(1.0 + cos*cos*0.5);
	float F2=(C4/pow(C5-C6*cos*0.5,C7));
	vec3 Br = cBr*F1;
	vec3 Bm = cBm*F2;
	
	float fogdist=ComputeVolumetricFog(Wpos.xyz, Cam2WorldPos);
	float att=clamp(ComputeLinearFog(Wpos.xyz, Cam2WorldPos),0.0,1.0);
	float scatter=ComputeScatter( Wpos.xyz, Cam2WorldPos );//*fogColor;//*0.01;
	
	/*vec3 LinMul;
	LinMul=C1*(1.0-exp(-C0*min(distance,10000.0)));
	vec3 fogLin = (Br+Bm*0.1)*LinMul;
	vec3 scatterFogColor=fogLin*inScatter + fogColor;*/
	
	vec3 fFex=exp(-C0*extintion*fogdist);
	vec3 fLin=(Br+Bm)*C1*(1.0-fFex)*inScatter*fogColor;
	vec3 scatterFogColor = fLin+fFex*color.xyz;
	
	// compute fog Color and density	
	//vec3 horizon=mix(fogColor+fogColor*0.1/*+scatter*/,color.xyz,delta);
	
	vec3 shallowColor=mix(oceanShallowColor,vec3(1.0,1.0,1.0),clamp(att,0.0,1.0));
	
	vec3 horizon= /*mix( scatterFogColor, color.xyz, fogdist )*/scatterFogColor*att*shallowColor + oceanDeepColor*scatter;//color.xyz*att + mix( scatterFogColor,waterColor*scatter, fogdist ) * (1.0-att);
	gl_FragColor.xyz=max(horizon,0.0);
	gl_FragColor.w=1.0;
}
