
//####################################################################################################################
//####################################################################################################################
// SKY
//####################################################################################################################
//####################################################################################################################

float3 CalculateMoon(float3 wpos, float3 MoonVec, float t)
{		 
	float moon = 0.04 - dot(-MoonVec, wpos);
	moon = pow(moon, 18.0);
	moon = (moon*moon)/5.0;
	moon *= smoothstep(0.0, 0.3, -wpos.y);
	
	float3 res = moon * t * 1.7 * float3(0.086, 0.13, 0.20);  //* float3(2.0, 0.1, 0.1)
	return res;
}

#define zenithDensity(x) 0.7 / pow(max(x - 0.1, 0.35e-2), 1.1)

float3 getSkyAbsorption(float3 x, float y)
{	
	float3 absorption = x * -y;
	absorption = lerp(exp2(absorption), float3(0.569, 0.392, 0.275),  0.0);
	return absorption;
}

float3 jodieReinhardTonemap(float3 c)
{
    float l = dot(c, float3(0.2126, 0.7152, 0.0722));
    float3 tc = c / (c + 1.0);
    return lerp(c / (l + 1.0), tc, tc);
}

float GetVolumetricFog(float3 wpos)
{ 
	float3 vec1 = normalize(float3(0.0, 0.0, 1.0));
	float fog = saturate(0.95 - dot(vec1, wpos));
	fog = pow(fog, 10.0);
	return fog;	
}

float getRayleigMultiplier(float3 p, float3 lp)
{   float ray = pow(1.0 - clamp(distance(p, lp), 0.0, 1.0), 3.0) * 6.594;
	return ray;
}

float3 getSunColor(float3 sunDir)
{
	float SunsetFact = smoothstep(-0.05,0.1, sunDir.z);
/*	
	float3 sunmix = SunsetFact * pow(float3(0.9, 0.7, 0.35), 1.5 * (sin(-1.25 * sunDir.z * (3.1415927 * 0.5)) + 1.0));
	sunmix = lerp(float3(0.9, 0.3, 0.1)*float3(0.9, 0.3, 0.1)*4.0, float3(1.0, 0.85, 0.75)*1.2, saturate(sunDir.z * 2.0));
	return sunmix;
*/
	float3 SunFix = lerp(float3(1.0, 0.9, 0.8), float3(1.0, 0.8, 0.4), saturate(1.5 * (sin(-1.25 * sunDir.z * (3.1415927 * 0.5)) + 1.0)));
	return SunsetFact * pow(float3(0.8, 0.4, 0.25), 1.5 * (sin(-1.25 * sunDir.z * (3.1415927 * 0.5)) + 1.0)) * SunFix;	
}


float3 getSunColor2(float3 sunDir)
{
	float SunsetFact = smoothstep(-0.05,0.1, sunDir.z);
	float3 SunFix = lerp(float3(1.0, 0.9, 0.8), float3(1.0, 0.8, 0.4), saturate(1.5 * (sin(-1.25 * sunDir.z * (3.1415927 * 0.5)) + 1.0)));
	return SunsetFact * pow(float3(0.8, 0.4, 0.25), 2.0 * (sin(-1.25 * sunDir.z * (3.1415927 * 0.5)) + 1.0)) * SunFix;	
	
}


float getMie(float3 p, float3 lp)
{
	float disk = clamp(1.0 - pow(distance(p, lp), 0.1), 0.0, 1.0);	
	return disk*disk*(3.0 - 2.0 * disk) * 2.0 * 3.14;
}

float Lum1(in float3 color)
{
	return dot(color.rgb, float3(0.2125f, 0.7154f, 0.0721f));
}

float3 GetAtmosphericScattering(float3 wpos, float3 wpos2, float gameTime, float3 sunDir, float wx, float3 MoonVec, float night,  float n1,  float n2)
{  
	float ta = saturate(1.5 * (sin(-1.0 * sunDir.z * (3.1415927 * 0.5)) + 1.05));
	
	float3 vec1 = normalize(float3(0.0, 0.0, 1.0));	  
	float sky = saturate(0.95 - dot(vec1, wpos));
	float skyA = lerp(3.32, 2.2, saturate(ta));		
	
	sky = pow(sky, skyA);
	
	float sky2 = (1.05 - dot(vec1, wpos));
	sky2 = pow(sky2, 40.0);
/*	
	float3 t1 = lerp(float3(0.765, 0.880, 1.0), Lum1(float3(0.765, 0.880, 1.0)), 1.0 - 0.8);	
	float3 b1 = lerp(float3(0.902, 0.840, 0.706), Lum1(float3(0.902, 0.840, 0.706)), 1.0 - 0.8);
	
	float3 SkyColorTop = float3(0.62, 0.815, 1.0) * 1.0;//float3(0.600, 0.835, 1.0)	
	SkyColorTop.rgb = lerp(SkyColorTop.rgb, t1 * 0.85,  saturate(ta) * 0.6);
	float3 SkyColorBot = float3(0.770, 0.860, 0.900);//float3(0.810, 0.880, 0.900)
	SkyColorBot.rgb = lerp(SkyColorBot.rgb * 0.97, b1 * 0.75,  saturate(ta) * 0.6);	
*/

	float3 t1 = lerp(float3(0.765, 0.880, 1.0), Lum1(float3(0.765, 0.880, 1.0)), 1.0 - 0.8);	
	float3 b1 = lerp(float3(0.902, 0.840, 0.726), Lum1(float3(0.902, 0.840, 0.726)), 1.0 - 0.5);
	
	float3 SkyColorTop = float3(0.62, 0.815, 1.0) * 1.0;//float3(0.600, 0.835, 1.0)	
	SkyColorTop.rgb = lerp(SkyColorTop.rgb, SkyColorTop.rgb * 0.85,  saturate(ta) * 0.6);
	float3 SkyColorBot = float3(0.770, 0.860, 0.900);//float3(0.810, 0.880, 0.900)
	SkyColorBot.rgb = lerp(SkyColorBot.rgb * 0.97, b1 * 0.75,  saturate(ta) * 0.6);	
	
	float3 absorption = getSkyAbsorption(SkyColorTop, sky2);



	
	float vec6 = lerp(0.4, 0.4, smoothstep(0.0, 3.0, gameTime));
	vec6 = lerp(vec6, 0.4, smoothstep(3.0, 4.0, gameTime));
	vec6 = lerp(vec6, 0.5, smoothstep(4.0, 6.0, gameTime));
	vec6 = lerp(vec6, 0.6, smoothstep(6.0, 7.0, gameTime));
	vec6 = lerp(vec6, 0.8, smoothstep(8.0, 17.0, gameTime));
	vec6 = lerp(vec6, 0.6, smoothstep(18.0, 19.0, gameTime));
	vec6 = lerp(vec6, 0.45, smoothstep(19.0, 20.0, gameTime));
	vec6 = lerp(vec6, 0.4, smoothstep(20.0, 21.0, gameTime));
	vec6 = lerp(vec6, 0.4, smoothstep(22.0, 23.0, gameTime));
	vec6 = lerp(vec6, 0.4, smoothstep(23.0, 24.0, gameTime));
	
	float3 sunAbsorption = getSkyAbsorption(SkyColorTop, zenithDensity(vec6)); // sunDir.z + vec6
	float3 sAbs = sunAbsorption * 0.6 + 0.4 * length(sunAbsorption);
	float Ray = getRayleigMultiplier(wpos2, sunDir);
	float3 Moon = CalculateMoon(wpos2, MoonVec, night);

	float3 SkyColor = lerp(SkyColorTop, SkyColorBot, sky);
	SkyColor *= lerp(sky, 1.0, 0.4);
	SkyColor = pow(SkyColor, 3.5);
	SkyColor = lerp(SkyColor * absorption, SkyColor, vec6);
	SkyColor *= 17.0;
	
	float3 sunColor = getSunColor2(sunDir) * 2.3;
	sunColor.rgb = lerp(sunColor, Lum1(sunColor), 1.0 - 1.2);	
	
	float3 mie = getMie(wpos2, sunDir) * sunAbsorption;
	SkyColor *= (1.0 + Ray * 0.4 * sunColor * sunColor); //
	SkyColor += mie * 0.4 * sunColor * sunColor;
	SkyColor *= sAbs;
	
	float ti4 = lerp(0.9, 0.55, saturate(sunDir.z));
	float asky = pow(sky, 1.55);
 	float3 fnight = lerp(float3(0.2, 0.55, 1.15) * n1, float3(0.34, 0.6, 1.04) * n2, asky);

	//float3 fnight2 = lerp(float3(0.45, 0.73, 1.2) * 0.3, float3(0.45, 0.73, 1.2) * 0.29, pow(sky, 0.85));	
	//float Cloudy = lerp(1.05, 0.96, pow(sky, 0.45));
	float Cloudy = lerp(1.0, 0.4, pow(sky, 0.85));	
	// Зима	
	//float3 overcast = Cloudy * lerp(float3(0.44, 0.69, 1.13) * 1.2, float3(0.7, 0.86, 1.1) * 2.9, saturate(sunDir.z * 6.0));
	//overcast = lerp(overcast, fnight2, night);
	
	// Лето
	//float3 Pasmurno = Cloudy * lerp(float3(0.90, 0.94, 1.05)*0.5, float3(0.90, 0.94, 1.05)*2.2, saturate(night)); //saturate(sunDir.z * 6.0)
	float3 Pasmurno = Cloudy * lerp(float3(0.94, 0.96, 1.0) * 2.2, float3(0.94, 0.96, 1.0) * 0.5, saturate(night));
	Pasmurno *= float3(0.75, 0.9, 1.0);

		
	float VolFog = GetVolumetricFog(wpos.xyz);
	float3 horColor = lerp(float3(0.765, 0.400, 0.480), float3(0.800, 0.740, 0.640), saturate(sunDir.z * 2.0));
	horColor = lerp(SkyColor.rgb, horColor, ti4 * VolFog * 0.80);
	
	SkyColor.rgb = lerp(SkyColor.rgb, horColor,  saturate(ta));
	

	
    float sA = Lum1(SkyColor);
	SkyColor = lerp(sA, SkyColor, 1.05);

	SkyColor = lerp(SkyColor, fnight * 1.1, night);	
	if (wx)SkyColor = Pasmurno;

	SkyColor += Moon;
	SkyColor = jodieReinhardTonemap(SkyColor);
	
    //float sA = Lum1(SkyColor);
	//SkyColor = lerp(sA, SkyColor, 0.9);
	SkyColor *= 1.2;	
	
	return SkyColor;
}
