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

#define S(p) sin(p + iTime)
#define A(u,i) p = mod(p,4.0)-2.0, u = abs(length(p) - 2.8) + 0.01, c += (vec3(i,1.0,2.0-i) - p*0.5 + 0.06/s)/u,

void mainImage( out vec4 O, vec2 I )
{
    vec3 p, c;
    float i = 0.0;
    float t = 0.1;
    float v = 0.0;
    float w = 0.0;
    float s = 1.0;

    O = vec4(0.0);
    for (i = 0.0; i < 70.0; i += 1.0)
    {
        p = vec3(1.0, 1.0, iTime) + t * normalize(vec3(I + I, 0.0) - iResolution.xyy);
        s = 16.0 - 4.0 * (step(0.0, S(p.x)) + step(0.0, S(p.y + 1.0)) + step(0.0, S(p.z + 2.0)));
        p = round(p * s) / s;
        s = min(min(abs(S(p.x)), abs(S(p.y + 1.0))), abs(S(p.z + 2.0))) + 0.01;
        A(v, 0.0)
        A(w, 2.0)
        t += 0.3 * min(v, w);
    }

    O = vec4(tanh(c / 2e3), 1.0);
}

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