#define PI 3.14159265359

uniform sampler2D image;  // The input texture (your PNG image)
uniform float iTime;      // Time, from 0 (scattered) to 1 (original)
uniform float maxRotation = PI / 8.0;
uniform float scatterStrength = 0.25;

// Bounce Out easing function for a bouncing effect
float easeOutBounce(float t) {
    float n1 = 7.5625;
    float d1 = 2.75;
    
    if (t < 1.0 / d1) {
        return n1 * t * t;
    } else if (t < 2.0 / d1) {
        t -= 1.5 / d1;
        return n1 * t * t + 0.75;
    } else if (t < 2.5 / d1) {
        t -= 2.25 / d1;
        return n1 * t * t + 0.9375;
    } else {
        t -= 2.625 / d1;
        return n1 * t * t + 0.984375;
    }
}

// Function to generate random displacement
vec2 randomDisplacement(vec2 uv, vec2 seed) {
    float displacementX = fract(sin(dot(uv + seed, vec2(12.9898, 78.233))) * 43758.5453);
    float displacementY = fract(sin(dot(uv + seed, vec2(43.5421, 19.4525))) * 24612.3456);
    return vec2(displacementX, displacementY) * 2.0 - 1.0;  // Output between -1 and 1
}

// Function to rotate the UV coordinates
vec2 rotateUV(vec2 uv, vec2 center, float angle) {
    float cosA = cos(angle);
    float sinA = sin(angle);
    mat2 rotation = mat2(cosA, -sinA, sinA, cosA);
    return rotation * (uv - center) + center;
}

void main() {
    vec2 iResolution = vec2(1920., 1080.);
    vec2 uv = gl_TexCoord[0].xy;
    
    // Center the UV coordinates for rotation
    vec2 center = vec2(0.5, 0.5);
    
    // Ease the time progression using the bounce easing
    float easedTime = easeOutBounce(clamp(iTime, 0.0, 1.0));

    // Increase the strength of the scatter
    // float scatterStrength = 0.25;  // Adjust this value to scatter pixels further offscreen

    // Calculate random displacement based on UV coordinates and a seed
    vec2 randomOffset = randomDisplacement(uv, vec2(0.5, 0.7));

    // Set maximum rotation and overshoot angle
    // float maxRotation = PI / 2.0;  // Start rotation at 90 degrees
    float overshootAmount = 4.0;   // Amount to overshoot (20% of max rotation)
    
    // Calculate the rotation angle with overshoot
    float rotationAngle = maxRotation * (1.0 - easedTime) * (1.0 + overshootAmount * (1.0 - easedTime));
    
    vec2 rotatedUV = rotateUV(uv, center, rotationAngle);

    // Interpolate between fully scattered and original pixel positions
    vec2 scatteredUV = rotatedUV + randomOffset * scatterStrength * (1.0 - easedTime);  

    // Sample the texture at the scattered coordinates
    vec4 color = texture2D(image, scatteredUV);

    gl_FragColor = color;
}
