Hello folks!
I’d like to formally introduce a library I’ve created for rendering high quality text within Three.js scenes using SDF (signed distance fields). I had found that existing SDF text libraries were missing features I needed, and I hated the idea of having to pre-generate SDF atlas textures, so I created my own solution.
PLEASE NOTE! As of v 0.29.0, this has been promoted to its own
troika-three-text
package, where previously you had to import a specific secondary dist file withintroika-3d-text
. I have edited this post to reflect its new home.
Repository: https://github.com/protectwise/troika/tree/master/packages/troika-three-text
Example: Troika Examples
Highlights:
Most importantly, it parses web font files (.ttf, .otf, .woff) directly using Typr.js and generates SDFs for specific glyphs on the fly as they are used. This means you can use ligatures and extended character sets without having to pre-generate large atlas textures.
Rather than using a simple custom ShaderMaterial, it “patches” any Three.js material you give it. So your text can use lighting, shadows, fog, textures, and any other feature the built-in materials provide.
Many CSS properties are supported for the text styling and layout, and I’ve strived to match CSS behavior as closely as possible. It supports clipping and I’m working on additional advanced features like truncation/ellipsis and text selection.
All font parsing, SDF generation, and text layout is performed off the main thread in a web worker to avoid frame drops. Performance has been a primary goal since the start.
Usage:
Full documentation is in the repository.
Even though it was originally created as part of our Troika scene management framework, I’ve provided it as a standalone troika-three-text
package that excludes any Troika framework dependencies, which you can use in any Three.js project.
import { Text } from 'troika-three-text'
let text = new Text()
text.font = 'path/to/font.woff'
text.text = 'Hello!'
text.fontSize = 0.2
text.color = 0x9966FF
text.sync()
myScene.add(text)
It’s a simple API and easily used within other Three.js-based frameworks, for example: AFrame and react-three-fiber. It’s also being used in Mozilla’s ecsy-three framework and was featured in their Hello WebXR demo.
Feedback:
I’m still actively developing this library with fixes and features, so I welcome any suggestions or bug reports; go ahead and open an issue in the Github repo. Thanks, I hope this is useful for people!