Create 2D Billboards in Three.js with SpriteMaterial
In Three.js, creating 2D elements that constantly face the
camera—commonly known as billboards—is highly efficient using the
Sprite and SpriteMaterial classes. This
article provides a quick, step-by-step guide on how to set up a
SpriteMaterial, apply a texture to it, and render a 2D
sprite that automatically rotates to face the viewer in a 3D scene.
What is a Sprite?
A Sprite is a special type of 3D object in Three.js that
always faces the camera. Unlike a standard Mesh created
with a PlaneGeometry, a Sprite does not
require you to manually update its rotation matrix in the animation
loop; Three.js handles the camera-facing calculation automatically under
the hood.
To create a billboard, you must pair a Sprite object
with a SpriteMaterial.
Step-by-Step Implementation
Follow these steps to implement a 2D billboard in your Three.js project:
1. Load the Texture
First, load the image file you want to display on your billboard
using the TextureLoader.
import * as THREE from 'three';
// Create a texture loader
const textureLoader = new THREE.TextureLoader();
// Load your image texture
const spriteMap = textureLoader.load('path/to/your/image.png');2. Create the SpriteMaterial
Next, instantiate a SpriteMaterial. This material is
specifically designed to work with Sprite objects. You can
pass your loaded texture into the map property.
const spriteMaterial = new THREE.SpriteMaterial({
map: spriteMap,
color: 0xffffff, // Use white to preserve original texture colors
transparent: true // Enable transparency if your image has an alpha channel
});3. Instantiate the Sprite
Create the Sprite object by passing the material into
its constructor. Then, position it in your 3D space.
const sprite = new THREE.Sprite(spriteMaterial);
// Position the sprite in the scene
sprite.position.set(0, 5, -10);
// Scale the sprite (Sprites are 1x1 units by default)
sprite.scale.set(2, 2, 1);
// Add the sprite to your scene
scene.add(sprite);Key Considerations for Sprites
- Scaling: Because sprites do not have custom
geometry, you control their size entirely using the
.scale.set(width, height, depth)method. The depth value is usually kept at1since sprites are flat 2D planes. - Rotation: Sprites always face the camera on the X
and Y axes. However, you can still rotate them along the Z-axis
(clockwise or counter-clockwise) by adjusting the
.material.rotationproperty. - Depth Testing: If you are using billboards for UI
elements or labels that should always appear on top of other 3D objects,
set
depthTest: falseanddepthWrite: falseinside yourSpriteMaterialconfiguration.