Game Development Reference

In-Depth Information

1.2.2

Blur Passes

The two blur passes are similar to one another. Each reads a fixed-length set of

adjacent samples, either horizontal or vertical, and computes two weighted sums.

The key outer loop section of the code is shown below.

// Accumulates the blurry image color

blurResult.rgb = float3(0.0f);

float
blurWeightSum = 0.0f;

// Accumulates the near-field color and coverage

nearResult = float4(0.0f);

float
nearWeightSum = 0.0f;

// Location of the central filter tap (i.e., "this" pixel's location)

// Account for the scaling down by 50% during blur

int2 A = int2(gl_FragCoord.xy) * (direction + ivec2(1));

float
packedA = texelFetch(blurSourceBuffer , A, 0).a;

float
r_A = (packedA * 2.0 - 1.0) * maxCoCRadiusPixels;

// Map large negative r_A to 0.0 and large positive r_A to 1.0

float
nearFieldness_A = saturate(r_A * 4.0);

for
(
int
delta = -maxCoCRadiusPixels; delta <= maxCoCRadiusPixels;

++delta) {

// Tap location near A

int2 B=A+(direction * delta);

// Packed values

float4 blurInput = texelFetch(blurSourceBuffer , clamp(B, int2(0),

textureSize(blurSourceBuffer , 0)

- int2(1)), 0);

// Signed kernel radius at this tap, in pixels

float
r_B = (blurInput.a * 2.0 - 1.0) *
float
(maxCoCRadiusPixels);

// [Compute blurry buffer]

...

// [Compute near-field super blurry buffer and coverage]

....

}

blurResult.a = packedA;

blurResult.rgb /= blurWeightSum;

nearResult /= nearWeightSum;

The details of the two blur kernel sections follow. See also our demo source code,

which contains extensive comments explaining optimizations and alternative im-

plementations.

Let
A
be the center sample of the kernel and
B
be a nearby sample (note

that
B
=
A
is included in the set of samples that we consider). We compute the

weight of sample
B
as follows.

Search Nedrilad ::

Custom Search