#version 330 core
out vec4 FragColor;
in vec2 vUV;
uniform vec3 iResolution;
uniform float iTime;
uniform float uAlpha;

#define T (sin(iTime*.4)/2.+iTime)
#define P(z) (vec3(cos((z)*.02)*64., cos((z)*.015)*32., (-z)))
#define R(a) mat2(cos(a + vec4(0,33,11,0)))
#define N normalize


float box (vec3 p, float i){
    p = i*.41 - abs(fract(p/i)*i - i/2.);
    return min(p.x, min(p.y, p.z));
}

float boxen(vec3 p) {
    float d = -9e9, i = 1e2;
    p *= 5e1;
    for(; i > .1; i *= .3)
        p.xz *= R((i < 50. ? i : 1.)),
        p.yz *= R((i < 20. ? i*i : 1.)),
        d = max(d, box(p, i));
    return d/5e1;
}

float map(vec3 p) {
    return max(1e1-length(p), max(boxen(p), 1e2*boxen(p.yxz/1e2)));
}

void mainImage(out vec4 o, vec2 u) {
    float s, i;

    vec3 r= iResolution;
    u = (u+u - r.xy) / r.y;
    if(abs(u.x) > 1.4) { o *= i; return; }
    
    
    vec3  p = P(T*6e1),
          Z = N(P(T*6e1 + 2e1) - p),
          X = N(vec3(Z.z, 0, -Z)),
          D = N(vec3(R(tanh(sin(p.z*.01)*4.)*6.) * u, 1) * mat3(-X, cross(X, Z), Z));
    vec2 v = 2e2*(.1*sin(T/1.5))+u + (u.yx*.8+.2-vec2(-1.,.1));
    for(o *= i; i++ < 64.; )
        p += D * s,
        s = map(p) * .8,
        o += s/i
          + .2*(vec4(clamp(v.x,1.,4.),1,2,0))*s,
          +  vec4(4,2,1,0)/ length(v);
        
    vec4 lights = abs(vec4(8,1,1,0) / dot(cos(iTime*3.+p/4e1),vec3(1e1)));
    o += lights;

    o = tanh(o / 1e2 * length(v-u)/3e1);
}

void main() {
    vec2 fragCoord = vUV * iResolution.xy;
    mainImage(FragColor, fragCoord);
    FragColor.a *= uAlpha;
}