From Perspective to Orthographic Camera in Three.js with Dolly Zoom — Vertigo Effect
Watch video on YouTube: https://youtu.be/dgCCboHXc3s
Have you ever experienced a sense of disorientation while watching a movie, especially during moments of high tension or panic? As if the space around the protagonist starts to twist and turn, creating an almost vertiginous effect? This is the famous Dolly Zoom, also known as the Vertigo Effect. First appearing in Alfred Hitchcock’s masterpiece “Vertigo,” this cinematic technique continues to be widely used today in films, animations, advertisements, and video games due to its power to convey strong emotions.
What is the Dolly Zoom?
The term “Dolly Zoom” itself explains its function. This effect is achieved by the simultaneous combination of two camera movements: the dolly and the zoom. The dolly refers to the camera’s forward and backward movement, often executed in films using a camera mounted on a dolly track. The zoom involves changing the camera’s focal length in the opposite direction. When the camera moves closer to the subject, the zoom decreases, and when the camera moves away, the zoom increases.
This combination alters the perspective around the subject, making the background appear to compress or expand while the central subject remains the same size within the frame.
This alteration of visual perception is ideal for conveying tension, disorientation, or fear in the viewer, as it enhances moments of strong emotion that the subject in the scene might be experiencing.
The Technical Breakdown
From a technical point of view, the dolly zoom effect involves three main elements: the foreground subject, the camera, and the background. The initial camera angle provides a specific perspective of the background, creating a relationship between the foreground subject and the background. As you move the camera and adjust the zoom simultaneously, this relationship changes.
There are two ways to replicate this effect:
In this post, we’ll explore the second approach, utilizing changes in zoom to determine the camera’s new position.
Implementing the Dolly Zoom in 3D
Imagine a 3D scene with a small version of Manhattan, generated through simple nested loops creating a grid of meshes.
/**
* Manhattan
*/
const material = new THREE.MeshPhysicalMaterial({ color: 0x7744cb })
const size = 6
for (let i = 0; i < size; i++) {
for (let j = 0; j < size; j++) {
const height = Math.random() * 4 + 1
const geometry = new THREE.BoxGeometry(1, height, 1)
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(-size + i * 2 + 1, -2.5 + height / 2, -size + j * 2 + 1)
scene.add(mesh)
}
}
The camera starts at a certain position, looking at the center of this grid.
/**
* Camera
*/
const fov = 90
const camera = new THREE.PerspectiveCamera(
fov,
sizes.width / sizes.height,
0.1,
10000
)
camera.position.set(9, 9, 9)
camera.lookAt(new THREE.Vector3(0, 0, 0))
A variable named “config” with a “progress” property controls an on-screen slider, allowing dynamic adjustment of the camera’s position and zoom.
/**
* GUI
*/
const gui = new GUI({ width: 500 })
const config = {
progress: 0,
}
gui.add(config, 'progress', 0, 1, 0.01).onChange((progress) => {
updateCamera(progress)
})
Consider using trigonometry to calculate the new camera distance when altering the field of view (FOV). The key lies in understanding the relationship between the camera’s initial position, the angle of view, and the resulting perspective transformation. This approach helps maintain the illusion of a consistent subject position while manipulating the perceived depth.
The code
/**
* Dolly zoom
*/
const finalFOV = 0.5
const initialPos = camera.position.clone()
const fovTan = Math.tan(MathUtils.degToRad(fov / 2))
const RATIO = initialPos.length() * fovTan
function updateCamera(progress) {
console.log(progress)
const newFOV = MathUtils.lerp(fov, finalFOV, progress)
const newFovTan = Math.tan(MathUtils.degToRad(newFOV / 2))
const d = RATIO / newFovTan
camera.fov = newFOV
camera.position.normalize().multiplyScalar(d)
camera.updateProjectionMatrix()
}
When applied correctly, the effect makes it seem like the subject remains firmly in place, while the world around shifts dramatically, shifting perspective from a very narrow angle to an almost orthogonal view.
Real-World Applications
This effect isn’t limited to film. By linking Dolly Zoom to web interactions like page scrolling, we can create captivating user experiences. One exciting example is a procedural world project, where scroll-induced acceleration creates an intense sense of speed, achieved by animating the camera’s zoom and position.
Through these steps, you’ve unlocked the potential of Dolly Zoom, opening up a realm of possibilities for adding depth and emotion to your digital creations.
Thank you for reading, and stay tuned for more insights into 3D development and tutorials!
Full code available on gitHub: https://github.com/rock-biter/vertigo-effect-01
Creative Developer
5 个月Gabriele Scaggiante vuoi aggiungere qualche chicca in più su questo argomento legato al mondo dei videogiochi? ??
Sviluppatore creativo e consulente / WebGL, Three.js, Unity / 3D Web Marketing / Configuratori 3D online / Indie gamedev
5 个月Ottimo spunto Gianluca. Lavorare con il FOV può dare davvero molte soddisfazioni. Io questa tecnica la uso in un videogioco a cui sto lavorando (Unity) ed rende tutto molto cinematografico.
Creative Developer
5 个月https://youtu.be/dgCCboHXc3s