// HACKER NEWS — CYBERSECURITY
SDF vs. MSDF vs. Slug: GPU Text Rendering
Text looks simple until you have to draw it yourself. A letter is not a picture, it is a set of outlines: closed loops of straight lines and Bezier curves, filled according to a winding rule. Drawing that on a CPU into a bitmap is a solved problem. Drawing it on a GPU, crisply, at any size, under any 3D transform, while the text changes every frame, is not. Most engines dodge the hard version by baking glyphs into textures ahead of time and living with the compromises.
In 2017 Eric Lengyel published an algorithm, called Slug, that stopped dodging. It renders glyphs directly from their outlines in the fragment shader, with no texture atlas and no per-frame tessellation. Lengyel patented it in 2019, and on March 17, 2026 he dedicated that patent to the public domain. That is why we built Slughorn, our C++20 implementation of the Slug technique, and it is why we can now talk about how it works and where it wins.
This is a tour of how GPU text rendering actually works, from the bitmap atlas up to Slug, and where each method fits.
Every scalable font stores each glyph as vector outlines. TrueType uses quadratic Bezier curves, OpenType with CFF uses cubic curves, and both mix in straight segments. The interior of the letter is whatever the fill rule says is inside, usually the nonzero winding rule: shoot a ray from the pixel, count how the outline crosses it, and if the winding number is nonzero the pixel is inside the glyph.
A glyph is a set of outlines, not pixels: filled dots are on-curve points, open circles are Bezier control points.
The renderer has to do three things at once and do them fast: fill the interior correctly, produce clean antialiased edges, and stay sharp whether the glyph is 8 pixels tall in a menu or filling the screen on a billboard rotated in perspective. On a CPU you rasterize each glyph once at its target size and you are done. On a GPU you want to draw thousands of glyphs per frame, at arbitrary scales, ideally without re-rasterizing anything. That constraint is where every technique below makes its trade.
The oldest and still most common approach. Rasterize each glyph once, at one size, into a shared texture called an atlas, then draw each on-screen character as a textured quad that samples its slot.
It is fast, trivially portable, and runs on anything with a texture unit. That is why it is everywhere.
The problems show up the moment you scale. Enlarge past the baked size and the glyph turns into blurry or blocky pixels, because you are magnifying a bitmap. Shrink it and you get shimmer and dropped stems unless you bake mip levels. Every size you want crisp is another atlas. Every language is another problem: a Latin atlas is small, but Chinese, Japanese, and Korean have tens of thousands of glyphs, and baking all of them at several sizes is a memory disaster. And a bitmap has no idea it is being viewed in perspective, so text laid onto a 3D surface looks soft.