#version 330 core

in vec2 vUV;
out vec4 FragColor;

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

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    float time = (iTime + 29.0) * 60.0;

    float s = 0.0;
    float v = 0.0;
    vec2 uv = (-iResolution.xy + 2.0 * fragCoord) / iResolution.y;

    float t = time * 0.005;

    float rdist = length(uv);
    uv *= 1.0 + rdist * rdist * 0.08;

    uv.x += sin(t) * 0.30;
    uv.y += cos(t * 0.7) * 0.08;

    float si = sin(t * 1.5);
    float co = cos(t);
    uv *= mat2(co, si, -si, co);

    vec3 col = vec3(0.0);
    vec3 init = vec3(
        0.25 + sin(t * 0.37) * 0.08,
        0.25 + sin(time * 0.001) * 0.12,
        time * 0.0008
    );

    for (int r = 0; r < 110; r++)
    {
        vec3 p = init + s * vec3(uv, 0.143);

        p.z = mod(p.z, 2.0);

        for (int i = 0; i < 10; i++)
        {
            p = abs(p * 2.04) / max(dot(p, p), 0.001) - 0.75;
            p.xy *= mat2(cos(0.025), sin(0.025), -sin(0.025), cos(0.025));
        }

        float sparkle = pow(max(0.0, 1.0 - length(p) * 0.18), 6.0);
        float density = length(p * p);

        v += density * smoothstep(0.0, 0.5, 0.9 - s) * 0.002;

        vec3 nebula = vec3(
            v * 1.15 + sparkle * 1.4,
            1.05 - s * 0.45 + sparkle * 0.45,
            0.75 + v * 0.65 + sparkle
        );

        float pulse = 0.75 + 0.25 * sin(t * 6.0 + s * 18.0);
        col += nebula * v * 0.014 * pulse;

        s += 0.0095;
    }

    float centerGlow = exp(-length(uv) * 2.2);
    vec3 core = vec3(0.15, 0.55, 1.0) * centerGlow * 0.35;

    vec2 guv = uv;
    float rays = pow(abs(sin(atan(guv.y, guv.x) * 18.0 + t * 4.0)), 18.0);
    rays *= exp(-length(uv) * 3.0);

    col += core;
    col += vec3(0.3, 0.8, 1.4) * rays * 0.12;

    col = pow(col, vec3(0.78));
    col *= 1.15;

    fragColor = vec4(col, 1.0);
}

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