/* Creative Commons Licence Attribution-NonCommercial-ShareAlike 
   phreax 2023
*/

#define SIN(x) (.5+.5*sin(x))
#define N 6.
#define K 1.1
#define PI 3.141592 

mat2 rot(float a) {float s=sin(a), c=cos(a); return mat2(c, s, -s, c);}

// by Nusan
float curve(float t, float d) {
  t/=d;
  return mix(floor(t), floor(t)+1., pow(smoothstep(0.,1.,fract(t)), 10.));
}

vec3 pal(float t) {

    vec3 a = vec3(.6);
    vec3 b = vec3(1.);
    vec3 c = vec3(.5);
    vec3 d = vec3(0.149,0.875,0.729);

    return a + b*cos(6.283*(c*t+d));
}

// chebyshev distance
float chebd(vec2 v, float k) {
    return pow(pow(abs(v.x), k)+pow(abs(v.y), k), 1./k);
}
        
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (fragCoord*2. - iResolution.xy)/iResolution.y;
    
    vec2 uv0 = uv;
    vec2 uv2 = uv;
    
    vec2 uvb = uv;
    
    float tt = iTime*.6;

    vec3 col = vec3(0);
    for(float j = 0.; j < N; j++) {
    
        float stepf = j/N;
        float z =  fract(stepf-.05*(tt+6.*curve(tt+2., 4.))); // depth value
        z = z*z;
        float luma = smoothstep(0.2, .9, exp(-z*1.5)); // brightness with exponential decay
        luma *= smoothstep(1., .8, exp(-z*1.));
   
        float  blur = smoothstep(.1, 0.0, z); // depth of field 
            
        uv0 *= rot(PI*.25*j);
        uv = uv0*z;
        uv2 = uv0*z;
       
        for(float i=0.; i< 5.; i++) {

            uv = abs(abs(abs(abs(uv)-.1+i/2.)-.1*SIN(.1*tt+.8*curve(tt, 2.)))-.05);
            
            uv = fract(uv*1.9+uv*z)-.5;
            uv2 = fract(uv2*(1.0+.5*sin(tt*.1)))-.5;

            vec3 c = pal(1.5*SIN(3.*chebd(uv0, K)-.1*tt-4.*curve(tt, 2.)) + tt*.4 + i*.4+.4*j);

            float d = (fract(chebd(uv, K)-.5)+chebd(uv2, K)*exp(-chebd(uv0, K)));

            d = abs(d -.4*i);
            d = abs(.1*d+sin(d*8.+tt+j*.3)/8.);

            d =  smoothstep(.015+.01*blur, .0, d);
            col += d*luma*c;

        }
    }


    // Output to screen
    col *= mix(.2, 1., (1.8-pow(dot(uvb, uvb), .4))); // vignette
    fragColor = vec4(col,1.0);
}
