Utility classes for Text rendering in Three.js using Bitmap fonts and MSDF (multi-channel signed distance fields).
npm install @srinivasprabhu/three-msdf-text-utilsbash
npm install three-msdf-text-utils
`
Usage
`js
import { MSDFTextGeometry, MSDFTextMaterial } from "three-msdf-text-utils";
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
import * as THREE from 'three';
Promise.all([
loadFontAtlas("./fonts/roboto/roboto-regular.png"),
loadFont("./fonts/roboto/roboto-regular.fnt"),
]).then(([atlas, font]) => {
const geometry = new MSDFTextGeometry({
text: "Hello World",
font: font.data,
});
const material = new MSDFTextMaterial();
material.uniforms.uMap.value = atlas;
const mesh = new THREE.Mesh(geometry, material);
});
function loadFontAtlas(path) {
const promise = new Promise((resolve, reject) => {
const loader = new THREE.TextureLoader();
loader.load(path, resolve);
});
return promise;
}
function loadFont(path) {
const promise = new Promise((resolve, reject) => {
const loader = new FontLoader();
loader.load(path, resolve);
});
return promise;
}
`
References
$3
`js
const geometry = new MSDFTextGeometry(options);
`
Options can be an object, or a String – equivalent to { text: str }.
#### Options specific to ThreeJS:
- flipY (boolean): whether the texture will be Y-flipped (default true)
- multipage (boolean): whether to construct this geometry with an extra buffer containing page IDs. This is necessary for multi-texture fonts (default false)
#### Other options
- font (required) the BMFont definition which holds chars, kernings, etc
- text (string) the text to layout. Newline characters (\n) will cause line breaks
- width (number, optional) the desired width of the text box, causes word-wrapping and clipping in "pre" mode. Leave as undefined to remove
- word-wrapping (default behaviour)
- mode (string) a mode for word-wrapper; can be 'pre' (maintain spacing), or 'nowrap' (collapse whitespace but only break on newline characters), otherwise assumes normal word-wrap behaviour (collapse whitespace, break at width or newlines)
- align (string) can be "left", "center" or "right" (default: left)
- letterSpacing (number) the letter spacing in pixels (default: 0)
- lineHeight (number) the line height in pixels (default to font.common.lineHeight)
- tabSize (number) the number of spaces to use in a single tab (default 4)
- start (number) the starting index into the text to layout (default 0)
- end (number) the ending index (exclusive) into the text to layout (default text.length)
#### Methods
- update(options)
Re-builds the geometry using the given options. Any options not specified here will default to those set in the constructor.
This method will recompute the text layout and rebuild the WebGL buffers.
Options can be an object, or a String – equivalent to { text: str }.
#### Properties
- layout
Text Layout instance, you can use it to access layout attributes such as :
> width, height, descender, ascender, xHeight, baseline, capHeight, lineHeight, linesTotal, lettersTotal
- visibleGlyphs
A filtered set from geometry.layout.glyphs intended to align with the vertex data being used by the underlying BufferAttributes.
This is an array of { line, position, index, data } objects, see here. For example, this could be used to add a new BufferAttribute for line offset.
$3
It extends from Three.js ShaderMaterial
You can use it just by setting the atlas texture from your font :
`js
const material = new MSDFTextMaterial(options);
material.uniforms.uMap.value = atlas;
`
#### Initial Properties
`js
const defaultOptions = {
side: THREE.FrontSide,
transparent: true,
defines: {
IS_SMALL: false,
},
extensions: {
derivatives: true,
},
uniforms: {
// Common
uOpacity: { value: 1 },
uColor: { value: new Color("#ffffff") },
uMap: { value: null },
// Rendering
uThreshold: { value: 0.05 },
uAlphaTest: { value: 0.01 },
// Strokes
uStrokeColor: { value: new Color("#ff0000") },
uStrokeOutsetWidth: { value: 0.0 },
uStrokeInsetWidth: { value: 0.3 },
},
vertexShader,
fragmentShader,
};
`
Note: IS_SMALL boolean is useful to render small fonts, it will switch the alpha rendering calculation to make them visually much smoother
#### Custom material
If you want to make some specific text effects you can create your own glsl code in your shader material based on the MSDFTextMaterial shader.
`js
import { uniforms } from "three-msdf-text-utils";
import * as THREE from 'three';
const material = new THREE.ShaderMaterial({
side: DoubleSide,
transparent: true,
defines: {
IS_SMALL: false,
},
extensions: {
derivatives: true,
},
uniforms: {
// Common
...uniforms.common,
// Rendering
...uniforms.rendering,
// Strokes
...uniforms.strokes,
},
vertexShader:
,
fragmentShader:
,
});
material.uniforms.uMap.value = atlas;
`
Dependencies
- quad-indices
- word-wrapper
- three.js (peer dependency)
Development
`bash
npm install
`
`bash
npm run dev
``