Font Loading in Three.Js

Yesterday i decided I would use a little free time to dabble in three.js and WebGl. Being brand new to both technologies my first step was, like everyone, to head to Google.

A demonstration of my google-fu

After wading my way through the introductory example and a few tutorials I figured it was time to branch out on my own and attempt a simple project. My goal for was to render my name to an html canvas in 3-d and have the ability to rotate it by clicking and dragging. Nothing too complicated but knowing nothing about the library it proved to be a challenge.

Three provides a TextGeometry function in order to render 3-d text using a Three compatible font. A lot of example fonts come bundled with the library when it is downloaded that can be pulled in and worked with. I set up a basic node project with webpack-dev-server and Three installed through npm. Since it wasn’t mentioned in the documentation I assumed it would be fine to simply include the font in my main.js file like so.

var THREE = require('three');
var font = require('../helvetiker_regular.typeface.js');

following along with the TextGeometry docs I created a new TextGeometry object, combined it with a material and rendered it to my scene.

var textMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00});
var textGeometry = new THREE.TextGeometry("Patrick Sullivan", {
font: font,
size: 40,
height: 15
});
var textMesh = new THREE.Mesh(textGeometry, textMaterial);
scene.add(textMesh);

I fired up my webpack server, navigated to my root page and was met with nothing but a black screen. Heading to the console I was met with an error stating that my font was undefined. It turns out that in Three you are now required to manually load in fonts using an undocumented function FontLoader. This transformed my font loading process to look like this.

var THREE = require('three');
var fontLoader = new THREE.FontLoader();
fontLoader.load('../somefont.typeface.js', function(font) {
// .. set up the scene, render canvas to dom and position camera.
var textMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00});
var textGeometry = new THREE.TextGeometry("Patrick Sullivan", {
font: font,
size: 40,
height: 15
});
var textMesh = new THREE.Mesh(textGeometry, textMaterial);
scene.add(textMesh);
// .. functions for click and drag rotation.
});

With the font loading in place I was able to see my name rendered to the page and it only was a matter of following along with documentation to get the rest of the functionality going.

This experience really highlighted the need for proper and thorough documentation for code libraries. It took me stumbling over a gist on github demonstrating modern font loading in Three before I was even introduced to the FontLoader function, and there is no mention of it in the official documentation. However, this isn’t meant to reflect badly upon the contributors working on three but really us as an open source community, it is our responsibility to provide not just the code, but clear documentation to go along with it, and if it doesn’t exist to take it upon ourselves to create it.