Improving text rendering with Signed Distance Fields

Text rendering has always been a problematic topic for graphics programmers. How can we render high quality text in a fast and reliable way?

Bitmap fonts has been around for quite some time now an they’re kind of the de facto way of rendering text.  Each character in a string is renderer as a quad strip (actually, a triangle strip), and then we use a texture atlas with a pre-rendered font to draw the actual glyphs.

High resolution bitmap font
A high resolution bitmap font

While this is a fast technique, it has a nasty drawback: visual quality is lost as we get closer to the rendered text due to texture magnification. Of course, we can increase the texture size in order to have a bigger, more detailed, font texture but that also increases the memory requirements for our application. And that doesn’t solve the problem in it’s entirety.

So far, bitmap fonts have been supported by Crimild in several ways. But recent versions include an implementation of a  complementary technique called Signed Distance Fields (SDF).

The use of SDF was originally  proposed by Valve for the game Team Fortress 2 and it’s actually really simple. Instead of using a bitmap containing the rendered characters for a particular font, we store a matrix containing the distance from each pixel to a glyph boundaries. Positive values are assigned to pixels outside the glyph, negative values for the ones inside and zeros for pixels that part of the boundary itself.

Low resolution SDF texture

The tricky part is to map positive and negative values to a grayscale image. By convention, the minimum distance is set to 1.0, the minimum to 0. A distance of 0 is mapped to 0.5 (gray). This may clamp large distances but that’s not an actual problem.

During the rendering step, a pixel shader is used to determine whether or not to render a pixel by checking if the texel’s distance is positive. Otherwise, the pixel is discarded. Texture magnification comes in handy here since it interpolates distances. The results are really good:

Bitmap fonts vs SDF
Bitmap fonts vs SDF
Bitmap fonts vs SDF (zoomed in)
Bitmap fonts vs SDF (zoomed in)
Quality differences
The difference in quality is quite notorious

It is possible to achieve this effect using the fixed pipeline, but shaders can achieve other effects, like outlines, shadows or glow:

Screen Shot 2013-09-01 at 8.11.25 PM
Rendering outlined text by using a custom fragment program

As a final note, although I talked about text rendering throughout this post, this technique is also useful for pretty much any bitmap asset as long as they’re greyscale.  After all, Valve engineers designed it for decals and billboards. I recommend you to give a quick look at the original paper since it’s very interesting.