uniform sampler2D texture;
uniform float time;

varying vec2 uv;

//Percent from the center to the edge where the dust should stop
const float innerRad = 0.05;
const float outerFade = 0.8;

//How many different speeds the dust should move at
const float steps = 36.0;
//How fast it spins overall
const float dustSpeed = 0.008;
//Rate of speed increase, should be an integer
const float dustSpeedCurve = 3.0;

//Fixed curve in the dust, should be an integer
const float fixedSpiral = 3.0;

//Texture mapping settings to avoid peroidic patterns
const float texRepeat = 6.0;
const float stepOffset = 0.2;

//Temperature stepping as dust approaches the horizon
const float kPerStep = 0.25;
const float tempCurve = 3.35;

//Temp above which the light is artificially brightened
const float hotTemp = 13000.0;
//Temp below which the light is artificially darkened
const float coolTemp = 2200.0;

const float twopi = 6.28318530718;

float mixRange(float x, float low, float hi) {
	return clamp((x - low) / (hi - low), 0.0, 1.0);
}

vec3 blackBody(float temp) {
	vec3 c;
	c.r = mix(1.0, 0.6234, mixRange(temp, 6400.0, 29800.0));
	c.b = mix(0.0, 1.0, mixRange(temp, 2800.0, 7600.0));
	if(temp < 6600.0)
		c.g = mix(0.22, 0.976, mixRange(temp, 1000.0, 6600.0));
	else
		c.g = mix(0.976, 0.75, mixRange(temp, 6600.0, 29800.0));
	if(temp < coolTemp)
		c *= temp / coolTemp;
	else if(temp > hotTemp)
		c *= (temp / hotTemp);
	return c;
}

//Blends a number of rotating sections together
//Sections rotate at integer multiples of the slowest speed to avoid animation hitching
void main() {
	vec2 p = (uv - vec2(0.5)) * 2.0;
	float d = length(p);
	if(d > 1.0 || d <= innerRad)
		discard;
	d = 1.0 - ((d - innerRad) / (1.0 - innerRad));
	float a = atan(p.y,p.x);
	
	//Whatever curve the second smoothstep makes, it works
	gl_FragColor.a = smoothstep(0.0,outerFade,d) * smoothstep(d,1.0,0.995);
	
	float step = d * steps + 0.5;
	
	float lowStep = floor(step);
	float hiStep = ceil(step);
	float lowPct = (hiStep - step);
	float hiPct = 1.0 - lowPct;
	
	vec3 col = vec3(0.0);
	vec3 bbCol = blackBody(kPerStep * pow(step, tempCurve));
	
	{
		vec2 st = vec2((a / twopi) - time * pow(lowStep, dustSpeedCurve) * dustSpeed + lowStep * stepOffset, (d - time * 4.0) * texRepeat);
		
		st.y -= fixedSpiral * (a/twopi);
		col += bbCol * (texture2D(texture, st).r * lowPct);
	}
	
	{
		vec2 st = vec2((a / twopi) - time * pow(hiStep, dustSpeedCurve) * dustSpeed + hiStep * stepOffset, (d - time * 4.0) * texRepeat);
		
		st.y -= fixedSpiral * (a/twopi);
		col += bbCol * (texture2D(texture, st).r * hiPct);
	}
	
	gl_FragColor.rgb = col;
}
