#version 330 core

in vec2 uv;
out vec4 FragColor;

uniform vec3 iResolution;
uniform float iTime;
uniform float uAlpha;
uniform float uStartDelay;
uniform sampler2D iChannel0;

#define R 16.0

float rand(float co)
{
    return fract(sin(co * 91.3458) * 47453.5453);
}

float rand(vec2 co)
{
    return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
}

float rand(vec3 co)
{
    return rand(co.xy + rand(co.z));
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 sourceUv = fragCoord / iResolution.xy;
    vec2 centeredUv = (fragCoord - vec2(0.5) * iResolution.xy) / iResolution.y + vec2(0.5);

    vec3 col = vec3(0.0);
    float total = 0.0;

    for (float dx = -R; dx <= R; dx += 1.0)
    {
        for (float dy = -R; dy <= R; dy += 1.0)
        {
            vec3 v = vec3(dx, dy, 1.0);
            if (length(v.xy) > R)
                continue;

            float weight = 1.0 / dot(v, v);
            total += weight;
            col += texture(iChannel0, sourceUv + v.xy / iResolution.y).rgb * weight;
        }
    }

    col /= total;
    col = (col - 0.5) * 5.0 + 0.5;
    col += rand(vec3(sourceUv, iTime)) * 2.0 - 1.0;
    col *= 1.0 - 0.5 * pow(length(centeredUv - vec2(0.5)), 2.0);
    col = vec3(round((col.x + col.y + col.z) / 3.0));

    fragColor = vec4(col, 1.0);
}

void main()
{
    float t = iTime - uStartDelay;
    if (t < 0.0)
        discard;

    mainImage(FragColor, uv * iResolution.xy);
    FragColor.a *= uAlpha;
}
