November 22, 2010
At SIGGRAPH 2007, Chris Green at Valve published a paper, Improved Alpha-Tested Magnification for Vector Textures and Special Effects . The paper is about a neat trick for making alpha tested textures containing contours (like text, or logos) look much better. Here’s why you should use it:
On the left standard alpha blending with a 32 x 32 texture and on the right the same texture but with alpha testing. Alpha testing makes the edges somewhat sharper but there’s still artefacts from the low resolution. There’s just too little information in the texture.
On the left standard alpha testing with a distance field texture and on the right the same texture but with a simple shader providing some anti-aliasing.
The basic idea is that instead of storing coverage information in the alpha channel, you store a uniformly sampled signed distance field, that for each texel contains the shortest distance to the contour.
Since graphics hardware uses a bi-linear filter, this makes the basic texture filtering do a piecewise linear reconstruction of the distance field, giving you nice sharp edges, even when the texture has fairly low resolution.
And best of all, it works on any hardware that can do bi-linear filtering and alpha testing. In other words, any piece of graphics hardware made in the last 15 years or so can do this.
For some reason, this trick isn’t as well known as it should be.
For a one off experiment you can just use Photoshop. Since I couldn’t find a simple cross platform generator, I wrote my own distance field texture generator. It uses a very simple brute force method, but it just takes a couple of seconds to generate a 32 x 32 texture from a 1024 x 1024 one, so it isn’t really a problem.
If you’re using Windows you can use Roman Keskenti’s SDFGen to convert a coverage texture into a distance field.
Generating a distance field from a standard bitmap is known as a distance transform, and you can do better than the simple brute force way on a high resolution 1-bit texture of your countour. Stefan Gustavsson has published a distance transform that takes the coverage information in an anti-aliased image into account. This means you can use a lower resolution source texture to generate the distance field and still get good results.
And for some gratuitous bling bling, here’s a WebGL demo of a bouncing, anti-aliased, letter a with a drop shadow. Just a 32 x 32 distance field texture and some shader magic.