Three.js updateMatrixWorld: When to Call It Manually
In Three.js, updateMatrixWorld is a crucial method used
to calculate the global position, rotation, and scale of a 3D object
relative to the 3D world. While Three.js typically handles this
transformation automatically during the rendering loop, there are
specific scenarios where developers must trigger it manually. This
article explains how the method works, why it is necessary, and the
exact situations where manual execution is required to prevent
positioning and physics bugs.
What updateMatrixWorld Does
Every 3D object in Three.js (Object3D) has two primary
matrices used to calculate its position in space: *
matrix (Local Matrix): Stores the
position, rotation, and scale of the object relative to its immediate
parent. * matrixWorld (World Matrix):
Stores the absolute position, rotation, and scale of the object relative
to the global scene origin (0, 0, 0).
The updateMatrixWorld method recalculates the
matrixWorld of the target object and all of its children.
It does this by multiplying the object’s local matrix with
its parent’s matrixWorld. This mathematical propagation
down the scene graph ensures that if a parent moves, all of its children
are correctly positioned in global 3D space.
Why Three.js Handles It Automatically
Under normal circumstances, you do not need to call this method. When
you call renderer.render(scene, camera), Three.js
automatically traverses the entire scene graph and calls
updateMatrixWorld on every object before drawing the frame.
This ensures that what is displayed on the screen is always up to date
with your latest coordinate modifications.
When You Must Call updateMatrixWorld Manually
You must call updateMatrixWorld() manually when you need
to access or use an object’s global coordinates immediately
after changing its position, rotation, or scale, but before the next
render frame occurs.
Because Three.js delays the matrix calculations until the render step to save performance, querying world-space properties right after modifying them will yield outdated data. Here are the most common scenarios where a manual update is required:
1. Raycasting Immediately After Movement
If you change an object’s position and immediately perform a raycast
calculation to detect collisions or mouse clicks, the raycaster will use
the old matrixWorld of the object. This causes the raycast
to miss or hit the wrong area. Calling
object.updateMatrixWorld() right before the raycast ensures
accurate collision detection.
2.
Getting Global Coordinates via getWorldPosition or
getWorldQuaternion
If you update an object’s local position and immediately try to
retrieve its global position using
object.getWorldPosition(targetVector), the returned vector
will reflect the old position. You must update the matrix world before
querying:
mesh.position.set(10, 5, 2);
mesh.updateMatrixWorld(); // Force recalculation
mesh.getWorldPosition(myVector); // Now contains correct global coordinates3. Dynamically Attaching and Detaching Objects
When transferring an object from one parent to another while trying to maintain its visual position in the scene, you must calculate its relative offset. If the old or new parent has moved during the current frame, their world matrices must be updated manually before recalculating the new local transformations.
How to Use It
To update a specific object and all of its descendants, call:
object.updateMatrixWorld();If you only want to update the local matrix of a single object
without traversing its children, you can use
object.updateMatrix(). However, for most global coordinate
calculations, updateMatrixWorld() is the safest choice to
ensure the entire local hierarchy is accurate.