#define PI     3.14159265358
#define TWO_PI 6.28318530718;
// #define FADES  1

float saw(float rads) {
    rads += PI * 0.5; // sync oscillation up with sin()
    float percent = mod(rads, PI) / PI;				
    float dir = sign(sin(rads));
    return dir * (2. * percent  - 1.);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // set time & centered position
    float time = 10. + iTime * 0.5;
    vec2 uv = (2. * fragCoord.xy - iResolution.xy) / iResolution.y;
	// calc additive distance from control points
    float dist = 0.;
    for(int ii = 1; ii < 5; ii++) {
        float i = float(ii);
        float rads = 1.75 * sin(time / 1./i);	// oscillate control point radius
        float ctrlX = sin(sin(uv.x / time) + sin(uv.y + time * i) + cos(time + time) * sin(time * i));
        float ctrlY = sin(sin(uv.y + time) + sin(uv.x + time / i) + cos(time + time) * cos(time * i));
        vec2 ctrlPoint = rads + vec2(ctrlX, ctrlY);
      	dist += (10. + 7. * sin(time * 0.5)) * distance(uv, ctrlPoint);
    }
    // oscillate color components by distance factor. smoothstep for contrast boost
    vec3 col = vec3(
        smoothstep(0.1, 0.8, abs(sin(time + dist * 0.11)) * 0.5 + 0.2),
        smoothstep(0.1, 0.8, abs(cos(time + dist * 0.22)) * 0.37 + 0.4),
        smoothstep(0.1, 0.8, abs(sin(time + dist * 0.33)) * 0.15 + 0.4)
    );
	// vignette outside of center
    float vignetteInner = 0.75;
    float vignetteDarkness = 0.4;
    col -= smoothstep(0., 0.7, max(0., length(uv) - vignetteInner) * vignetteDarkness);
    // fade in/out
    #ifdef FADES
        float loopSecs = 4.;
        float fadeTime = 1.;
        if(abs(mod(time, loopSecs)) < fadeTime * 2.) {		// fade in/out for looping purposes
            col = mix(vec3(1.), col, abs(-fadeTime + mod(time, loopSecs)));	
        }
    #endif

    fragColor = vec4(col, 1.0);
}
