Create Smooth 3D Paths with Three.js CatmullRomCurve3
Generating smooth, curved trajectories through a set of coordinates
is a common requirement in 3D web development, whether for camera
animations or character movement. This article provides a step-by-step
guide on how to use CatmullRomCurve3 in Three.js to define
3D waypoints, generate a smooth mathematical curve through them, and
visualize or animate objects along that path.
1. Define Your Waypoints
The first step is to define an array of 3D coordinates using
THREE.Vector3. These points act as the anchors that your
smooth path must pass through.
import * as THREE from 'three';
const waypoints = [
new THREE.Vector3(-10, 0, 10),
new THREE.Vector3(-5, 5, 5),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(5, -5, -5),
new THREE.Vector3(10, 0, -10)
];2. Create the CatmullRomCurve3 Instance
Pass your array of waypoints into the
THREE.CatmullRomCurve3 constructor. This class interpolates
a smooth spline through all the specified points.
// Create the 3D curve
const curve = new THREE.CatmullRomCurve3(waypoints);
// Optional configurations:
// curve.closed = true; // Makes the path loop back to the start
// curve.curveType = 'centripetal'; // Options: 'centripetal', 'chordal', or 'catmullrom'Using the default configuration is usually sufficient, but setting
closed: true is ideal for continuous circular tracks or
patrol paths.
3. Visualize the Curve
To see the generated path in your scene, you need to extract a series of detailed points from the curve, assign them to a geometry, and render them using a line material.
// Divide the curve into 50 segments to get 51 points for a smooth visual line
const points = curve.getPoints(50);
// Create geometry from the points
const geometry = new THREE.BufferGeometry().setFromPoints(points);
// Create a material for the line
const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
// Create the final object to add to the scene
const curveObject = new THREE.Line(geometry, material);
scene.add(curveObject);4. Animate an Object Along the Path
To move a 3D object (like a camera or a mesh) smoothly along the
generated path, use the .getPointAt(t) method in your
animation loop. This method takes a value t between
0 (start of the curve) and 1 (end of the
curve).
const mesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
scene.add(mesh);
let progress = 0; // Starts at 0 (0%) and goes to 1 (100%)
const speed = 0.002; // Controls the movement speed
function animate() {
requestAnimationFrame(animate);
// Increment progress and loop it
progress += speed;
if (progress > 1) progress = 0;
// 1. Get the current position on the curve
const position = curve.getPointAt(progress);
mesh.position.copy(position);
// 2. Optional: Make the object look ahead along the curve
const lookAtTarget = curve.getPointAt(Math.min(progress + 0.01, 1));
mesh.lookAt(lookAtTarget);
renderer.render(scene, camera);
}
animate();