version 5
uniform vec3 sunDir;
uniform vec2  cc; //  cloudness,color
in vec2 tc;
out vec3 fragcolor;

const vec3 scale = vec3(3.99e-5,3.99e-5,2.99e-4);
const vec2  norm = vec2(1.0,1.4);
const float gain = 0.5;
const float lacunarity= 2.2;
const int   octaves   = 8;

float noise( in vec3 x )
{
  vec3 p = floor(x);
  vec3 f = fract(x);
	f = f*f*(3.0-2.0*f);
	vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
  vec2 rg = texture( noiseSampler, (uv+0.5)/256.0, -100.0 ).yx;
	return mix( rg.x, rg.y, f.z );
}

vec4 cloudColor(vec3 worldP)
{
 float cloudness=cc.x;
 vec3  st = worldP*scale;
 float  g = 1.0;
 float  r = 0.0;
 float icloudness=4.0-cloudness*2.0;
 for (int i = 0; i < octaves; i += 1)
 {
  st = st * lacunarity;
  r -= g * (icloudness * noise(st) - 1.0);
  g    *= gain;
 }
 vec2 v=clamp(norm*r, 0.0, 1.0);

 vec3 PP = worldP + earthPos;
 vec3 Lsun;
 vec3 Esky;
 vec3 extinction;
 sunRadianceAndSkyIrradiance(sunDir, Lsun, Esky);
 vec3 cloudL = v.x * (Lsun * max(sunDir.z, 0.0) + Esky / 10.0) / M_PI;
 vec3 inscatter = inScattering(earthPos, PP, sunDir, extinction);
 cloudL = cloudL * extinction + inscatter;
 return vec4(cloudL, v.y);
}



void main()
{
 vec2 u = tc;
 float l = dot(u, u);
 if (l <= 1.02)
 {
  if (l > 1.0)  {  l = 1.0 / l;  u = u * l;  }
  vec3 r = vec3(2.0 * u, 1.0 - l) / (1.0 + l);
  vec3 result   = skyRadiance(earthPos,length(earthPos), r, sunDir);
  vec4 cloudL   = cloudColor(r * 3000.0 / r.z);
  fragcolor.rgb = cloudL.rgb * cloudL.a + result.rgb * (1.0 - cloudL.a);
 }
 else fragcolor.rgb = 0.17 * skyIrradiance(sunDir.z) / 3.14159;
 fragcolor.rgb *= cc.y;
}
