Search code examples
textgodotrasterizing

Why does text look so bad in game engines?


I'll pick on Godot as that is what I've been using lately, but I've seen the same (or at least similar) issues on Unity too.

When I add text into my game world (like adding text to a UI button to add a concrete example) the text is a blurry mess by default. I have to be very careful to choose an exact size for each font and then scale it carefully too to ensure it can be easily read. This is in contrast to, say, Notepad or even a console terminal where I can have pretty much any font at pretty much any size and everything will look good.

I assume that it has to do with rasterizing or some other fundamental assumption of the engine, but this seems like a problem that was solved long ago. What am I missing? Why is displaying text so hard?


Solution

  • Text is hard because a lot of the important details are approximately the same size as pixels. For example, the width of the strokes that make up a letter might (ideally) be a little less than the width of a pixel or a bit more. Often a letter's position is partway between two pixels, and making that look as good as the same letter positioned directly on a pixel is difficult. Text has lots of sharp, high-contrast edges. These sharp edges represent extremely high spatial frequencies that don't normally occur in natural images. The algorithms graphics engines use to scale textures work best for "natural" images, like photographs, which have much lower spatial frequencies (and even then generally need some antialiasing).

    Some image formats include a "rendering intent" to distinguish between these categories so that the graphics engine can switch algorithms to the ones best suited for the type of image. But that kind of functionality is more common in a 2D engine than a 3D game engine.

    Text looks good in 2D because 2D graphics engines have a lot of code specialized for rendering text well on a pixel grid. Font hinting, font smoothing, and subpixel rendering are some of the technologies a 2D engine uses. 3D engines have similarly named technologies, but they are generally not optimized for text.

    If you want a deep dive into the problems (and solutions) for rendering text well, The Raster Tragedy is an amazingly comprehensive resource.

    To make text look good in 3D engines, there are custom shader techniques that can help, like pre-filtered MIP maps or signed-distance fields.

    Generally speaking, if you plan to simply slap a textual texture onto a quad, then you want the resolution of that texture to be at least as large as the screen area it will be projected onto. You might also want to experiment with different anti-aliasing settings for textual textures than you would use for other textures in your game.