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;
uniform float 		sssMultiplier;

// 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 vec3 		moonlightcolor;

// ------------ ATMOSPHERE ------------------------------

uniform float 		length_unit;
uniform vec3 		earth_center;
uniform vec3 		sundirW;

vec3 GetSunIrradiance(vec3 p, vec3 sun_direction);

// -------------------------------------------------------

const float PI=3.1415926535;

const float cHeightFallof=0.00001;	// 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 exp( -waterDensity * (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;
}

float hgPhase(float x, float g)
{
    float g2 = g*g;
	return 0.25 * ((1.0 - g2) * pow(1.0 + g2 - 2.0*g*x, -1.5));
}

float phase2Lobes(float x)
{
  //  const float m = 1.0;
   // const float gm = 0.9;
    
	float lobe1 = hgPhase(x, 0.55 /* gm*/);
    //float lobe2 = hgPhase(x, -0.5 * gm);
    
    return lobe1;//mix(lobe2, lobe1, m);
}

/*float Phase(float nu) 
{
	float k = 3.0 / (16.0 * PI);
	return k * (1.0 + nu * nu);
}*/

void main()
{
	vec4 pos;
	pos.z=texture2D(depthTex,texcoord.st).r;
	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);
	
	/*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);

	vec3 rwp=-earth_center.xyz;
	rwp.y=-earth_center.y+(100.0*length_unit);
	vec3 sunLightColor = GetSunIrradiance(rwp, sundirW) + moonlightcolor;

	//float sss=(/*0.1+*/pow(max(-cos,0.0),2.0));
	float sss=phase2Lobes(-cos);
	sss=(max(sss*sssMultiplier,0.0));
	
	float att=/*clamp(*/ComputeVolumetricFog(Wpos.xyz, Cam2WorldPos);//,0.0,1.0);
	float scatter=ComputeScatter( Wpos.xyz, Cam2WorldPos );//*fogColor;//*0.01;
	
//	vec3 fFex=exp(-C0*extintion*fogdist);
//	vec3 fLin=(Br+Bm)*C1*(1.0-fFex)*inScatter*fogColor;
	vec3 scatterFogColor = color.xyz;//fLin+fFex*color.xyz;
	
	vec3 shallowColor=mix(oceanShallowColor*sunLightColor,vec3(1.0,1.0,1.0),clamp(att/*att*/,0.0,1.0));
	sss=mix(sss,0.0,clamp(att,0.0,1.0));

	// compute fog Color and density	
	vec3 horizon= scatterFogColor*att*shallowColor + (oceanDeepColor*scatter + sss*oceanShallowColor)*sunLightColor;//color.xyz*att + mix( scatterFogColor,waterColor*scatter, fogdist ) * (1.0-att);
	gl_FragColor.xyz=max(horizon,0.0);
	gl_FragColor.w=1.0;
}
