
vec3 hueToRGB(float hue)
{
    // https://www.shadertoy.com/view/ll2cDc

	return vec3(.5 + .5 * clamp( 1.3*cos(-0.3 + 6.28 * hue + vec3(0,0.66666*6.28, 0.3333*6.28)), -1.0, 1.0));
//I treat (hue+1.0) to be proportional to wavelength
//approximate colors
//red is hue = 0.05
//green is 0.38
//blue is 0.71

}

float PHI = 1.61803398874989484820459;  // F = Golden Ratio   

float gold_noise(in vec2 xy, in float seed){
       return fract(tan(distance(xy*PHI, xy)*seed*333.0)*xy.x);
}


float dopplerShift(float hue, float factor){
	float freq = 1.0/(hue+1.0); 
	//hue=1/freq-1
	float freqDoppl = freq*factor;
	float hueDoppl = 1.0/freqDoppl - 1.0;
	return hueDoppl;
}


vec3 wideSpectrum(float hue,in vec2 xy, in float seed) {
	if (hue<0.0) {
		vec3 red = hueToRGB(0.0);
	    float noise = (-hue)*gold_noise(xy, seed);
		
		return red-noise*red;
    }
	if (hue>0.8) {
		vec3 violet =  hueToRGB(0.8)*exp(-(hue-0.8));
		vec3 antiViolet = 1.0 - violet;
		float noise = (1.0-exp(0.16*0.8-0.16*hue))*gold_noise(xy, seed);
		return violet+noise*antiViolet;
    }


	return hueToRGB(hue);
}

vec3 wideSpectrum2(float hue, in vec2 xy, in float seed) {
	if (hue<0.0) {
		vec3 red = hueToRGB(0.0);
	    float noise = (-hue)*gold_noise(xy, seed);
		
		return red-noise*red;
    }
	if (hue>0.8) {
		vec3 violet =  hueToRGB(0.8);
		vec3 antiViolet = 1.0 - violet;
		float noise = gold_noise(xy, seed);
		return violet+(exp(-0.3*noise)*(1.0-exp(-0.2*(hue-0.8))) )*antiViolet;
        
    }


	return hueToRGB(hue);
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    //frequency scan [-1e5, 1e5]
    //vec3 col = wideSpectrum( exp(10.0*uv.x-5.0)-1.0, uv.xy, iTime );
    //wavelength scan [0, 9]
    //vec3 col = wideSpectrum( 10.0*uv.x-1.0, uv.xy, iTime );
    
    //doppler factor [1/50, 50] vs wavelength 
    vec3 col = wideSpectrum( dopplerShift(10.0*uv.x-1.0, exp(4.*(uv.y-0.5)) ), uv.xy, iTime );
    
    //vec3 col = wideSpectrum( dopplerShift(exp(10.0*uv.x-5.0)-1.0, exp(4.*(uv.y-0.5)) ), uv.xy, iTime );
    

    // Output to screen
    fragColor = vec4(col,1.0);
}
