#version 330 core
out vec4 FragColor;
in vec2 vUV;
uniform vec3 iResolution;
uniform float iTime;

// NOP slide adapted

void mainImage(out vec4 o, vec2 u) {
    float i = 0.0;
    float d = 0.0;
    float s = 0.0;
    float n = 0.0;
    float t = -iTime;
    vec3 p;
    vec3 r = iResolution;
    u = (u - r.xy/2.0) / r.y;

    // make cinema bars at top and bottom
    //if (abs(u.y) > 0.4) { o = vec4(0.0); return; }

    // initialize accumulator
    o = vec4(0.0);

    // clear o, 100 steps, accumulate distance, accumulate brightness
    for(o *= i; i++ < 1e2; d += s = (.006 + abs(s) * .8), o += 1.0 / s)
        // march and move forward
        for (p = vec3(u * d, d - t * 4.0),
             // twist (p.z) and spin (t)
             p.xy *= mat2(cos(.3 * t + p.z * .08 + vec4(0,33,11,0))),
             // sin/cos waves to make some geometry
             // remove the above rotation to see what it
             // looks like not twisted
             s = max(abs(sin(t + p.y * .3)) - 1.0, cos(p.x)),
             // noise starts at 2., up to 8., grow by n
             n = 2.0; n < 8.0; n += n)
                 // apply rounded noise, the rounding creates
                 // the large pixel effect
                 s -= abs(dot(.25 * round(sin(p * n)), vec3(1.0))) / n;
    // tanh tone map, green color, and divide down brightness
    o = tanh(vec4(2.0, 7.0, 1.0, 1.0) * o * o / 3e7);
}

void main() { mainImage(FragColor, vUV * iResolution.xy); FragColor.a *= 1.0; }