How to Maintaining consistent viewport size when switching between perspective and orthographic cameras using orbitControls?

I have created a CodePen example using Three.js:

In this example, I am switching between a perspective camera and an orthographic camera while using orbitControls. Currently, the change in perspective maintains the same viewing direction, but the distance from the current viewport to the target point is different.



After switching to OrthographicCamera,what I expect in OrthographicCamera:

I know that in an orthographic camera, the viewport size is controlled by the zoom. However, how can I keep the viewport consistent with the perspective camera after switching?

That’s a pretty wild claim :thinking: What’s observable is, that your object fills more screen space in one case, and less screen space in the other.

To get you started I suggest, you familiarize yourself with the concepts (similarities and differences) between true “Zooming”, which involves a change in the cameras focal length and (inherently) field of view (FOV), while camera and object stay in place!

Dollying, OTOH, involves moving the camera along a predefined path, for instance its “line of sight”, towards an object or away from it, while maintaining its FOV.

And then are of course combinations of the two. :sunglasses:

Both can be used to make your contents “fill” you viewport to the same degree.

Three.js functions which may assist you are:


Since your geometry most likely contains coordinates which are closer to the camera than others, you need to decide on a “reference” plane perpendicular to the camera’s line of sight, which you want to keep in place when switching between Orthographic ans Perspective Cameras back and forth.

I would like to express my acknowledgement of the lack of precision in my statement and my gratitude towards your assistance. I have found the solution I was looking for(Camera perspective <-> orthographic toggle in r3f and vanilla three.js · GitHub), although I haven’t fully understood the underlying principles. Nonetheless, I am extremely grateful for your help. :heartpulse:

What principles are you not understanding?

It owns two cameras, the two types you want to switch between. Only one seems to be added to the controls, so perspective could be called “master”.

Each update tick, it decides which logic to call, be it ortho or perspective.

Now this is where it gets a little bit confusing. Ortho always seems to be in zoom 1 but they make the frustrum tight. It’s taking some measurement of the perspective frustrum at some distance. Basically it looks at how tall the camera “pyramid” is, at a distance where the controls target is. This looks weird by just looking at the code.

The controls probably change the frustrum of the perspective camera, and then the ortho code derives the ortho frustum from that. The size of the ortho camera could always be your window size, and zoom could be different.

Think of it as a box and a pyramid. Whenever you make the pyramid wider or narrower, the box adjusts to fit around it as tight as possible. The height of the pyramid is the distance between target and camera.


It actually does change the the object the controls are controlling, but most of this still applies :slight_smile:

1 Like