Text looks uncomplicated until you have to diagram it yourself. A letter is not a picture, it is a set of outlines: closed loops of direct 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, during the content changes all frame, is not. Most engines dodge the difficult type by baking glyphs into textures onward of period and living alongside the compromises.
In 2017 Eric Lengyel published an algorithm, called Slug, that stopped dodging. It renders glyphs immediately from their outlines in the part shader, alongside no texture atlas and no per-frame tessellation. Lengyel patented it in 2019, and on March 17, 2026 he dedicated that patent to the community domain. That is why we built Slughorn, our C++20 implementation of the Slug technique, and it is why we can now conversation concerning how it plant and anywhere it wins.
This is a tour of how GPU content rendering really works, from the bitmap atlas up to Slug, and anywhere all method fits.
What makes glyphs hard
Every scalable font stores all glyph as vector outlines. TrueType uses quadratic Bezier curves, OpenType alongside CFF uses cubic curves, and the two mix in direct segments. The inner of the letter is any the inhabit regulation says is inside, normally the nonzero winding rule: fire a ray from the pixel, figure how the outline crosses it, and if the winding figure is nonzero the pixel is inner the glyph.
![]()
A glyph is a set of outlines, not pixels: filled dots are on-curve points, open circles are Bezier authority points.
The renderer has to do three things at formerly and do them fast: inhabit the inner correctly, create spotless antialiased edges, and remain keen whether the glyph is 8 pixels lofty in a list or filling the display on a advertisement rotated in perspective. On a CPU you rasterize all glyph formerly at its mark size and you are done. On a GPU you desire to diagram thousands of glyphs per frame, at arbitrary scales, ideally without re-rasterizing anything. That constraint is anywhere all method below makes its trade.
Method 1: the texture atlas (bitmap glyphs)
The oldest and motionless most average approach. Rasterize all glyph once, at one size, into a shared texture called an atlas, afterward diagram all on-screen character as a textured quad that samples its slot.
It is fast, trivially portable, and runs on item alongside a texture unit. That is why it is everywhere.
The problems display up the instant you scale. Enlarge former the baked size and the glyph turns into blurry or blocky pixels, since you are magnifying a bitmap. Shrink it and you get shimmer and dropped stems unless you roast mip levels. Every size you desire keen is another atlas. Every tongue 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 multiple sizes is a recollection disaster. And a bitmap has no idea it is being viewed in perspective, so content laid onto a 3D exterior looks soft.
![]()
Magnifying a baked atlas glyph (left and center) versus rendering it from the outline (right).
Method 2: signed extend sectors (SDF)
Valve introduced the fix that carried the industry for a decade. Chris Green's 2007 SIGGRAPH work, "Improved Alpha-Tested Magnification for Vector Textures and Special Effects," stores not the glyph's pixels but a signed extend field: all texel holds the extend to the nearest edge, affirmative inside, negative outside. In the shader you example that site and threshold at zero. Because extend interpolates smoothly, you can measure a small SDF texture up dramatically and motionless get a spotless edge, and you get cheap antialiasing by softening the threshold.
One small texture, resolution autonomous inside reason, one cheap shader. For a lengthy period this was the default for keen UI content and equivalent HUDs, and it motionless is on constrained hardware.
But an SDF is motionless a baked texture sampled at a fixed resolution, and it lies concerning corners. A keen border is a discontinuity in the extend field, and bilinear interpolation rounds it off. Every difficult border on a letter, the item of an "A", the notch of a "K", gets softened. Push the magnification far enough, or create the glyph small adequate that the site is lone a few texels wide, and lean stems interrupt up and item smears.
![]()
A signed extend site (left) and the keen border a shader recovers from it (right).
Method 3: multi-channel signed extend sectors (MSDF)
Viktor Chlumsky's work, from his 2015 thesis and the 2018 document "Improved Corners alongside Multi-Channel Signed Distance Fields," fixes the border problem. Instead of one extend channel, MSDF stores three, in red, green, and blue, all encoding extend to a distinct subset of edges chosen so that keen corners survive. In the shader you obtain the median of the three channels. The median trick reconstructs corners nearly perfectly, so an MSDF glyph stays keen at magnifications that would circular an SDF to mush.
MSDF is the current saccharine place for a lot of teams, and Chlumsky's msdfgen is MIT licensed and extensively adopted. If you need keen scalable content and you are consenting to roast an atlas, it is an outstanding choice.
It is motionless an atlas, though, alongside the expenses that implies. You roast all glyph at a chosen resolution onward of time, so energetic or user-supplied text, and enormous glyph sets akin CJK, motionless average baking pipelines and recollection budgets. Generation is additional costly than plain SDF. At extremely small sizes you are motionless sampling too few texels to clasp fine detail, and at extreme minification you motionless combat aliasing. The three-channel lookup expenses additional bandwidth than one. MSDF raises the ceiling on quality, but it motionless uses an atlas.
![]()
SDF rounds keen corners; MSDF preserves them. Images: Viktor Chlumsky / msdfgen (MIT).
Method 4: tessellation and safety (Loop-Blinn, NV_path_rendering, Pathfinder, Rive)
A distinct family skips textures entirely and turns the outline into geometry the GPU can rasterize.
- Loop-Blinn feeds curved triangles to the GPU and uses a per-pixel discard shader to keep lone the inner of all quadratic Bezier, blended alongside the stencil buffer to determine winding. Elegant, but dependable antialiasing is genuinely difficult without tricks that disbursal quality.
- Stencil-then-cover, exposed as NVIDIA's NV_path_rendering extension, draws the way into the stencil buffer in one pass, afterward covers it in a second. It is elevated norm but leans on vendor extensions and particular hardware paths.
- Pathfinder tessellates edges into microtriangles, computes signed trapezoidal areas per pixel, and accumulates safety in a compute pass. Tile-based and accelerated on contemporary GPUs.
- Rive's renderer, open-sourced in 2024, reduces antialiased vector paths into distinctive triangle patches and rasterizes them through a massively parallel pipeline alongside pixel local storage, hitting 120 fps on animated vector art.
This family is genuinely resolution-independent and, for animated designed vector graphics, frequently the correct answer. Rive in particular is built for artwork that moves. The expenses are the tessellation itself, which have to be redone whenever geometry changes, the geometry blowup for complex glyphs, the difficulty of spotless analytic antialiasing, and in several cases a dependence on particular hardware features or extensions.
![]()
Tessellation methods rotate the outline into triangles the GPU rasterizes.
Method 5: Slug, rendering direct from the outline
Slug skips the atlas and per-frame tessellation and keeps the glyph as a catalog of quadratic Bezier curves and row segments stored in a small GPU buffer. Alongside it, Slug builds a lightweight per-glyph acceleration construction that partitions the glyph into horizontal bands, so a stated pixel lone has to regard the fistful of curves near it fairly than the entire outline.
Then it resolves safety directly in the part shader. For all pixel it efficiently casts a ray, finds anywhere that ray crosses the nearby Bézier curves, and counts those crossings to compute the winding figure and hence coverage. The difficult part, and Lengyel's concealed sauce, is a test he calls root eligibility: a exact regulation for which curve-ray intersections should count, so the winding math is exact at the shared endpoints anywhere curves encounter and anywhere naive approaches create cracks or double-counts. Because the shader is solving the curve equations analytically fairly than sampling a baked field, it produces exact safety and spotless antialiasing at any scale.
![]()
Slug’s center idea: for all pixel, mold a ray and figure how many times it crosses the outline.
There is no baked resolution, so the identical glyph is razor keen at 6 pixels or 6000, and it stays keen under arbitrary 2D and 3D transforms, including perspective, since safety is computed per pixel following the transform. There is no atlas, so a hundred thousand CJK glyphs disbursal a font's value of outline data, not an atlas the size of a video. Text can alter all example at no baking cost, which is exactly what you desire for live data, person input, and localized content. And it all happens in a sole diagram alongside an average part shader, no vendor expansion required.
This is crucial whenever you cannot foretell how the content volition be viewed. Atlas, SDF, and MSDF all roast a fixed resolution onward of time, which quietly assumes a bounded range of on-screen sizes and viewing angles. When the association between the content aircraft and the camera is not known in advance, a liberated 3D camera, an arbitrary zoom, a close-up, or a steep off-axis grazing angle, those baked approximations interrupt down: magnify former the baked resolution and the atlas blurs during SDF and MSDF circular and smear, and at oblique angles the sampled site aliases. You cannot pre-allocate adequate resolution for all imaginable perspective without the retention exploding. Slug computes safety analytically, per pixel, following the transform, so it stays exact no matter how close, how far, or how oblique the spectator gets, alongside nothing baked and no ceiling to hit. Tessellation is the lone another family that shares this, and it pays for it in tessellation disbursal and harder antialiasing. That is why Slughorn is the one to attain for in interactive 3D, AR and VR, flythroughs, moving HUDs, and CAD or digital-twin navigation, anywhere you do not get to decide ongoing how near or how oblique the spectator volition be.
Seeing the difference
We rendered the identical chief R alongside Slughorn (our osgSlug integration) next to the alternatives you would really attain for: a single-channel SDF, an MSDF, Rive's renderer, and osgText's bitmap alongside alongside its bitmap-derived SDF. Every texture-based panel got the identical budget, 64 texels per em, so what separates them is technique, not resolution.
![]()
Straight on at their baked size, five of the six are practically identical: Slughorn, Rive, and MSDF reproduce the outline, and the single-channel SDFs differ lone by slightly rounded corners at the ft of the leg. The outlier is the osgText bitmap, a 64 px/em depiction magnified concerning four times, which cannot regain item it never stored.
Tilt the glyph into viewpoint and the image changes.
![]()
In grazing perspective, Slughorn and the three distance-field panels keep the R in location alongside spotless edges, since they compute safety per pixel inner the glyph’s own plane, so the projection expenses them nothing. The osgText bitmap blurs as it recedes. Rive’s R is the incorrect shape: its renderer lone accepts 2D affine transforms, and a viewpoint projection is not affine, so the finest it can do is an approximation that is exact at the center and drifts toward the edges.
Now zoom in on a sole edge.
![]()
At extreme magnification, lone the curve-based renderers, Slughorn and Rive, motionless create a straight, spotless edge, since the two activity from the genuine outline at any size it is shown (Rive by re-tessellating all example for this view). The distance-field panels notch, anywhere interpolating between stored samples no longer matches the true curve. The osgText bitmap has dissolved into a sole gray gradient, since all of its texels now covers a ample part of the panel.
A note on fairness, since the specialized audience volition ask. Every texture-based method current used the identical 64 texels per em, and giving them additional pushes these artifacts rear without removing them. The SDF and MSDF panels use default roast settings, and MSDF's error-correction options would soften several of the notches in the final image. Rive is shown at its finest for these views, rendered through the camera all frame, which is additional generous than how it is normally embedded in a 3D scene, anywhere it would be drawn into a texture and mapped onto the surface, avoiding the distortion but blurring the way the bitmap does.
Head to head
| Concern | Bitmap atlas | SDF | MSDF | Tessellation / Rive | Slug |
|---|---|---|---|---|---|
| Sharp at any scale | No | Partly | Mostly | Yes | Yes |
| Sharp corners | Yes at roast size | No | Yes | Yes | Yes |
| Tiny sizes | Bake per size | Weak | Better | Good | Good |
| Memory for ample glyph sets (CJK) | Very high | High | High | Low | Moderate |
| Dynamic / changing text | Rebake | Rebake | Rebake | Re-tessellate | Free |
| 3D and perspective | Soft | OK | OK | Good | Excellent |
| Heavily animated vector art | No | No | No | Excellent (Rive) | Good |
| Runs on low-end / old GPUs | Excellent | Excellent | Good | Varies | Needs a capable shader stage |
| Implementation complexity | Low | Low | Medium | High | Medium to high |
Pale green marks anywhere Slug is the finest or a tied-best choice.
So which one should you use
There is no sole winner, there is a correct tool per job.
- Reach for Slug(horn) whenever you need content that is keen at all measure and under 3D and viewpoint (VR/AR/xR), whenever you have huge or energetic glyph sets, whenever the content changes constantly, or whenever you are rendering blended vector UI into a real-time pipeline. This is GIS pane cockpits, visual simulation labels, space domain displays, AR overlays, and any interface that has to remain legible during it moves. This is why we built Slughorn.
- Reach for MSDF whenever you desire keen scalable text, you can roast an atlas up front, and you are blessed on a broad range of hardware. It is a awesome default for simpler equivalent HUDs and app UI.
- Reach for plain SDF whenever the hardware is constrained, the content is fairly static, and you can live alongside softened corners.
- Reach for a bitmap atlas whenever the content is a fixed size on a fixed UI and you desire the simplest, most portable item that works.
- Reach for Rive or a tessellation renderer whenever the job is designed vector artwork that animates, not chiefly text.
But wait, there's more
![]()
We keep saying content since content is anywhere Slug earned its name, but Slughorn draws item you can province as filled and stroked vector geometry, from any of its backends. That method complete SVG alongside gradients, layered shaders, and animation inside layers, and it holds up at map-cartography scale, example labels and linework at clarity and resolution the pre-baked approaches cannot reach. There is a lot additional we volition be demonstrating soon. For the features we have not called out here, see the Slughorn repository on GitHub.
Tooting Slughorn's horn
Slughorn is our implementation of the Slug method in contemporary C++20. It does the dense activity once, at build time, so there is no runtime tessellation: the outline data and collection construction are prepared onward of period and the shader fair evaluates coverage. And during content is anywhere Slug made its name, Slughorn doesn't treat glyphs specially: a glyph is fair a famous shape. Anything you can depict as vector paths renders through the identical pipeline, alongside the identical quality. It ingests the formats you already use, including SVG, FreeType fonts, and paths from Blend2D, Cairo, and Skia, and it exposes a native Canvas-style API for authoring shapes directly, alongside fills, strokes, and gradients composited into a sole GPU-ready atlas of outline data. It targets OpenGL, Vulkan, WebGPU, and DirectX, and ships alongside Python bindings alongside the C++ API, so the identical rendering plant from an embedded HUD to a complete 3D scene.
Credit anywhere it is due: the Slug algorithm is Eric Lengyel's, published in the Journal of Computer Graphics Techniques and, since March 2026, liberated for anyone to implement. We think it is the correct basis for correct, resolution-independent content on the GPU, and Slughorn is our obtain on making it uncomplicated to use.
If you are fighting blurry labels in a 3D scene, an atlas that volition not fit your glyph set, or content that has to remain keen during it moves, that is exactly the benevolent of issue we solve. Contact us to conversation concerning Slughorn or to put it to activity in your pipeline.
References
- Eric Lengyel, "GPU-Centered Font Rendering Directly from Glyph Outlines," Journal of Computer Graphics Techniques, vol. 6, no. 2, 2017.
- Eric Lengyel, "A Decade of Slug" (Slug patent dedicated to the community domain, March 2026), terathon.com.
- Chris Green, "Improved Alpha-Tested Magnification for Vector Textures and Special Effects," Valve, SIGGRAPH 2007.
- Viktor Chlumsky, "Shape Decomposition for Multi-Channel Distance Fields" (thesis, 2015) and "Improved Corners alongside Multi-Channel Signed Distance Fields," Computer Graphics Forum, 2018. msdfgen is MIT licensed.
- Rive, "Rive Renderer, now open origin and accessible on all platforms," 2024.
- servo/pathfinder project and its "Related approaches" documentation.
Frequently asked questions
What is the difference between texture-atlas, SDF, MSDF, and Slug content rendering?
A texture atlas stores all glyph as a baked bitmap, so it blurs formerly you measure former its baked size. SDF (signed extend field) stores distance-to-edge instead, which scales improved but rounds keen corners. MSDF adds channels so corners remain crisp, but it is motionless a baked atlas at a chosen resolution. Slug skips the atlas and computes safety from the glyph's genuine Bezier outline in the shader, so it stays exact at any size or angle.
Why does content go blurry whenever I measure or tilt it in 3D?
Because most engines diagram content from a pre-baked bitmap atlas. Magnify former the baked resolution, tilt it in perspective, or cover it onto a surface, and you are stretching a fixed grid of pixels, so the edges soften. Outline-based methods akin Slug evade this since safety is computed per pixel following the transform.
What is the Slug algorithm?
Slug is a method published by Eric Lengyel in 2017 that renders glyphs immediately from their quadratic Bezier outlines on the GPU, alongside no texture atlas and no per-frame tessellation. A part shader casts a ray per pixel and counts curve crossings to get exact coverage, using Lengyel's “root eligibility” test for correctness anywhere curves meet.
Is the Slug method liberated to use now?
Yes. Lengyel dedicated the Slug patent to the community domain in March 2026, so anyone can execute the technique. AlphaPixel's Slughorn is a C++20, MIT-licensed implementation of it.
When should I use MSDF alternatively of Slug?
When you can roast an atlas up front, your content is fairly static, and you desire one cheap shader that runs on a broad range of hardware. MSDF is a powerful default for equivalent HUDs and app UI. Slug wins whenever content must remain keen at any measure and angle, whenever glyph sets are huge or dynamic, or whenever the camera association is unbounded.
Does Slug grip ample glyph sets akin Chinese, Japanese, and Korean?
Yes, and without the atlas-memory explosion. Because Slug stores outline data alternatively of baked bitmaps, tens of thousands of CJK glyphs disbursal a font's value of curve data fairly than a elephantine multi-size texture. In Slughorn the per-glyph collection construction adds average overhead, motionless fine below a CJK atlas.
How is Slughorn connected to Slug?
Slug is the algorithm (Lengyel's); Slughorn is AlphaPixel's archive that implements it. Slughorn feeds any GPU API (OpenGL, Vulkan, WebGPU, Direct3D) and draws any filled and stroked vector geometry, not fair text.