Fast and Simple 2-Pass Depth of Field

Gnome Depth-Of-FieldDepth of Field is a photographic effect caused by aperture and focal length. A very interesting article about this topic has been published in istockphoto.com. It provides a reliable depth-cue for two-dimensional, projected material. In other words: It makes pictures look 3D while they’re still 2D projections.

In current generation of graphics hardware, it is possible to render a lot of fancy post-processing effects – an besides soft shadows and the motion blur, depth of field (DOF) might be on of the most often used effect to enhance visual quality. There is a vast coverage on different techniques in creating pleasing DOF effects – a simple google for “depth of field shader” gave me a about 74.000 hits. For a demo I wanted to write, I decided to use a simple, alpha-channel-based approach because it is simple, fast and looks nice.

The idea is easy: If you already have a shader that does things like per-pixel-lighting, just put the depth information into the resulting color’s alpha channel. All that has to be done in the second pass: render the image again and blur the image with a suitable kernel. As kernel, I chose a Poisson-Disc-Filter with CPU-precomputed data – this is less “jaggy” than using a simple quadratic kernel, giving better visual quality by less samples. To prevent nasty halos around the edges of areas that have high depth-differences, the result is not simply a blurred picture, but the focal-length also controls how much blurred image data get into the final result.

vec4 vColor = texture2D(sceneMap, gl_TexCoord[0].xy);
float fBlurAmount = abs(vColor.a*2.0-1.0);
float fTexel = 16.0/mapSize;
vec4 vResult;
for (int i=0; i<16; ++i) {
    vResult += texture2D(blurMap, gl_TexCoord[0].xy + fBlurAmount*fTexel*poisson[i].xy*poisson[i].z);
}
vResult/=16.0;
gl_FragColor = mix(vColor, vResult, fBlurAmount);

I am aware that this approach is quite limited – as soon as the alpha channel is needed for other effects (like a glow-pass or velocity), it can’t be used like this. But anyway, I’m happy with the results. ;)

This entry was posted in Computer Science and tagged , , , . Bookmark the permalink.

Comments are closed.