// Code by Flopine

// Thanks to wsmind, leon, XT95, lsdlive, lamogui,
// Coyhot, Alkama,YX, NuSan, slerpy, wwrighter
// BigWings and FabriceNeyret 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 6.283185

#define time iTime
#define dt(sp,off) fract((time+off)*sp)

#define rot(a) mat2(cos(a),sin(a),-sin(a),cos(a))
#define crep(p,c,l) p=p-c*clamp(round(p/c),-l,l)
#define hash11(x) fract(sin(x)*1455.2)
#define hash21(x) fract(sin(dot(x,vec2(12.5,23.4)))*124.2)

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 od (vec3 p, float d)
{return dot(p,normalize(sign(p)))-d;}

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

float cyl (vec3 p, float r, float h)
{return max(length(p.xy)-r,abs(p.z)-h);}

float g1=0.; vec2 starid;
float SDF (vec3 p)
{
    p.yz *= rot(-atan(1./sqrt(2.)));
    p.xz *= rot(PI/4.);

    vec3 pp = p;
    float per = 4.;
    vec2 id = floor(p.xz/per);
    p.xz = mod(p.xz,per)-per*.5;
    p.xz *= rot(dt(0.5,id.y)*TAU);
    p.xy *= rot(dt(0.3,id.x)*TAU);

    p.x -= 1.;
    float s = mix(od(p,0.25),box(p,vec3(0.4)),0.5);
    g1 += 0.1/(0.1+s*s);

    p=pp;
    starid = round(p.xz/per);
    crep(p.xz,per,4.);
    float scene = max(-box(p,vec3(0.85)),mix(od(p,0.8),sc(p,0.4),0.7));

    return min(scene,s);
}

vec3 getnorm (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.xy-iResolution.xy)/iResolution.y;
    float dither = hash21(uv);

    vec3 ro = vec3(uv*7.,-50.),
    rd=vec3(0.,0.,1.),
    p=ro,
    col=vec3(0.99),
    l=normalize(vec3(1.,2.,-3.));

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

    if (hit)
    {
        vec3 n = getnorm(p);
        float light = max(0.,dot(n,l));
        float colid = length(starid);
        col = (mod(colid,2.)<=0.) ?
              mix(vec3(0.5,0.,0.6),vec3(0.1,0.95,0.99),light):
              mix(vec3(0.05,0.7,hash11(colid)*0.4),vec3(.8,1.,hash11(colid)),light);

    }
    col -= g1*.08;
    col = clamp(col,0.,1.);
    fragColor = vec4(sqrt(col),1.);
}
