#version 330 core

uniform vec3 iResolution;
uniform float iTime;
uniform float uAlpha;

out vec4 FragColor;

#define P p.xz = vec2(length(p.xz), length(p.xz) * (mod(atan(p.z, p.x), 0.628) - 0.314));
#define L length(p.yz)

vec4 tanh4(vec4 x)
{
    vec4 e = exp(clamp(2.0 * x, vec4(-20.0), vec4(20.0)));
    return (e - vec4(1.0)) / (e + vec4(1.0));
}

void mainImage(out vec4 O, in vec2 I)
{
    float t = 0.0;
    float v = 0.0;
    float i = 0.0;
    float j = 0.0;
    float T = iTime;

    O = vec4(0.0);

    for (; i++ < 60.0;)
    {
        vec3 p = t * normalize(vec3(1.0, I + I) - iResolution.yxy);
        p.y += 13.0;
        p = reflect(p, normalize(sin(T * 0.1 + vec3(0.0, 2.0, 4.0))));
        p += sin(p * 12.0) / 6.0;
        P
        p.y = mod(p.y, 12.0) - 6.0;
        v = max(L, 0.001);

        for (j = 0.0; j++ < 3.0;)
        {
            p = p.zxy;
            P
            p.y = mod(p.y + T + t * 0.2, 6.0) - 3.0;
            v = min(v, max(L, 0.001));
        }

        t += v * 0.3;
        O += vec4(1.0, 2.0, 3.0, 0.0) * exp(sin(t + vec4(0.0, 2.0, 4.0, 0.0))) / v;
    }

    O = tanh4(O / 1000.0);
    O.a = 1.0;
}

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