4. [Three.js] 3D Object Transformations
1. Digest
Transforming 3D objects in space is fundamental to creating any interactive 3D scene. This module covers the three essential transformation properties that every Three.js developer must master: position, scale, and rotation. Through four progressive examples, you'll learn how to manipulate objects in 3D space using Vector3 coordinates, apply non-uniform scaling to stretch and squash geometry, and rotate objects around multiple axes with proper gimbal lock prevention.
The examples use dat.GUI for real-time parameter adjustment and AxesHelper for visual reference, making it easy to understand how transformations affect objects in 3D space. The final example demonstrates hierarchical transformations using Groups, creating a solar system model where the sun, earth, and moon each have their own orbital rotations. This teaches a crucial concept: child objects inherit transformations from their parent groups, enabling complex animations through simple rotation updates.
These transformation techniques form the foundation for any 3D interaction, from simple object movement to complex hierarchical animations. By the end of this module, you'll be comfortable manipulating objects in 3D space and creating nested transformation hierarchies for realistic multi-object systems.
2. What is the purpose
The purpose of this module is to teach fundamental 3D transformation concepts that are essential for any Three.js project. You'll gain hands-on experience with:
- Position control: Moving objects anywhere in 3D space using the x, y, z coordinate system and Three.js Vector3 methods
- Scale manipulation: Resizing objects uniformly or non-uniformly along different axes to create stretched or squashed effects
- Rotation techniques: Rotating objects around axes using radians, including proper rotation order management to avoid gimbal lock issues
- Hierarchical transformations: Building complex object relationships using Groups where parent transformations cascade to children
These skills are directly applicable to creating animated scenes, building interactive 3D applications, and organizing complex 3D objects. Understanding transformations is critical for camera control, object animations, physics simulations, and any scenario where objects need to move, rotate, or change size in response to user input or automated behaviors.
3. Some code block and its explanation
Example 1: Position Control
function draw() {
const delta = clock.getDelta();
mesh.position.set(-1, 4, 0);
// Useful Vector3 methods:
// mesh.position.length() - distance from origin
// mesh.position.distanceTo(new THREE.Vector3(1,1,1)) - distance to another point
renderer.render(scene, camera);
window.requestAnimationFrame(draw);
}
The position property uses Three.js's Vector3 class to control object location in 3D space. You can set position using set(x, y, z) for absolute positioning, or modify individual axes like mesh.position.x += 0.1. The Vector3 class provides useful utility methods like length() to get distance from the origin and distanceTo() to measure distance between points, which are invaluable for collision detection and proximity-based interactions.
Example 2: Non-uniform Scaling
function draw() {
const delta = clock.getDelta();
mesh.scale.set(3, 1.3, 1);
renderer.render(scene, camera);
window.requestAnimationFrame(draw);
}
The scale property also uses Vector3, allowing independent scaling along each axis. Here, the box is stretched 3 times wider on the x-axis and 1.3 times taller on the y-axis while maintaining its original z-axis depth. This creates non-uniform scaling, useful for creating squash-and-stretch animation effects or adapting objects to fit specific spaces. Uniform scaling would use the same value for all three axes like scale.set(2, 2, 2).
Example 3: Rotation with Proper Axis Ordering
// Set rotation order before applying rotations
mesh.rotation.reorder('YXZ');
mesh.rotation.x = THREE.MathUtils.degToRad(50);
mesh.rotation.z = THREE.MathUtils.degToRad(20);
function draw() {
const delta = clock.getDelta();
// Continuous rotation example (commented out):
// mesh.rotation.y += delta
renderer.render(scene, camera);
window.requestAnimationFrame(draw);
}
Rotation in Three.js uses radians, not degrees, so THREE.MathUtils.degToRad() converts familiar degree values. The reorder() method is critical for controlling how rotations are applied - the default 'XYZ' order can cause gimbal lock in certain orientations. By setting the order to 'YXZ', you ensure rotations are applied in a sequence that prevents mathematical gimbal lock issues. For animations, adding delta (time elapsed since last frame) to rotation properties creates smooth, frame-rate-independent rotation.
Example 4: Hierarchical Solar System with Groups
const group1 = new THREE.Group();
const sun = new THREE.Mesh(geometry, material);
const group2 = new THREE.Group();
const earth = sun.clone();
earth.scale.set(0.3, 0.3, 0.3);
group2.position.x = 2;
const group3 = new THREE.Group();
const moon = earth.clone();
moon.scale.set(0.15, 0.15, 0.15);
moon.position.x = 0.7;
group3.add(moon);
group2.add(earth, group3);
group1.add(sun, group2);
scene.add(group1);
function draw() {
const delta = clock.getDelta();
group1.rotation.y += delta; // Sun rotates
group2.rotation.y += delta; // Earth orbits sun and rotates
group3.rotation.y += delta; // Moon orbits earth and rotates
renderer.render(scene, camera);
window.requestAnimationFrame(draw);
}
Groups are containers that allow hierarchical transformations - when a parent group transforms, all children transform with it. In this solar system example, rotating group1 makes the entire system spin. Rotating group2 makes the earth orbit around the sun while also rotating on its own axis. Rotating group3 makes the moon orbit the earth. The positioning is clever: earth is positioned 2 units from group2's origin, and moon is 0.7 units from group3's origin. When the parent groups rotate, these offset positions create orbital paths. This demonstrates the power of transformation hierarchy: complex multi-object animations can be created with simple rotation updates on parent groups.
