How to Use Three.js BufferAttribute updateRange
In Three.js, uploading an entire geometry buffer to the GPU can cause
performance bottlenecks, especially when dealing with large datasets or
dynamic meshes. This article explains how to use the
updateRange property of a BufferAttribute to
modify and upload only a specific portion of an attribute array,
significantly optimizing your WebGL rendering pipeline.
Understanding updateRange
The updateRange property of a
BufferAttribute is an object containing two properties: *
offset: The starting index in the typed
array where the update begins. * count:
The number of array elements (not vertices) to be uploaded to the
GPU.
By default, offset is 0 and
count is -1 (which tells Three.js to upload
the entire buffer). By limiting this range, WebGL only transfers the
modified subset of data to the GPU memory.
Step-by-Step Implementation
To update a specific portion of a geometry, modify the underlying typed array, define the update range, and flag the attribute for an update.
1. Modify the Array Data
Locate the index of the data you want to change. If you are updating
a position attribute with 3 components per vertex (\(X, Y, Z\)), multiply the vertex index by 3
to find the correct array index.
const positionAttribute = geometry.attributes.position;
const array = positionAttribute.array;
const vertexIndex = 10; // The 11th vertex in the geometry
const arrayIndex = vertexIndex * 3; // Component offset (X)
// Update the X, Y, and Z coordinates of this single vertex
array[arrayIndex] = 5.0; // New X
array[arrayIndex + 1] = 2.5; // New Y
array[arrayIndex + 2] = -1.0; // New Z2. Configure updateRange and Trigger the Update
Once the data is modified, configure the updateRange
using the starting array index and the total number of array elements
modified. Finally, set needsUpdate to
true.
// Set the start index and the number of elements to copy
positionAttribute.updateRange.offset = arrayIndex;
positionAttribute.updateRange.count = 3; // We updated 3 array elements (X, Y, Z)
// Flag the attribute for GPU upload
positionAttribute.needsUpdate = true;Important Considerations
- Array Elements vs. Vertices: The
offsetandcountproperties refer to the individual elements of the typed array (e.g.,Float32Array), not the vector grouping. If you are updating two vertices in a 3D position attribute, yourcountmust be6(2 vertices × 3 coordinates). - One-Time Use: Three.js resets
updateRange.countback to-1after the rendering frame processes the update. You must redefine theoffsetandcountevery time you setneedsUpdate = trueif you want to keep using partial updates. - Sequential Ranges: If you need to update multiple
separate sections of an array in a single frame, you must either find a
single bounding range that covers all changes or allow the entire buffer
to update, as
updateRangeonly supports a single contiguous block per frame.