// Code by Flopine

// Thanks to wsmind, leon, XT95, lsdlive, lamogui, 
// Coyhot, Alkama,YX, NuSan, slerpy, wwrighter 
// BigWings, FabriceNeyret and Blackle for teaching me

// Thanks LJ for giving me the spark :3

// Thanks to the Cookie Collective, which build a cozy and safe environment for me 
// and other to sprout :)  
// https://twitter.com/CookieDemoparty


#define PI acos(-1.)
#define TAU (2.*PI)

#define rot(a) mat2(cos(a),sin(a),-sin(a),cos(a))

#define noise(u) textureLod(iChannel0, u, 0.).x
#define crep(p,c,l) p-=c*clamp(round(p/c), -l, l)

#define BPM (140./60.)
#define anim(st, sp, of, po) (TAU/st)*(floor((iTime+of)*sp),pow(fract((iTime+of)*sp), po))

float box (vec3 p, vec3 c)
{
    vec3 q=abs(p)-c;
    return min(0., max(q.x,max(q.y,q.z)))+length(max(q,0.));
}

float sc (vec3 p, float d)
{
    p = abs(p);
    p=max(p,p.yzx);
    return min(p.x,min(p.y,p.z))-d;
}

float g1 = 0.;
float prim1 (vec3 p, float o)
{
    float speed = BPM/4.;
    p.xz *= rot(anim(4., speed, o, 20.));
    p.xy *= rot(anim(4., speed, .5+o , 20.));
    
    float d = max(-sc(p,.5),box(p,vec3(.8)));
    
    float s = length(p)-.5;
    g1 += 0.01/(0.01+s*s);
    
    return min(d, s);
}

float SDF (vec3 p)
{
    p.yz *= rot(-atan(1./sqrt(2.)));
    p.xz *= rot(PI/4.);
    
    float per = 2.5;
    vec3 id = round(p/per);
    crep(p, per, 2.4);
    
    float shape = (noise(id*.27+sin(iTime*.25)*.1+.15) < .5) ? prim1(p, length(id*.1)) : box(p,vec3(1.));
   
    return shape;
}

vec3 gn (vec3 p)
{
    vec2 eps = vec2(0.001, 0.);
    return normalize(SDF(p)-vec3(SDF(p-eps.xyy),SDF(p-eps.yxy),SDF(p-eps.yyx)));
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (2.*fragCoord-iResolution.xy)/iResolution.y;
    
    vec3 ro = vec3(uv*4.8, -20.), rd=vec3(0.,0.,1.), p=ro,
    col=vec3(0.), l=normalize(vec3(1.5, 2., -1.));

    bool hit = false;
    for(float i=0.; i<64.; i++)
    {
        float d = SDF(p);
        if (d<0.01)
        {
            hit=true; break;
        }
        p += d*rd*.8;
    }

    if (hit)
    {
        vec3 n = gn(p);
        float li = max(dot(n,l), 0.);
        
        col = mix(vec3(0.85, .3, .01),  vec3(1., .9, .5),li);
    }
    col += g1*.15;
    
    fragColor = vec4(sqrt(col),1.0);
}
