vec2 OffsetDist(float x) {
    float n = fract(x * 8.0) * pi;
    return vec2(cos(n), sin(n)) * x;
}
vec4 ld4(vec4 dist) {
    return (2.0 * near) / (far + near - dist * (far - near));
}

float AmbientOcclusion2(float dither, float depth) {
    float ao = 0.0;

    depth = ld(depth);

    vec2 scale = dither * gl_FragCoord.xy * 0.5;
    float mult = 0.5 * (far - near);

    const vec4 steps = 0.4 + vec4(0.0, 0.2, 0.4, 0.6);

    #if defined MC_GL_VENDOR_NVIDIA && defined MC_OS_WINDOWS
    ivec2 texoffsets0[4];
    texoffsets0[0] = ivec2(vec2(0.321630, 0.237497) * scale);
    texoffsets0[1] = ivec2(vec2(0.170197, 0.575310) * scale);
    texoffsets0[2] = ivec2(vec2(0.226930, 0.767481) * scale);
    texoffsets0[3] = ivec2(vec2(1.000000, 0.000000) * scale);

    ivec2 texoffsets1[4];
    texoffsets1[0] = -texoffsets0[0];
    texoffsets1[1] = -texoffsets0[1];
    texoffsets1[2] = -texoffsets0[2];
    texoffsets1[3] = -texoffsets0[3];

    vec4 depthgather0 = ld4(textureGatherOffsets(depthtex0, texcoord, texoffsets0, 0));
    vec4 depthgather1 = ld4(textureGatherOffsets(depthtex0, texcoord, texoffsets1, 0));

    #else

    ivec2 texelcoord = ivec2(gl_FragCoord.xy);

    ivec2 texelCoords0 = ivec2(texelcoord + vec2(0.321630, 0.237497) * scale);
    ivec2 texelCoords1 = ivec2(texelcoord + vec2(0.170197, 0.575310) * scale);
    ivec2 texelCoords2 = ivec2(texelcoord + vec2(0.226930, 0.767481) * scale);
    ivec2 texelCoords3 = ivec2(texelcoord + vec2(1.000000, 0.000000) * scale);

    ivec2 texelCoordsx = ivec2(texelcoord - vec2(0.321630, 0.237497) * scale);
    ivec2 texelCoordsy = ivec2(texelcoord - vec2(0.170197, 0.575310) * scale);
    ivec2 texelCoordsz = ivec2(texelcoord - vec2(0.226930, 0.767481) * scale);
    ivec2 texelCoordsw = ivec2(texelcoord - vec2(1.000000, 0.000000) * scale);

    vec4 depthgather0 = ld4(vec4(texelFetch(depthtex0, texelCoords0, 0).r, texelFetch(depthtex0, texelCoords1, 0).r, texelFetch(depthtex0, texelCoords2, 0).r, texelFetch(depthtex0, texelCoords3, 0).r));
    vec4 depthgather1 = ld4(vec4(texelFetch(depthtex0, texelCoordsx, 0).r, texelFetch(depthtex0, texelCoordsy, 0).r, texelFetch(depthtex0, texelCoordsz, 0).r, texelFetch(depthtex0, texelCoordsw, 0).r));

    #endif        

    vec4 sample0 = (depth - (depthgather0)) * mult / steps;
    vec4 sample1 = (depth - (depthgather1)) * mult / steps;

    vec4 angle;
    angle += max(0.5 - sample0, 0.0);
    angle += max(0.5 - sample1, 0.0);

    vec4 dist;
    dist += max(0.25 * sample0 - 1.0, 0.0);
    dist += max(0.25 * sample1 - 1.0, 0.0);

    vec4 ao2 = clamp(angle + dist, 0.0, 1.0);
    ao = dot(ao2, vec4(1.0)) * 0.25;

    return ao;
}