
layout (std140) uniform AtmosphereModel {
	vec4  SunColor;
	vec3  SunPosition;
	vec3  SunDirection;
	vec3  EyePosition;
	vec3  BetaRay;
	vec3  BetaRayTheta;
	vec3  BetaMie;
	vec3  BetaMieTheta;
	float DirectionalityFactor;
};

/*
vec3 desaturateNightView(in vec3 color, in float desat)
{
	float lum = dot(color, vec3(0.299, 0.587, 0.114));
	return mix(color,  color*vec3(0.2, 0.5, 1.0), desat);
}
*/

vec3 calcBetaR(in float theta)
{
	return BetaRayTheta * (2.0 + 0.5*theta*theta);
}


vec3 calcBetaM(in float theta)
{
	float g = DirectionalityFactor;

	return (BetaMieTheta * pow(1.0f - g, 2.0f)) / (pow(1.0 + g*g - 2.0*g*theta, 1.5));
}


vec3 calcI(in float theta)
{
	return ( calcBetaR(theta) + calcBetaM(theta) ) / (BetaRay + BetaMie);
}


vec3 calcE(in float Theta, in float sr, in float sm)
{
	return exp( -(BetaRay*sr + BetaMie*sm) );
}


vec3 calcLin(in float theta, in float sr, in float sm)
{
	return ( (calcBetaR(theta) + calcBetaM(theta)) * (1.0 - exp(-(BetaRay*sr + BetaMie*sm)) ) ) / (BetaRay + BetaMie);
}


void calculateGroundAtmosphere(in vec3 position, in vec3 normal, out vec4 extinction, out vec3 inscatter)
{
	vec3 v = position - EyePosition;
	float dist = length(v);
	v = normalize(v);

	float theta = dot(v, SunDirection);

	float sr = dist*0.005;
	float sm = dist*0.05;

	extinction.rgb = calcE(theta, sr, sm);
	extinction.a = max(dot(normal, SunDirection), 0.0);

	inscatter = (vec3(1.0) - extinction.rgb) * calcI(theta) * SunColor.rgb * SunColor.w;
}


void calculateGroundAtmosphereDualSided(in vec3 position, in vec3 normal, out vec4 extinction, out vec3 inscatter)
{
	vec3 v = position - EyePosition;
	float dist = length(v);
	v = normalize(v);

	float theta = dot(v, SunDirection);

	float sr = dist*0.005;
	float sm = dist*0.05;

	extinction.rgb = calcE(theta, sr, sm);
	extinction.a = abs(dot(normal, SunDirection));

	inscatter = (vec3(1.0) - extinction.rgb) * calcI(theta) * SunColor.rgb * SunColor.w;
}


void lightGroundAtmosphere(inout vec4 color, in vec4 extinction, in vec3 inscatter)
{
	color.rgb = color.rgb*SunColor.rgb*extinction.w; // + color.rgb*0.1;
	color.rgb = color.rgb*extinction.rgb + inscatter;
	color.a = 1.0;
}


void calculateCloudAtmosphere(in vec3 position, in vec3 normal, out vec4 extinction, out vec3 inscatter)
{
	vec3 v = position - EyePosition;
	float dist = length(v);
	v = normalize(v);

	float theta = dot(v, SunDirection);

	float sr = dist*0.005;
	float sm = dist*0.3;

	extinction.rgb = calcE(theta, sr, sm);
	extinction.a = max(dot(normal, SunDirection), 0.0);

	inscatter = (vec3(1.0) - extinction.rgb) * calcI(theta) * SunColor.rgb * SunColor.w;
}


void lightCloudAtmosphere(inout vec4 color, in vec4 extinction, in vec3 inscatter)
{
	color.rgb = color.rgb*extinction.rgb + inscatter;
	//color.a = 1.0;
}


void calculateSkydomeAtmosphere(in vec3 position, out vec4 diffuse)
{
	float dist = length(position);
	vec3 v = normalize(position);
	float theta = dot(v, SunDirection);
	float sr = (1.05 - pow(v.y, 0.3))*1000.0;
	float sm = dist*0.05;
	vec3 l = calcLin(theta, sr, sm);
	
	diffuse.xyz = l*SunColor.xyz*SunColor.w;
	diffuse.w = 1.0;
}
