Game Development Reference
In-Depth Information
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-
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