How to Update BufferGeometry Vertices in Three.js
Updating the vertex positions of an active
BufferGeometry in Three.js is a crucial technique for
creating dynamic animations, terrain deformations, or interactive 3D
effects. This article provides a straightforward guide on how to access
a geometry’s position attribute, modify its underlying coordinate data,
and signal Three.js to successfully render these changes on the
screen.
Accessing and Modifying Vertex Positions
To update the vertices of a BufferGeometry, you must
directly access its position attribute. This attribute
contains a typed array storing the X, Y, and Z coordinates of every
vertex in the 3D model.
Here is the step-by-step process to update these coordinates:
- Access the position attribute: Retrieve the
positionattribute from the geometry. - Modify the data: Loop through the vertices and change their coordinates.
- Set the update flag: Set the attribute’s
needsUpdateproperty totrue. This tells Three.js to upload the new vertex data to the GPU.
Code Example
The following code demonstrates how to modify the Y-coordinates of a geometry over time, creating a simple wave effect:
// 1. Get the position attribute
const positionAttribute = geometry.attributes.position;
// Use a loop to modify each vertex
for (let i = 0; i < positionAttribute.count; i++) {
// Read current coordinate values
const x = positionAttribute.getX(i);
const z = positionAttribute.getZ(i);
// Calculate a new Y position (e.g., using a sine wave)
const newY = Math.sin(x + time) * Math.cos(z + time);
// Write the updated Y coordinate back to the attribute
positionAttribute.setY(i, newY);
}
// 2. Signal Three.js that the vertex data has changed
positionAttribute.needsUpdate = true;Performance Optimization with Usage Hints
If you plan to update your vertex positions frequently (for example, on every frame in the animation loop), you should inform the GPU. This allows the graphics card to allocate the memory more efficiently for frequent writes.
You can do this by setting the usage pattern of the
BufferAttribute to DynamicDrawUsage right
after creating your geometry:
// Set the usage to dynamic for frequent updates
geometry.attributes.position.setUsage(THREE.DynamicDrawUsage);By combining DynamicDrawUsage with
needsUpdate = true, you can achieve smooth, real-time
vertex animations in Three.js without sacrificing web browser
performance.