#version 330 core
out vec4 FragColor;

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

void mainImage(out vec4 O, vec2 I)
{
    float i = 0.0;
    float t = 0.0;
    float v = 1.0;
    float s = 1.0;
    float j = 0.0;

    O = vec4(0.0);

    for (; i++ < 60.0; t += v * 0.2)
    {
        vec3 q;
        vec3 p = t * normalize(vec3(I + I, 0.0) - iResolution.xyy);

        p.z += 6.0;
        q = p = reflect(p, normalize(sin(iTime * 0.2 + vec3(0.0, 1.0, 2.0))));
        p += sin(p * 4.0 + iTime) / 4.0;
        p = round(p * 8.0) / 8.0;
        p = (p.x < p.z ? p.zyx : p);

        s = 1.0;
        for (j = 0.0; j++ < 15.0;)
        {
            p *= 1.4;
            s *= 1.4;
            p = (p.y > p.z ? p.xzy : p);
            p.y += 3.0;
            p.xz = vec2(p.z, -p.x);
        }

        v = max(length(p) / s, 0.0001);
        O += exp(sin(length(q) + vec4(0.0, 1.0, 2.0, 0.0))) / v;
    }

    O = tanh(O / 5e2);
    O *= O;
    O.a *= uAlpha;
}

void main()
{
    mainImage(FragColor, gl_FragCoord.xy);
}
