Skip to main content

Fonts

A Text Element renders its string using a Font asset — a multi-channel signed distance field (MSDF) atlas made up of a .json file (glyph metrics) and one or more .png texture pages. Because the glyphs are stored as distance fields rather than fixed-size bitmaps, a single Font asset stays crisp at any size, so you only need one asset per typeface.

This page covers the two ways to create a Font asset and how to load one in each runtime.

Creating a Font asset

In the Editor

Drag a .ttf, .ttc, .otf or .dfont file into the Editor and it is converted to an MSDF Font asset automatically. You choose which characters to include and tune the result, then click Process Font to regenerate. See the Font asset inspector for the full list of options.

Without the Editor — font-tools

If you are building with the Engine, React or Web Components — without the Editor — use font-tools to generate the same .json + .png asset the Editor produces. There are two ways to use it:

  • Web app — Open playcanvas.github.io/font-tools, drag in a TTF or OTF, choose a character set and glyph size, preview the result in live PlayCanvas text, and download the files. Everything runs in your browser — your font is never uploaded.

  • Command line — Generate an asset without leaving your terminal:

    npx @playcanvas/font-tools MyFont.ttf --charset latin-ext -o assets/fonts/myfont

    This writes myfont.json and myfont.png (large character sets spill onto additional pages: myfont1.png, myfont2.png, and so on).

Open Source

font-tools is open-sourced under an MIT license on GitHub. See the README for the full list of CLI options and the JavaScript API for generating fonts programmatically.

Using a Font asset

Keep the .json and its .png page(s) together, with the same base name — the loader derives the texture URLs from the JSON URL and fetches the pages automatically.

// myfont.json + myfont.png (from font-tools) sit side by side;
// loading the .json pulls in the .png page(s) automatically.
const asset = new pc.Asset('myfont', 'font', { url: '/assets/fonts/myfont.json' });
app.assets.add(asset);

asset.ready(() => {
// A 2D screen to hold the text
const screen = new pc.Entity('screen');
screen.addComponent('screen', { screenSpace: true });
app.root.addChild(screen);

const text = new pc.Entity('text');
text.addComponent('element', {
type: 'text',
fontAsset: asset.id,
text: 'Hello, World!',
fontSize: 32,
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5]
});
screen.addChild(text);
});

app.assets.load(asset);