#version 330 core

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

out vec4 FragColor;

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 u = fragCoord.xy;

    float i = 0.0;
    float a = 0.0;
    float d = 0.0;
    float s = 0.0;
    float t = iTime + 10.0;
    float r = 0.0;

    vec3 p = iResolution;
    u = (u + u - p.xy) / p.y;

    vec4 o = vec4(0.0);

    for (i = 0.0; i++ < 150.0; ) {
        s = 0.004 + abs(s) * 0.20;
        d += s;

        o += s * d;
        o.r += (d * 1.5 - 5.0 / s) * 0.2;
        o.b += sin(d * 0.09 + p.z * 0.3) * 1.0 / s;
        o.g += sin(d * 0.2) * 1.0 / s;

        p = vec3(u * d, d + t * 3.0);
        p.x = abs(p.x);
        s = min(p.z, 1.75 + sin(p.z) * 0.15);

        for (a = 0.8; a < 3.0; a += a) {
            p += cos(t - p.yzx * 0.9) * 0.3;

            r = p.z * 0.025 + sin(t * 0.03);

            mat2 rot = mat2(cos(r), -sin(r), sin(r), cos(r));
            p.xy *= rot;
            s += abs(sin(p.x * a)) * (1.2 + sin(t * 0.1) * 0.25) * -abs(sin(abs(p.y) * a) / a);
        }
    }

    o = pow(tanh(o * o / 1e8 * length(u)), vec4(1.0 / 2.2));
    o *= o;

    fragColor = o;
}

void main()
{

    vec4 col = vec4(0.0);
    mainImage(col, gl_FragCoord.xy);
    col.a = max(uAlpha, 1.0);
    FragColor = col;

}
