Three.js From Zero · Article s7-08

S7-08 Text in 3D

Season 7 · Article 08

Text Rendering in 3D

Crisp text at any distance or zoom. Canvas texture blurs when scaled. Bitmap fonts pixelate. MSDF (multi-channel signed distance field) gives you vector-sharp text at any scale for ~20KB.

1. The text-in-3D problem

  • TextGeometry: extrudes a font into 3D mesh. Heavy, crisp, static.
  • CanvasTexture: draw text on a canvas, map to a plane. Fast, blurry when scaled up.
  • Bitmap fonts: pre-baked glyph atlas, pixelated at scale.
  • SDF/MSDF: signed distance field. Crisp at any scale. Best.

2. Signed Distance Field (SDF)

Each texel stores the distance to the nearest glyph edge. Shader: threshold at 0.5 → filled pixel. Because it's a continuous field, bilinear filtering gives smooth edges at any zoom.

// Fragment
float d = texture(uFontAtlas, vUv).r;
float alpha = smoothstep(0.5 - fwidth, 0.5 + fwidth, d);
gl_FragColor = vec4(color, alpha);

3. MSDF (multi-channel)

Single-channel SDF rounds corners. Multi-channel stores three distance fields in RGB, each for a different edge direction. Shader picks the median. Sharp corners preserved.

4. Troika Three Text (recommended)

import { Text } from 'troika-three-text';

const label = new Text();
label.text = 'Hello 3D!';
label.font = '/fonts/Inter.ttf';
label.fontSize = 0.3;
label.color = 0xffffff;
label.anchorX = 'center';
label.anchorY = 'middle';
label.sync();  // build MSDF atlas in worker
scene.add(label);

Builds the atlas on the fly from any TTF. Handles wrapping, alignment, clipping. 20kb library.

5. TextGeometry (built-in, heavy)

import { FontLoader } from 'three/addons/loaders/FontLoader.js';
import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';

const font = await new FontLoader().loadAsync('helvetiker.json');
const geo = new TextGeometry('Hello!', { font, size: 0.3, height: 0.05 });
scene.add(new THREE.Mesh(geo, material));

Extruded 3D letters. Great for logos. Heavy and not re-editable.

6. Live demo

Demo uses CanvasTexture for portability. In production use troika-three-text for MSDF.

7. When each wins

MethodUse
TextGeometry3D logo, decorative title
CanvasTextureQuick label, low-frequency updates
Troika Text (MSDF)Dynamic labels, UI text, production
three-bmfont-textLegacy, many codebases
HTML overlaySmall amounts, screen-space

8. Text on curves

Troika can lay text along a spline. Also supports maxWidth wrapping, overflow clipping, per-glyph callbacks.

9. Emoji & non-Latin

  • TrueType fonts handle most scripts out of box.
  • Emoji: colored fonts (COLRv1) work in Troika.
  • RTL (Arabic/Hebrew): Troika has a bidi option.
  • CJK: atlas can balloon. Preload subset for efficiency.

10. Takeaways

  • MSDF is the modern way. Vector-sharp at any scale.
  • Troika Three Text: drop-in, handles everything.
  • TextGeometry for 3D extruded logos only.
  • CanvasTexture for quick + low-update labels.
  • HTML overlay for small screen-space text.