// 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 prevColor, vec3 CurrentColor, ivec2 FragCoord, 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 = texelFetch(currTex, FragCoord + ivec2(x, y), 0).rgb;
            minColor = min(minColor, color);
            maxColor = max(maxColor, color);
        }
    }
    return clipAABB(prevColor, minColor, maxColor);
}

vec3 get_closest_depth(ivec2 FragCoord) {
    vec3 MinDepth = vec3(FragCoord, texelFetch(depthtex1, FragCoord, 0).x);
    for (int i = -1; i <= 1; i += 2) {
        for (int j = -1; j <= 1; j += 2) {
            ivec2 OffsetCoords = FragCoord + ivec2(i, j);
            float NewDepth = texelFetch(depthtex1, OffsetCoords, 0).x;
            if (NewDepth < MinDepth.z) MinDepth = vec3(OffsetCoords, NewDepth);
        }
    }
    MinDepth.xy *= resolutionInv;
    return vec3(MinDepth);
}

vec3 TAA(vec3 Color, ivec2 FragCoord, vec2 Texcoord) {
    vec3 ClosestSample = get_closest_depth(FragCoord);
    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, PrevColor, Color, FragCoord, ClippingMaxColor);

    #if AA_MODE == 0
    float blendFactor = 0.6 + 0.2 * exp(-length((PrevCoord - Texcoord) * resolution));
    #else
    float blendFactor = 0.92;
    #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 != 0
    // Flicker reduction
    blendFactor = clamp(blendFactor + pow2(get_luminance((PrevColor - Color) / ClippingMaxColor) * 0.33), 0, 1);
    #endif

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