#version 330 core

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

out vec4 FragColor;

// DarkTransit - low tech tunnel adaptation

#define T        (iTime*4.0 + 5.0 + 5.0*sin(iTime*0.3))
#define P(z)     vec3(12.0 * cos((z)*vec2(0.1,0.12)), (z))
#define A(F,H,K) abs(dot(sin(F*p*K), H + p - p)) / K

void mainImage(out vec4 o, in vec2 u) {
    float t=0.0,s=0.0,i=0.0,d=0.0,e=0.0;
    vec3 c = vec3(0.0);
    vec3 r = iResolution;

    u = (u - r.xy/2.0) / r.y;
    if (abs(u.y) > 0.375) { o = vec4(0.0); return; }

    vec3 p = P(T);
    vec3 Z = normalize(P(T+4.0) - p);
    vec3 X = normalize(vec3(Z.z, 0.0, -Z.x));
    vec3 D = vec3(u, 1.0) * mat3(-X, cross(X, Z), Z);

    for(; i++ < 28.0 && d < 30.0; c += 1.0/s + 10.0*vec3(1.0,2.0,5.0)/max(e, 0.6)) {
        p += D * s;
        X = P(p.z);
        t = sin(iTime);
        e = length(p - vec3(X.x + t, X.y + t*2.0, 6.0 + T + t*2.0)) - 0.01;
        s = cos(p.z*0.6)*2.0 + 4.0
            - min(length(p.xy - X.x - 6.0), length((p-X).xy))
            + A(4.0, 0.25, 0.1)
            + A(T+8.0, 0.22, 2.0);
        d += s = min(e, 0.01 + 0.3*abs(s));
    }

    o.rgb = c*c/1e6;
    o.a = 1.0;
}

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