In our previous blog post we announced a new text rendering engine in VTS Browser JS. The text engine uses our new custom font format. Designing a font file format that supports different writing systems, such as Arabic or Chinese is not a trivial task. In most 3D rendering engines the solution consists of a single texture where glyphs for a certain Unicode range are stored at regular distances. This approach works well when the number of glyphs is small (for example, Latin glyphs).
When the number of glyphs is large, the size of the texture is becoming impractical, since on most GPU devices there is a limit on texture size. In this stage we had to figure out how to divide the glyphs into several textures. This way we didn’t need to worry about texture size and our only limit was the memory capacity of the target device. Another benefit of this approach is that all glyphs are usually not needed at the same time, so we can only stream some of them. This brings the question of optimal texture size. It is clear that smaller textures are more memory efficient for this purpose. In the extreme case each glyph would have its own texture and we could stream exactly those glyphs that are needed. In practice we choose a reasonable texture size of 256x256 so several glyphs share one texture. Other texture sizes are supported by the file format as well.
An interesting issue is the way the glyphs are represented in the texture. The obvious but suboptimal approach is to store the glyphs as a gray-scale mask. A better approach is to store instead the result of a signed distance field filter. This technique was used for the first time by Valve in their game engine and it has many advantages over simple grayscale masks. Glyphs reconstructed from the signed distance field (SDF) can be zoomed by a surprising amount before pixelation or other artifacts start to appear. Also, effects like color stroke or shadow can be implemented easily with almost no performance penalty.
Similarly to the texture size, there has to be a balance in glyph size. Even with SDF the glyphs need to a have certain minimal size to look good and to retain all their features. We use 24pt as the minimal glyph size. But even this parameter is optional and our file format supports different glyph sizes. In the second part of this blog post we will talk more about how we pack glyphs into the texture and what additional information is stored with the font.