I'm using FTGL library to render fonts in my game, but I have completely no idea how to create an outline around text. Achieving a shadow could be easy, because I can simply do it like this:
(pseudo code)
font.render(Color::BLACK, position.x + 1, position.y + 1); // Shadow
font.render(Color::WHITE, position.x, position.y) // Normal text
But how to create an outline? Unfortunately I haven't found any interesting solutions for it over internet which seemed to me a bit strange, because I thought it's quite popular problem.
Drawing outline with just a bigger font is not a right way, because as I found out, letters just don't match in this case:
So is there any simple way to create an outline for fonts? How do they do it in real games?
Thanks in advance for any answer
Answer
Flexible & Accurate: Filters
Use a texel filter either on the texture on the CPU side, or if you are using programmable pipeline OpenGL, directly in the fragment shader.
The idea of a filter is simply that you run through a 2D loop to process every texel. If it is white, then you run through an inner 2D loop for each of its surrounding pixels in some radius, and adapt accordingly. This is also known as a box filter, though if you include the radius check, it is really a circular filter -- which avoids axis-al artifacting.
A faster way to do this is to precalculate the set of offsets from each central pixel that you check; this way, you needn't run a square root for every pixel surrounding a given pixel. You want to keep complexity down to `O(texWidth*texHeight) rather than O(texWidth*texHeight*filterRadius*filterRadius), in other words.
Easy: Multiple renders
Another way to achieve the effect would be not to scale the text, but instead to render your red outline at each of eight (or more) directions, each slightly offset from the original in that direction:
\|/
--+--
/|\
By offsetting each of the red versions like this, you would get a fairly uniform outer edge around your original text. Bear in mind that when shifting diagonally, you should use the same vector magnitude as when you shift horizontally or vertically, rather than simply offsetting by the same x and y values (which leads to a approximatlely 1.4x further length -- basic trig).
FYI
This sort of effect is known as dilation, and is sometimes performed via Minkowski Summation, which is the vector-based (continuous) approach to the pixel-based (quantised) box filter I described above.
No comments:
Post a Comment