#version 330 core

out vec4 FragColor;

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

const float radius = 2.0;
const float depth = radius / 2.0;

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 uv = fragCoord.xy / iResolution.xy;

    vec2 center;
    center.x = 0.5 + 0.25 * cos(iTime * 0.8) + 0.1 * sin(iTime * 1.3);
    center.y = 0.5 + 0.25 * sin(iTime * 0.6) + 0.1 * cos(iTime * 1.1);
    center += 0.05 * vec2(sin(iTime * 5.0), cos(iTime * 2.5));

    float aspect = iResolution.x / iResolution.y;
    float ax = ((uv.x - center.x) * (uv.x - center.x)) / (0.2 * 0.2)
             + ((uv.y - center.y) * (uv.y - center.y)) / (0.2 / aspect);

    float dx = (-depth / radius) * ax + (depth / (radius * radius)) * ax * ax;
    float f = ax + dx;
    if (ax > radius) f = ax;

    ax = max(ax, 0.0001);
    vec2 magnifierArea = center + (uv - center) * f / ax;
    vec2 sampleUv = magnifierArea;

    fragColor = vec4(texture(iChannel0, sampleUv).rgb, 1.0);
    fragColor.a *= uAlpha;
}

void main()
{
    vec4 color = vec4(0.0);
    mainImage(color, gl_FragCoord.xy);
    FragColor = color;
}
