// @name Bulge Distortion
// @group Distortion
// @param uBulgeStrength "Bulge Strength" 0.5 0.0 2.0 0.01
// @param uBulgeRadius "Bulge Radius" 0.4 0.001 1.0 0.01
// @param uBulgeCenterX "Center X" 0.5 0.0 1.0 0.01
// @param uBulgeCenterY "Center Y" 0.5 0.0 1.0 0.01

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / uResolution.xy;
    
    vec2 center = vec2(uBulgeCenterX, uBulgeCenterY);
    vec2 offset = uv - center;
    float dist = length(offset);
    
    vec2 distortedUV = uv;
    
    // Calculate normalized distance from center, relative to the bulge radius.
    // Ensures r is between 0 (at center) and 1 (at radius edge).
    float r = dist / uBulgeRadius;
    
    // Apply distortion only within the specified radius
    if (r < 1.0) {
        // Calculate the amount of distortion.
        // It's strongest at the center (r=0) and gradually falls off
        // towards the edge of the radius (r=1) using a quadratic falloff.
        // The overall strength is scaled by uBulgeStrength and uIntensity.
        float distortionAmount = uBulgeStrength * uIntensity * (1.0 - r * r);
        
        // Apply distortion: pixels are pushed outwards from the center.
        // We scale the offset vector by (1.0 + distortionAmount).
        // A larger factor pushes the UV further away from the center, creating the bulge.
        distortedUV = center + offset * (1.0 + distortionAmount);
    }
    
    // Sample the input texture with the potentially distorted UV coordinates.
    // If uIntensity is 0, distortionAmount will be 0, and distortedUV will be equal to uv,
    // effectively showing the original image.
    fragColor = texture(uTexture, distortedUV);
}