// https://discord.com/channels/237199950235041794/525510804494221312/955458285367066654
vec3 clipAABB(vec3 prevColor, vec3 minColor, vec3 maxColor) {
    vec3 pClip = 0.5 * (maxColor + minColor); // Center
    vec3 eClip = 0.5 * (maxColor - minColor); // Size

    vec3 vClip = prevColor - pClip;
    vec3 aUnit = abs(vClip / eClip);
    float denom = max(aUnit.x, max(aUnit.y, aUnit.z));

    return denom > 1.0 ? pClip + vClip / denom : prevColor;
}

vec3 neighbourhoodClipping(sampler2D currTex, vec3 CurrentColor, vec3 prevColor, out vec3 maxColor) {
    vec3 minColor = CurrentColor;
    maxColor = CurrentColor;

    for (int x = -1; x <= 1; x++) {
        for (int y = -1; y <= 1; y++) {
            if (x == y && x == 0) continue;
            vec3 color = texelFetch2D(currTex, ivec2(gl_FragCoord.xy + vec2(x, y)), 0).rgb;
            minColor = min(minColor, color);
            maxColor = max(maxColor, color);
        }
    }
    return clipAABB(prevColor, minColor, maxColor);
}
vec3 get_closest_depth(ivec2 FragCoord, vec2 Texcoord) {
    vec3 MinDepth = vec3(FragCoord, texelFetch(depthtex1, FragCoord, 0).x);

    const ivec2[4] Offsets = ivec2[4](
        ivec2(-1, -1),
        ivec2(1, -1),
        ivec2(-1, 1),
        ivec2(1, 1)
    );
    vec4 D = textureGatherOffsets(depthtex1, Texcoord, Offsets);

    MinDepth = MinDepth.z > D.x ? vec3(FragCoord - Offsets[0], D.x) : MinDepth;
    MinDepth = MinDepth.z > D.y ? vec3(FragCoord - Offsets[1], D.y) : MinDepth;
    MinDepth = MinDepth.z > D.z ? vec3(FragCoord - Offsets[2], D.z) : MinDepth;
    MinDepth = MinDepth.z > D.w ? vec3(FragCoord - Offsets[3], D.w) : MinDepth;

    MinDepth.xy *= resolutionInv;
    return MinDepth;
}

vec3 TAA(vec3 Color, ivec2 FragCoord, vec2 Texcoord) {
    vec3 ClosestSample = get_closest_depth(FragCoord, Texcoord);
    vec2 PrevCoord = Texcoord + toPrevScreenPos(ClosestSample.xy, ClosestSample.z).xy - ClosestSample.xy;

    if (clamp(PrevCoord, 0, 1) != PrevCoord)
        return Color;

    #ifdef TAA_BICUBIC_FILTER
    vec3 PrevColor = texture_catmullrom_fast(colortex4, PrevCoord).rgb;
    #else
    vec3 PrevColor = texture(colortex4, PrevCoord).rgb;
    #endif
    if (PrevColor == vec3(0)) return Color;

    vec3 ClippingMaxColor;
    vec3 ClampedColor = neighbourhoodClipping(colortex0, Color, PrevColor, ClippingMaxColor);

    #if AA_MODE != 2
    float blendFactor = 0.6 + 0.2 * exp(-length((PrevCoord - Texcoord) * resolution));
    #else
    float blendFactor = 0.9;
    #endif

    // Jessie's offcenter rejection (reduce ghosting)
    vec2 pixelOffset = 1.0 - abs(2.0 * fract(PrevCoord * resolution) - 1.0);
    float OffcenterRejection = sqrt(pixelOffset.x * pixelOffset.y) * 0.15 + 0.85;
    blendFactor *= OffcenterRejection;

    #if AA_MODE == 2
    // Flicker reduction
    blendFactor = clamp(blendFactor + pow2(get_luminance((PrevColor - Color) / ClippingMaxColor)) * 0.15, 0, 1);
    #endif

    Color = mix(Color, ClampedColor, blendFactor);
    return Color;
}
