# How do i do dolly/Hitchcock/Vertigo zoom using perspective camera?

**URL:** <https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894>\
**Category:** Questions\
**Tags:** zoom, orbit-controls, camera\
**Created:** [November 19, 2021, 5:35am UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894 "2021-11-19T05:35:37Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![orion\_prime](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/orion_prime/32/15785_2.png) [@orion\_prime](https://discourse.threejs.org/u/orion_prime)\
**Post date:** [November 19, 2021, 5:35am UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/1 "2021-11-19T05:35:37Z")

</div>

> **[Dolly zoom](https://en.wikipedia.org/wiki/Dolly_zoom)**
>
> A dolly zoom (also known as a Hitchcock shot, Vertigo shot, Jaws effect,
> or Zolly shot) is an in-camera effect that appears to undermine normal visual perception.
> The effect is achieved by zooming a zoom lens to adjust the angle of view (often referred to as field of view, or FOV) while the camera dollies (moves) toward or away from the subject in such a way as to keep the subject the same size in the frame throughout. In its classic form, the camera angle is pulled away from a subject while th...

as the camera zooms in the fov should goes in the opposite direction.

using lerpVectors i can zoom with orbitcontrols ,  
and  
with orbitcontrols.getDistance() i can get the distance between camera and target

how do i calculate the correct fov change ?

[https://upload.wikimedia.org/wikipedia/commons/transcoded/5/5f/DollyZoomTest.ogv/DollyZoomTest.ogv.480p.vp9.webm](https://upload.wikimedia.org/wikipedia/commons/transcoded/5/5f/DollyZoomTest.ogv/DollyZoomTest.ogv.480p.vp9.webm)

---

<div class="post-metadata">

**Author:** ![looeee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/looeee/32/59_2.png) [@looeee](https://discourse.threejs.org/u/looeee)\
**Post date:** [November 19, 2021, 7:52am UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/2 "2021-11-19T07:52:43Z")

</div>

> [@orion\_prime](#):
>
> how do i calculate the correct fov change ?

There’s a formula on the wiki page you linked:

distance = \frac{width}{2 \tan (\frac{1}{2} \* FOV)}

There are also many results if you search for “calculate fov for hitchcock zoom”. For example, [this page](https://www.noveltech.dev/unity-dolly-zoom-effect/) gives a code sample for Unity which you can adapt for three.js.

---

<div class="post-metadata">

**Author:** ![orion\_prime](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/orion_prime/32/15785_2.png) [@orion\_prime](https://discourse.threejs.org/u/orion_prime)\
**Post date:** [November 19, 2021, 11:11am UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/3 "2021-11-19T11:11:54Z")

</div>

oh the unity example came in handy 👍 👍 👍

here’s a pen [https://codepen.io/optimus007-the-looper/pen/porYyER](https://codepen.io/optimus007-the-looper/pen/porYyER)

how can i auto set the width, based on current camera position ?

[https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/b/7/b7fc4e9df225142a46861375c32a816b82c98f46.mp4](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/b/7/b7fc4e9df225142a46861375c32a816b82c98f46.mp4)

---

<div class="post-metadata">

**Author:** ![orion\_prime](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/orion_prime/32/15785_2.png) [@orion\_prime](https://discourse.threejs.org/u/orion_prime)\
**Post date:** [November 19, 2021, 12:58pm UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/5 "2021-11-19T12:58:00Z")

</div>

current snippet

```javascript
gui.add(camera,'fov',1,180,1).onChange((v)=>{
    camera.updateProjectionMatrix()
    const width=1
    const fov=v
    const distance = width / (2 * Math.tan(THREE.MathUtils.degToRad(fov * 0.5)));

	const lerpDist = distance / controls.getDistance()
	
	camera.position.lerpVectors(controls.target, camera.position, lerpDist)

  })

```

---

<div class="post-metadata">

**Author:** ![looeee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/looeee/32/59_2.png) [@looeee](https://discourse.threejs.org/u/looeee)\
**Post date:** [November 19, 2021, 1:31pm UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/6 "2021-11-19T13:31:51Z")

</div>

You could try this - put in the distance of your object (in world space) to the camera as the z-depth to get the width of the scene at that distance. Then use that width in the calculation.

> [@Functions to calculate the visible width / height at a given z-depth from a perspective camera](https://discourse.threejs.org/t/functions-to-calculate-the-visible-width-height-at-a-given-z-depth-from-a-perspective-camera/269):
>
> These two functions will give you the visible height and width in your scene at a given distance from a PerspectiveCamera. It’s useful if you want to create an object that is the full width / height of the scene, or want to place objects at screen edges etc. Here’s the code (ES6): const visibleHeightAtZDepth = ( depth, camera ) =\> { // compensate for cameras not positioned at z=0 const cameraOffset = camera.position.z; if ( depth \< cameraOffset ) depth -= cameraOffset; else depth += c…

---

<div class="post-metadata">

**Author:** ![orion\_prime](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/orion_prime/32/15785_2.png) [@orion\_prime](https://discourse.threejs.org/u/orion_prime)\
**Post date:** [November 19, 2021, 1:58pm UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/7 "2021-11-19T13:58:32Z")

</div>

`visibleWidthAtZDepth(controller.getDistance(), camera)`

gives huge values , inverse of this also did not work.

updated the pen with width slider to see its effects

[https://codepen.io/optimus007-the-looper/pen/porYyER](https://codepen.io/optimus007-the-looper/pen/porYyER) (same pen as above)

---

<div class="post-metadata">

**Author:** ![looeee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/looeee/32/59_2.png) [@looeee](https://discourse.threejs.org/u/looeee)\
**Post date:** [November 20, 2021, 6:52am UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/8 "2021-11-20T06:52:04Z")

</div>

You should get the distance between the camera and the mesh, not the camera and the target.  
Actually I would recommend removing the controls from the scene while you are working on this, and if you do include them, disable them while doing the zoom. Using `OrbitControls` while doing camera animation is tricky.

You can get the camera distance to the mesh like this:

```javascript
const a = new Vector3();

mesh.getWorldPosition(a);

const distance = camera.position.distanceTo(a);

```

Although in this case, you can also just leave the mesh at (0,0,0), then do:

```javascript
camera.position.set(0, 0, 1);

```

Then the z-depth will be 1.

---

<div class="post-metadata">

**Author:** ![orion\_prime](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/orion_prime/32/15785_2.png) [@orion\_prime](https://discourse.threejs.org/u/orion_prime)\
**Post date:** [November 20, 2021, 10:47am UTC](https://discourse.threejs.org/t/how-do-i-do-dolly-hitchcock-vertigo-zoom-using-perspective-camera/31894/9 "2021-11-20T10:47:02Z")

</div>

right now the target and mesh is at 0,0,0 so that simplifies stuff ,

i kept orbitcontrols cause its easier to handle framing & i’ll put target at the center of mesh bounding box before starting vzoom

so width is the unknown factor , i’ll try to setup a `bounding box size * distance from target * constant factor` as default width …once its in the correct ballpark a gui slider can used to add or remove a bit of width.
