Render 3D Typography with Three.js FontLoader

Rendering three-dimensional text in a web browser is a powerful way to enhance interactive experiences, and Three.js makes this possible through its FontLoader and TextGeometry modules. This article provides a step-by-step guide on how to import fonts, generate 3D mesh geometry from typeface JSON files, apply materials, and render the resulting 3D typography within a Three.js scene.

1. Import the Required Modules

In modern Three.js, FontLoader and TextGeometry are not part of the core library. You must import them explicitly from the examples/addons directory.

import * as THREE from 'three';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';

2. Prepare the Font File

Three.js cannot read standard .ttf or .otf font files directly. You must convert your font into a typeface JSON file. You can use online converters like facetype.js to convert your preferred font into a .json file and place it in your project’s public directory.

3. Load the Font and Generate 3D Text

Use the FontLoader to load the JSON font file. Inside the loader’s success callback, instantiate TextGeometry by passing the desired string and a configuration object, then pair it with a material to create a renderable mesh.

// Initialize the FontLoader
const loader = new FontLoader();

loader.load('path/to/your/font.json', function (font) {
    
    // Create the 3D Text Geometry
    const textGeometry = new TextGeometry('Hello 3D!', {
        font: font,
        size: 80,          // Size of the text
        depth: 20,         // Thickness of the text (formerly 'height')
        curveSegments: 12, // Number of points on the curves
        bevelEnabled: true,
        bevelThickness: 10,
        bevelSize: 8,
        bevelOffset: 0,
        bevelSegments: 5
    });

    // Center the geometry's bounding box to align text properly
    textGeometry.center();

    // Create a material
    const textMaterial = new THREE.MeshStandardMaterial({ 
        color: 0xff0055,
        roughness: 0.3,
        metalness: 0.8
    });

    // Combine geometry and material into a Mesh
    const textMesh = new THREE.Mesh(textGeometry, textMaterial);

    // Add the mesh to the scene
    scene.add(textMesh);
});

4. Optimize and Center the Text

By default, Three.js aligns text geometry from the left edge of the first character. Calling textGeometry.center() recalculates the bounding box and centers the text perfectly around its local origin, making rotations and positioning much easier to manage.

5. Add Lights

Since MeshStandardMaterial responds to light, ensure your scene contains at least one light source (like an ambient light and a directional light) to make the depth, bevels, and shadows of your 3D typography visible:

const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(100, 100, 100);
scene.add(directionalLight);