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

   Elaboration of by previous experiment https://www.shadertoy.com/view/wlV3zy

   Introducing more kaleidoscopic shapes as attractor for the basic kifs pattern.
   The attractor idea goes to evvvvil - it's very interesting method to shape your kifs.
*/

#define PI 3.141592
#define TAU 2.*PI
#define hue(v) ( .6 + .6 * cos( 6.3*(v) + vec3(0,23,21) ) )
#define rot(a) mat2(cos(a), sin(a), -sin(a), cos(a))
#define COUNT 100.
#define N 10.
#define DISTORT .6
#define SQR(x) ((x)*(x))
#define SIN(x) sin(x)*.5+.5

float tt;

float flower(vec2 uv) {
    float n = 3.;
    float a = atan(uv.y,uv.x);

    float d = length( uv) - cos(a*n);
    return smoothstep(fwidth(d)+.01, -.07, abs(d+.2));    
}


// from "Palettes" by iq. https://shadertoy.com/view/ll2GD3
vec3 pal( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d )
{
    return a + b*cos( 6.28318*(c*t+d) );
}

vec3 getPal(int id, float t) {

    id = id % 7;

    vec3          col = pal( t, vec3(.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(1.0,1.0,1.0),vec3(0.0,-0.33,0.33) );
    if( id == 1 ) col = pal( t, vec3(0.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(1.0,1.0,1.0),vec3(0.0,0.10,0.20) );
    if( id == 2 ) col = pal( t, vec3(0.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(1.0,1.0,1.0),vec3(0.3,0.20,0.20) );
    if( id == 3 ) col = pal( t, vec3(0.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(1.0,1.0,0.5),vec3(0.8,0.90,0.30) );
    if( id == 4 ) col = pal( t, vec3(0.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(1.0,0.7,0.4),vec3(0.0,0.15,0.20) );
    if( id == 5 ) col = pal( t, vec3(0.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(2.0,1.0,0.0),vec3(0.5,0.20,0.25) );
    if( id == 6 ) col = pal( t, vec3(0.8,0.5,0.4),vec3(0.2,0.4,0.2),vec3(2.0,1.0,1.0),vec3(0.0,0.25,0.25) );
    
    return col;
}



float entity(vec2 uv) {
    
	uv *= mix(.1, .7, smoothstep(0., 14., tt));       // transition effect in the beginning
 	uv = mix(fract(uv*.25-.5)-.5, uv, smoothstep(14., 14., tt));
    
    uv *= rot(PI/2.);
    
    vec2 bp = uv;
    
    uv = abs(uv)-.2;
        
    uv *= rot(-0.5*tt);
    uv = abs(uv-.2*SIN(tt))-.2;
    uv *= rot(0.93*tt);
    
    uv += smoothstep(0., 1.5, bp.x);

    
    float r = length(uv);
    float a = atan(uv.y,uv.x);

    float f = cos(a*4.);
    
    return smoothstep(f, (f+.1), r); 
}

vec2 kalei(vec2 uv) { 
    vec2 bp = uv;

    float n = N;
    float r = TAU/n;
    
    float at = entity(uv);
    for(float i=0.; i<n; i++) {     
    	uv = abs(uv);
        uv.x -= (.2*i*at)+.2;
    	uv *= rot(r*i-.2*tt-.1*at);
    }

    uv = abs(uv) - (sin(.15*tt)+1.2);
    
    return uv;
}


vec3 spiral(vec2 uv, float i) {  
    uv *= rot(i*PI+tt*.3);
    uv += DISTORT*sin(5.*uv.yx);
	return flower(uv)*SQR(getPal(0, i+tt*.2));
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	vec2 uv = (fragCoord-.5*iResolution.xy)/iResolution.y;
    vec3 col = vec3(0);
    
    uv *= rot(-.5*PI);
    tt = .3*iTime;
    if(iTime < 20.) tt = .7*iTime;
    else tt = (.7*20.) + (iTime-20.)*.4;
    
    uv = kalei(uv*5.);

    float s = 1./COUNT;
	
    for(float i=0.; i<1.; i+=s) {   
        float z = fract(i-.1*tt);
        float fade = smoothstep(0., .2, 1.-abs(2.*z-1.));
        col += spiral(uv*z, i)*fade;
    }

    
    col = sqrt(col);
    fragColor = vec4(col,1.);
}
