|
Features

Creating A Post-Processing Framework:
Tips & Tricks
Bloom
There are different ways for designating the areas for blooming
in the target scene. Apart from working with floating point buffers
and implementing a real HDR, a high-pass filter can be used for
extracting the bright areas from the regular scene, or the alpha
channel (as mentioned in “Using the Alpha Channel”)
be used for rendering the bloomed geometry separately.
The bloom filter typically consists of the following steps:

The image illustrates the stages and passes of the bloom filter.
The effect is typically started by extracting the bloom information
into a smaller work buffer (Aux 1 here). A horizontal pass is then
applied with a wide target buffer (Aux 2), and a vertical pass
with a full-size target buffer (Back-Buffer).
The bloom effect is then achieved by sampling a number of neighboring
texels for the current source texel in question, and assigning
the texels further from the center decreasing blending weights.
Separate horizontal and vertical passes are necessary for sampling
a large enough number of texels, and avoiding a “star” artifact
in the resulting image.
On the level of individual pixels, the passes look as follows:

The image illustrates the horizontal pass in Aux 2 and the vertical
pass in Aux 3.
A naïve implementation might sample each pixel at the texel
center with the appropriate weight set for that texel. However,
it is possible to optimize this process by enabling linear filtering
for the source texture and sampling at texel boundaries (as mentioned
in “Using the Hardware Filtering”), which allows for
either a much larger number of samples to be taken to enhance the
effect, or doing the same effect with less samples and thus optimizing
its performance.
The following image illustrates this method:

Bloom filters by sampling at texel centers and texel boundaries.
In the 3 sample method, the sampling points do not lie exactly
at the texel boundaries. Rather, they take into account the blending
weights for the each texel and the samples are then jittered so
that the linear filtering automatically samples each texel with
its relative correct weight comparing to its neighbor.
The correct offset between the texels can be calculated with the
following formula.
Offset = Weight2 / (Weight1+Weight2)
The result of this sample has to be then normalized by multiplying
it with the sum of the weights of both texels.
Weight = Weight1+Weight2
The calculation of offsets and weights should be done on the CPU,
which leaves the vertex and pixel shaders as follows.

The HLSL code sample contains the input and output structures for
the bloom effect.

The HLSL code sample contains the vertex and pixel shaders for
the bloom effect.
Note that the sample offsets are packed into float4 texture coordinates
for optimization. Typically the hardware may interpolate even float2
coordinates as full float4’s, thus using two separate variables
of float2 would be wasteful, and it is instead better to pack all
the information into as few variables as possible.
Image Perturbation
Perturbation of the rendered scene can be used for a multitude
of effects such as simulating a daze, heat-shimmer or different
blast waves.

Battlefield 2: Special Forces featured an image perturbation effect
when the player was dazed by tear-gas. (The screenshot has been brightened for
this article)
These effects are typically based on perturbing the source texture
coordinates by using the sine and cosine instructions. In the case
of the pixel shader model 1.4, these instructions are not available
in which case they can be simulated by sampling a sine texture.
The perturbation could also be moved to per-vertex level if using
a highly tessellated target quad. In this case, at least a vertex
shader model 2.0 would be required for using the sine and cosine
instructions on the GPU. Alternatively, the vertices could be perturbed
on the CPU for each frame.

HLSL code sample for an image perturbation effect. Pixel Shader
2.0 required.
• deltaUV - pixel deltas as calculated at the beginning
of this article.
• strength - 4 weights for tweaking the waviness of the resulting
image.
• timeDistortion -2 time values for horizontal and vertical perturbation
speeds, the values should loop within range 0-1.
Conclusion
Hopefully this article has both given some insight into the basics
of post-processing, and highlighted some of the common problems
experienced with it, while also giving ideas for solutions and
optimizations for creating more efficient graphics engines and
more advanced post-processing effects in general.
Many of the techniques mentioned here can be applied to a wide
range of effects not covered in the article, and can hopefully
serve as an inspiration for future work and adaptation for your
own special-effects.
|