Hi all,
here's the result of a little experiment with a technique called "Signed Distance Fields" I made this evening. It was invented and
published by Valve Software and used in their game Team Fortress 2. I read about it last week and wanted to give it a go.
Check the video:
The technique is very simple, but gives great results when rendering text using a font texture, which is quite common in games. The basic idea is to create a texture containing all characters of a font. You can then write lines of text by copying the right area of the texture to screen, or by creating a mesh that uses the correct texture coordinates. A class called TextureFont was recently added to Cinder that does text rendering this way.
The problem with rendering text like this, is that the characters can't be scaled up without losing detail. You start seeing pixels as soon as you zoom in just a little bit. This is because each character takes up a limited amount of pixels in the texture, so rendering at 150% scale or bigger gives increasingly bad results.
Valve has found a way to keep the edges of your characters sharp, by cleverly encoding so-called "Signed Distance Fields" into the font texture and then using a threshold shader to compute the edges on-the-fly. It's one of those techniques where you go "Why didn't I think of that?".
I will post the code as soon as I think it is ready to share with you, right now it's a bit messy and lacks a lot of features.
The shader, which is very simple, looks like this:
// VERTEX SHADER
#version 110
void main()
{
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
// FRAGMENT SHADER
#version 110
uniform sampler2D tex0;
void main()
{
// retrieve distance from texture
float mask = texture2D( tex0, gl_TexCoord[0].xy).a;
// use current drawing color
// perform simple thresholding
clr.a = 0.0;
clr.a = 1.0;
clr.a *= smoothstep(0.25, 0.75, mask);
It would be awesome if some of this functionality could go into the TextureFont class. But I am afraid it would require quite a bit of work to add the SDF algorithms.
-Paul