vec3 scene(float time, vec2 uv)
{
    uv = uv * 2.0 - 1.0;
    
   // uv = atanh(uv);

    vec2 olduv = uv;
    uv.x += sin(olduv.y * 2. + time* 20.) * 0.5;
    uv.y -= sin(olduv.x * 2. + time* 16.1) * 0.2;
    olduv = uv;
    uv.x += sin(olduv.y * 2. + time* 16.1) * 0.2;
    uv.y -= sin(olduv.x * 2. + time* 20.) * 0.5;
    
   // uv = tanh(uv);
    
    uv = uv * 0.5 + 0.5;
    
    vec3 c = texture(iChannel0, uv).rgb;
    
    // Fake an HDR texture.
    c = pow(c, vec3(4)) * 6.;
    
    return pow(c, vec3(2.2));
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // For aspect corrected UV's use the following calculation: 
    /*
    float s = min(iResolution.x, iResolution.y);
   	vec2 uv = (2.*fragCoord.xy - vec2(iResolution.xy)) / s;
    */
    
    // For UVs sampling from textures use the following calculation:
    vec2 uv = fragCoord.xy / iResolution.xy;
    
    mat2 jitter;
    jitter[0] = dFdx(uv);
    jitter[1] = dFdy(uv);
    
    vec2 blueNoiseUV = fragCoord.xy / iChannelResolution[1].xy;
    
    float blueNoise = texture(iChannel1, blueNoiseUV).r / 9.;
    

    //aa and motion blur
    float t = iTime + blueNoise*iTimeDelta;
    vec3 c 
        = scene(t,                    uv)
        + scene(t-iTimeDelta*(1./9.), uv+jitter*vec2( 0.66,  0.00  ))
        + scene(t-iTimeDelta*(2./9.), uv+jitter*vec2(-0.66,  0.00  ))
        + scene(t-iTimeDelta*(3./9.), uv+jitter*vec2( 0.00,  0.66))
        + scene(t-iTimeDelta*(4./9.), uv+jitter*vec2( 0.00, -0.66))
        + scene(t-iTimeDelta*(5./9.), uv+jitter*vec2( 0.50,  0.50))
        + scene(t-iTimeDelta*(6./9.), uv+jitter*vec2(-0.50,  0.50))
        + scene(t-iTimeDelta*(7./9.), uv+jitter*vec2(-0.50, -0.50))
        + scene(t-iTimeDelta*(8./9.), uv+jitter*vec2( 0.50, -0.50));
        
    c /= 9.;
    
    fragColor = vec4(pow(c, vec3(1.0/2.2)),1.0);
}
