Convert Local Direction to World Trajectory in Three.js
In Three.js, moving an object along its own local axes requires
converting local direction vectors into world space. This article
explains how to use the localToWorld method to transform a
localized direction vector into a global trajectory, allowing you to
move 3D objects relative to their current orientation.
The Challenge with Direction Vectors
The localToWorld method in Three.js is designed to
convert a local position coordinate into a world
position coordinate. It does this by multiplying the
vector by the object’s global transformation matrix
(matrixWorld), which applies scale, rotation, and
translation (position).
Because localToWorld applies translation, passing a pure
direction vector (like 0, 0, -1 for forward) directly into
the method will not yield a pure direction vector. Instead, it yields a
specific point in world space. To get a global trajectory, you must
isolate the direction from the object’s position.
Method 1: The Vector Subtraction Approach
To use localToWorld to find a global direction, you
calculate the world position of a point directly in front of the object
and subtract the object’s actual world position. This isolates the
orientation vector.
Here is the step-by-step implementation:
// 1. Define the local direction (e.g., local forward along the negative Z-axis)
const localDirection = new THREE.Vector3(0, 0, -1);
// 2. Convert the local point to a world position
const worldPoint = object.localToWorld(localDirection.clone());
// 3. Get the object's current world position
const worldPosition = new THREE.Vector3();
object.getWorldPosition(worldPosition);
// 4. Subtract the positions to get the global direction vector
const globalTrajectory = new THREE.Vector3()
.subVectors(worldPoint, worldPosition)
.normalize();The resulting globalTrajectory vector is a normalized
unit vector pointing in the object’s global forward direction. You can
multiply this vector by a speed scalar to move the object or a
projectile along this trajectory in your render loop:
const speed = 0.5;
projectile.position.addScaledVector(globalTrajectory, speed);Method 2: The Optimized Alternative (transformDirection)
While the subtraction method using localToWorld is
highly illustrative, Three.js provides a built-in, computationally
cheaper method specifically for converting directions:
Vector3.transformDirection.
This method multiplies the vector by the object’s 3D matrix and automatically ignores translation, meaning you do not need to perform subtraction or manually query the object’s world position.
const localDirection = new THREE.Vector3(0, 0, -1);
// Ensure the object's world matrix is up to date
object.updateMatrixWorld();
// Transform the direction vector directly using the object's world matrix
const globalTrajectory = localDirection.clone().transformDirection(object.matrixWorld);Both methods yield the exact same global trajectory. Use the
localToWorld subtraction method if you are already working
with relative point distances, and use transformDirection
for clean, high-performance vector transformations.