How to Update CanvasTexture in Three.js
When using an HTML canvas as a texture source in Three.js, changes
made to the canvas 2D context are not automatically reflected in your 3D
scene. To render these changes, you must manually signal to Three.js
that the texture’s data has changed. This article explains how to
quickly and efficiently trigger this update using the
needsUpdate property.
The Solution:
texture.needsUpdate = true
To update a CanvasTexture after modifying its underlying
HTML canvas, you must set the texture’s needsUpdate
property to true. This flags the Three.js renderer to
upload the new canvas pixel data to the GPU on the next render
frame.
Here is a step-by-step code example demonstrating how to implement this:
// 1. Create the HTML canvas and draw something
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 256;
canvas.height = 256;
ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, 256, 256);
// 2. Create the CanvasTexture and apply it to a material
const texture = new THREE.CanvasTexture(canvas);
const material = new THREE.MeshBasicMaterial({ map: texture });
const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material);
scene.add(mesh);
// 3. Modify the canvas context later (e.g., in a function or event)
function drawBlueCircle() {
ctx.beginPath();
ctx.arc(128, 128, 50, 0, Math.PI * 2);
ctx.fillStyle = '#0000ff';
ctx.fill();
// 4. Manually trigger the texture update
texture.needsUpdate = true;
}
// Call the update function
drawBlueCircle();How It Works Behind the Scenes
Three.js caches textures on the GPU to maximize rendering performance. Because Three.js cannot automatically detect when you draw on the 2D canvas context, the GPU will continue to display the old cached pixels.
Setting texture.needsUpdate = true tells the WebGL
renderer to clear the cache for this specific texture and re-upload the
current state of the DOM canvas. Once the renderer completes the upload
on the next frame, it automatically resets needsUpdate back
to false.
Performance Best Practices
- Only update when necessary: Re-uploading textures
to the GPU is a relatively expensive operation. Do not set
needsUpdate = trueinside your animation loop (requestAnimationFrame) unless the canvas content has actually changed. - Batch your canvas draws: If you are making multiple
drawing calls to the canvas (e.g., drawing text, then a shape, then a
background), perform all drawing operations first, and set
needsUpdate = trueonly once at the very end of the changes.