Skip to content
Jaakko Alajoki
Jaakko Alajoki, October 19, 2015

Pure Three.js HUD

I was working on a Three.js project and I had to implement a HUD (Head-up display). Most of the tutorials I found suggested using HTML-elements on top of a WebGL canvas element. That’s pretty nice solution but unfortunately I wasn’t able to use it. I was targeting my project to Oculus Rift using WebVR and WebVR doesn’t currently support rendering of DOM-elements.

So I had to rely on pure Three.js. I wasn’t able to find any good tutorials about how to create HUD without DOM elements and I decided to write one. So, let’s go!

Screen-Shot-2015-10-18-at-21.29.57-1024x720

Basic concept is that I’m creating a separate scene for HUD and render that on top of my original scene. The HUD scene is very simple. I’ll create only one plane to fit the whole screen and use 2D canvas to dynamically create a HUD texture. This solution makes text rendering dead simple. Live demo is available on Codepen.

I assume that you know how to do a 3D scene and I’ll just show what you need to modify to get the HUD working.

First we’ll create a canvas and use that to render the HUD. We’ll also make the canvas to fit screen size and initialize 2D drawing context.

var hudCanvas = document.createElement('canvas')
hudCanvas.width = width
hudCanvas.height = height
var hudBitmap = hudCanvas.getContext('2d')

Now we’re ready to render the actual HUD! You can let your imagination fly. I’m just using stupid white text and place it to the screen. You can use all 2D canvas drawing primitives available.

hudBitmap.font = "Normal 40px Arial"
hudBitmap.textAlign = 'center'
hudBitmap.fillStyle = "rgba(245,245,245,0.75)"
hudBitmap.fillText('Initializing...', width / 2, height / 2)

Then we need to create a new camera. The camera will be orthographic and we’ll made it to match the dimensions of your window. That makes it possible to use pixel perfect 2D image as a HUD.

var cameraHUD = new THREE.OrthographicCamera(
-width/2, width/2,
height/2, -height/2,
0, 30
)

Then we need to create a new scene.

sceneHUD = new THREE.Scene()

Next we will create a material by using the 2D graphics we just rendered.

var hudTexture = new THREE.Texture(hudCanvas)
hudTexture.needsUpdate = true
var material = new THREE.MeshBasicMaterial({map: hudTexture})
material.transparent = true

Then we need to create a plane, apply the material to it and add it to the scene. The plane size is again matching the screen dimensions.

var planeGeometry = new THREE.PlaneGeometry( width, height )
var plane = new THREE.Mesh( planeGeometry, material )
sceneHUD.add( plane )

No we just need to add new render call to the render loop.

renderer.render(sceneHUD, cameraHUD)

Hoorray! The HUD is ready! You can check the demo and full source code at Codepen.io.