Why DownsampleBox13Tap in post-processing stack do so much sample?

This function is a part of fragment shader in Sampling.hlsl used in bloom.Each edge of destination texture is 1/2 of the source texture.

// . A . B . C .
// . . D . E . .
// . F . G . H .
// . . I . J . .
// . K . L . M .

half4 DownsampleBox13Tap(TEXTURE2D_ARGS(tex, samplerTex), float2 uv, float2 texelSize)
{
half4 A = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2(-1.0, -1.0)));
half4 B = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2( 0.0, -1.0)));
half4 C = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2( 1.0, -1.0)));
half4 D = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2(-0.5, -0.5)));
half4 E = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2( 0.5, -0.5)));
half4 F = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2(-1.0, 0.0)));
half4 G = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv ));
half4 H = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2( 1.0, 0.0)));
half4 I = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2(-0.5, 0.5)));
half4 J = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2( 0.5, 0.5)));
half4 K = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2(-1.0, 1.0)));
half4 L = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2( 0.0, 1.0)));
half4 M = SAMPLE_TEXTURE2D(tex, samplerTex, UnityStereoTransformScreenSpaceTex(uv + texelSize * float2( 1.0, 1.0)));

half2 div = (1.0 / 4.0) * half2(0.5, 0.125);

half4 o = (D + E + I + J) * div.x;
o += (A + B + G + F) * div.y;
o += (B + C + H + G) * div.y;
o += (F + G + L + K) * div.y;
o += (G + H + M + L) * div.y;

return o;
}

I think “G” is equal to “(D + E + I + J)*0.25”.
So it just samples G is enough,why does it sample D,E,I,J?It looks like not necessary.There must be some reason to add so mush extra sampling.

This shader is based on a talk Jorge Jimenez – Next Generation Post Processing in Call of Duty: Advanced Warfare
If you look at the slides it becomes clear that all 13 samples are supposed to be bilinear fetches across a 6 by 6 texel grid, but I think the shader code done by Unity Tech. might be implementing it incorrectly. Below is the screenshot of the slide in question:

In the original slides G(center-most sample) would not be equal (D + E + I + J) * 0.25 (red samples) because all the components are already bilinear interpolations, not texels.

As the DownsampleBox13Tap function is now, it looks like samples D, E, I and J are interpolated(since they use half-texel offsets) and the rest seem to be uninterpolated. Have you investigated this further? Any interesting discoveries?

Disclaimer: I might be completely wrong.

That kernel assumes the starting UV is at the corner between texels. When downsampling, the texture UV of the lower res texture will already be centered between the 4 texels of the previous texture.