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