#define SIDEMUL 1.2
#define BOUNCE  0.4
#define NOF_BALLS 22.
#define COLOR 1

float sidePos(float t, float mul) {
    t = mod(t,2.0)-0.5;
    if (t > 0.5) t=1.0-t;
    return t * mul;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 ouv = (fragCoord/iResolution.xy) * 2.0 - 1.0;
    float time = (iTime+NOF_BALLS) * 0.55;

    vec3 col = vec3(0.05,0.04,0.09);
    for (float i = NOF_BALLS; i >= 1.; i--) {
        vec2 uv=ouv;
        float j=i*15./NOF_BALLS;
        float sz=j*0.009+0.01;
        float szm = (2.-sz)*(2.-sz);
        float st = time*0.3*(1.5-j/14.)+0.5+j*8.;
        uv.x -= sidePos(st, SIDEMUL * (1.6-sz));
        uv.y -= sin(mod(time*4.0*(0.7+j/50.)+j,3.14))*BOUNCE*(szm*(abs(sin(j/2.3)*0.7)+0.5))-(1.-sz);
        uv.x *= iResolution.x / iResolution.y;

        float dist = sqrt(sz-(dot(uv,uv)));
        
        if (dist > 0.07) {
            vec3 tcol = texture(iChannel0, 20.6*((NOF_BALLS-j/1.6)*sidePos(st,-0.023)) + uv/dist).rgb*(0.3 + min(dist,0.8)*0.7);
            col = tcol * (1.-sz);
#if COLOR
            float cz=j*0.01;
            float czm = (2.-cz)*(2.-cz);
            col *= vec3(sin(j/1.4+0.79)*0.5+1.35,sin(j/2.+2.15)*0.7+0.6,sin(czm*5.+3.02)*0.8+1.0);
#else
            col = vec3(col.x);
#endif
            i = 0.;
        }
    }

    col = col*col*9.5;
    fragColor = vec4(col,1.0);
}
