Camera position vs zoom vs fov

Hi all,
I have a ThreeJS scene that uses OrbitControls.js to move and zoom a PerspectiveCamera around a target.
I would like to save the camera zoom (or/and fov) values of my application to a local file to be loaded later, but it seems that OrbitControls.js zoom method is based on changing the camera position instead of using camera.zoom or camera.fov properties (these remain unchanged).

My questions are:

  • Is there any advantage in changing the camera position vs zoom or fov?
  • Should I use a different camera controller instead? If so, is there an alternative to OrbitControls.js that uses zoom/fov values?
  • I want my saved value to be as ā€˜standardā€™ as possible. Should I convert (somehow) the camera position to corresponding zoom/fov values or just store the x,y,z position, or all of them?

Iā€™ve talked with @WestLangley about your questions since i was not 100% sure what to say :blush:

OrbitControls transforms a perspective camera when panning, dollying (zooming) or orbiting is performed. Yes, zooming can be implemented differently by changing the zoom/fov properties of the camera object. Instead of moving the camera near (or far) of the target, the camera keeps its position. But conceptually there is no a real advantage of doing this. Itā€™s just a different approach.

I donā€™t think that makes sense. Why are you so focused on zoom/fov?

If you use OrbitControls with a perspective camera, you can just save the transformation of the camera object. Transfer the value of camera.matrix into an array via Matrix4.toArray().

1 Like

Zooming and changing the FOV is the same thing, but they are very different to getting near/far. There is no ā€œcorrespondingā€ camera position to FOV/zoom values, they are simply doing different things.
If you want to understand it visually, you should take a real camera, use the zoom in and out, and then moving forward backward: the difference in perspective should be apparent.
So, to answer your question: if you really need a zoom/fov control, you should modify the OrbitController (itā€™s very easy, look for the place where the distance to the object is changed by the controls and change the camera FOV instead).

I found a couple of videos explaining the difference of zooming vs dollying (the action of moving the camera in filmmaking terms):


And there is also the famous dolly-zoom effect (invented during a Hitchcockā€™s movie): https://en.wikipedia.org/wiki/Dolly_zoom

2 Likes

When I change the zoom of a PerspectiveCamera, the field of view remains unchanged, but Iā€™m not entirely sure thatā€™s right. Shouldnā€™t the fov property be updated if I change the zoom?

For instance:

var camera = new THREE.PerspectiveCamera( 90, width / height, 1, 1000 );
console.log(camera.fov); // <- Outputs 90
camera.zoom = 2;
camera.updateProjectionMatrix();
console.log(camera.fov); // <- Outputs 90, but shouldn't it be 45 now?

is the same as this:
zoom2

Is this the correct behavior?

Well no, itā€™s the difference between having

var zoom = 1 
var fov = 45

function doStuff(){
  return fov / zoom
}

vs

var fov  = 45
function doStuff(zoom){
  zoom = zoom || 1
  return fov / zoom 
}

You could override your own setFOV method to use a private _zoom property, so that every time you set fov to something, it considers the zoom but i think this would be a pretty bad pattern, when you can probably already do something like

camera.fov = myFov / myZoom

and just keep zoom at 1. Think of it like a ā€œdigital zoomā€ some digital cameras have. Up to a point you can modify the lens, and then you can blow up the pixels themselves (the lens stays the same).