Fixed Zoom Level for Different Screen Widths

I’m working with screen sharing with cesium, and I noticed that it changes the zoom level when the screens are different widths even when the camera is in the exact same position.

These images are taken at the exact same camera positions, however due to the different screen widths, the sports fields are completely different dimensions.

I noticed screen height doesn’t affect the zoom at all; it just cuts off part of the screen. Is there a way to make cesium also do this for screen width?

One thing you could do is define a rectangle for the camera to zoom to, to make sure that’s always visible regardless of the screen dimensions (and you can initiate that camera flight whenever you detect the window dimensions change to keep it there).

For computing the rectangle, are you suggesting that I use the camera’s computeViewRectangle function? If so, will that function also work for when the camera is looking into space?

The horizontal FOVs appear to be the same in both cases. I believe vertical FOV is calculated from the aspect ratio. Since the aspect ratio went from like 2x1 to 4x1 the vertical fov went way down. If you were to have the same FOV ratio in both aspect ratios, you would get a warped view where images would either get stretched or compressed, though perhaps this is preferred over clipping off sections of the view. Alternatively the one with the 4x1 aspect ratio might just use half of their screen. Reminds me of ‘full screen’ movies that didn’t actually show the ‘full scene’.

Thank you, Hyper_Sonic. That fix worked perfectly.
Edit: Spoke too soon. It seems that solution only half works. For screens with similar heights, I can simply divide the horizontal fov by the original aspect ratio / the copy’s aspect ratio. However different screen heights don’t work this way, and for some reason dividing by just the screen widths instead of the heights resolves this, but then the screens with similar heights no longer works,

Attempting to match aspect ratios with screens of different sizes? Say one is 600x600, and another 1200x600, you then reduce the larger viewport or canvas to 600x600?

It would appear that there’s no way to manually adjust vertical FOV (so neither the FOV ratio) without altering the Cesium engine:

Dissecting the formula I now understand why it works:

Math.tan(frustum.fov * 0.5)

tan(ang)=opp/adj by definition
let adj = 1
so opp is half the viewport’s width

say the aspect ratio is 2:1, meaning vertical is half of horizontal, which explains

/ frustum.aspectRatio

Now you have a vertical opposite for an adj of 1, and to get an angle of opp/adj you use atan


If aspectRatio is <= 1 it would appear that horiz and vert fovs would match, which I would think would stretch vertical imagery if height were much more than width.

I think I understand what you’re saying, but now I’m not sure how it worked in the first place. Should I make both the fov and the fovy of the copy screen the same proportion to the aspect ratio as the original screen? Would that even be possible if I can’t change the fovy directly?

I believe you’d have to alter the code in /Source/Core/PerspectiveFrustum.js. As new Cesium versions come out you’d have to keep altering it for each new version if you want to update your app to the new versions. Though using any other fov ratio that doesn’t conform to the aspect ratio will warp the view.

Having a frustum.fovy variable would be nice though, for those not minding how it might warp the view. Perhaps it could be modified as such (adding a frustum.fovy var)

    frustum._fovy = frustum.aspectRatio <= 1
    ? frustum.fov
    : Math.atan(Math.tan(frustum.fov * 0.5) / frustum.aspectRatio)
else {frustum._fovy=frustum.fovy;}

Then you could match the original fovs to the copy fovs regardless of their respective aspect ratios.

Thanks. I’ll go ahead and give that a try.