// 5 texture samples instead of 9
vec3 blur3x3(sampler2D image, vec2 texcoord) {
    vec3 Color = vec3(0);
    vec2 Off1 = vec2(-0.33, 1.0) * resolutionInv;
    vec2 Off2 = vec2(1.0, 0.33) * resolutionInv;
    Color += texture(image, texcoord).rgb * 0.25;
    Color += texture(image, texcoord + Off1).rgb * 0.1875;
    Color += texture(image, texcoord - Off1).rgb * 0.1875;
    Color += texture(image, texcoord + Off2).rgb * 0.1875;
    Color += texture(image, texcoord - Off2).rgb * 0.1875;
    return Color;
}

// https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare/
vec3 blur6x6(sampler2D image, vec2 texcoord) {
    vec3 Color = texture(image, texcoord).rgb;

    // Sample corners
    Color += textureOffset(image, texcoord, ivec2(-2, -2)).rgb * 0.125;
    Color += textureOffset(image, texcoord, ivec2(2, -2)).rgb * 0.125;
    Color += textureOffset(image, texcoord, ivec2(-2, 2)).rgb * 0.125;
    Color += textureOffset(image, texcoord, ivec2(2, 2)).rgb * 0.125;

    // Sample in a + shape
    Color += textureOffset(image, texcoord, ivec2(0, -2)).rgb * 0.25;
    Color += textureOffset(image, texcoord, ivec2(0, 2)).rgb * 0.25;
    Color += textureOffset(image, texcoord, ivec2(-2, 0)).rgb * 0.25;
    Color += textureOffset(image, texcoord, ivec2(2, 0)).rgb * 0.25;

    // Sample closer corners
    Color += textureOffset(image, texcoord, ivec2(-1, -1)).rgb * 0.5;
    Color += textureOffset(image, texcoord, ivec2(1, -1)).rgb * 0.5;
    Color += textureOffset(image, texcoord, ivec2(-1, 1)).rgb * 0.5;
    Color += textureOffset(image, texcoord, ivec2(1, 1)).rgb * 0.5;

    return Color / 4.5;
}

void write_bloom(ivec2 Pos, vec3 Color, bool IsAlt) {
    if (IsAlt) {
        Pos = ivec2(resolution) - Pos;
    }
    imageStore(image0, Pos, vec4(Color, 0));
}

vec3 read_bloom(vec2 Pos, bool IsAlt) {
    if (IsAlt) {
        Pos = 1 - Pos;
    }
    return texture(image0Sampler, Pos).rgb;
}

vec3 read_bloom_downscale(vec2 Pos, bool IsAlt) {
    if (IsAlt) {
        Pos = 1 - Pos;
    }
    return blur6x6(image0Sampler, Pos);
}

vec3 read_bloom_upscale(vec2 Pos, bool IsAlt) {
    if (IsAlt) {
        Pos = 1 - Pos;
    }
    return blur3x3(image0Sampler, Pos);
}
