David Lyons

3D Artist, Front End / WebXR Developer and Interaction Designer based in Los Angeles


Rendering Text in WebVR

SDF Bitmap Text example

The purpose of this GitHub repo is to make it as easy as possible to add arbitrary text to new Three.js WebVR projects. This involves either using the included Roboto font, or converting another licensed font to the same format (.png + .json) for use in Three.js.

In 2016, I needed to figure out how to render text in WebVR for WITHIN's WebVR site. Because WebVR relies on a canvas element, text rendering must be done in canvas, in the 3D scene. I spent some time researching and evaluating different text rendering methods, and found that signed distance field bitmap fonts are the most effective and efficient way to render arbitrary blocks of text in WebVR. So I created a bitmap font with Hiero (.fnt and .png), browserified Matt DesLauriers' three-bmfont-text and converted my .fnt files to .json to remove the load-bmfont and Node dependencies, then wrote a convenience wrapper class to handle the creation of text objects with the .png and .json assets:

Roboto Bitmap PNG


Roboto Bitmap JSON


In February 2017, I wrote an article that was published on Google's developer blog documenting and explaining how to generate a bitmap font with Hiero and how to use the font in Three.js with my wrapper class. My example on GitHub demonstrates the typography capabilities of layout-bmfont-text with the dat.gui sliders and includes a bitmap version of Roboto that you can use in your own projects. My usage has changed a bit since the Google dev blog article was written.


<script src="three-bmfont-text-bundle.js"></script>
<script src="sdf-shader.js"></script>
<script src="text-bitmap.js"></script>
var robotoBoldKey = 'roboto-bold';
var fileName = './fonts/roboto/bitmap/' + robotoBoldKey;
var jsonPath = fileName + '.json';
var imagePath = fileName + '.png';

// load the Roboto bitmap font assets and assign them to the key
TextBitmap.load( robotoBoldKey, jsonPath, imagePath );

// after the assets load, you can pass the font key to the TextBitmap constructor
THREE.DefaultLoadingManager.onLoad = function ( ) {

	// fontKey and text are required, the rest are optional
	var bmtext = new TextBitmap({
		text: 'Grumpy wizards make toxic brew for the evil Queen and Jack.',
		fontKey: robotoBoldKey,
		width: 1000,
		align: 'center',
		valign: 'center',
		lineHeight: 80,
		letterSpacing: 1,
		scale: 0.0004,
		color: '#fff',
		outlineColor: '#000'

	// TextBitmap inherits THREE.Group
	// so you can add instances to the scene
	// and position, scale or rotate them
	scene.add( bmtext );
	bmtext.position.set( 0, 1, -0.5 );

	// you can also change the text by setting the text property
	bmtext.text = 'The quick brown fox jumps over the lazy dog.';