I'm trying to program a three.js scene with a PerspectiveCamera
. The canvas will show a sub-region of the whole camera view and it will also have a zoom factor. I've double checked that my offset numbers are good and the zoom factor makes sense.
At full vertical fit they are
current zoom 1
x 714.4099378881989 y 0 w 3755.1801242236024 h 3888
The offset works perfectly when the zoom is 1 but when the zoom factor is changed, everything goes off the rails. The zoom > 1 also works as expected with no view offset and targeting the center of the frustum. I'm using TrackballControls
but they shouldn't be at play here since I'm setting all values programatically.
The relevant camera update function that three in the PerspectiveCamera
class is
updateProjectionMatrix: function () {
var near = this.near,
top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,
height = 2 * top,
width = this.aspect * height,
left = - 0.5 * width,
view = this.view;
if ( this.view !== null && this.view.enabled ) {
var fullWidth = view.fullWidth,
fullHeight = view.fullHeight;
left += view.offsetX * width / fullWidth;
top -= view.offsetY * height / fullHeight;
width *= view.width / fullWidth;
height *= view.height / fullHeight;
}
var skew = this.filmOffset;
if ( skew !== 0 ) left += near * skew / this.getFilmWidth();
this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
this.projectionMatrixInverse.getInverse( this.projectionMatrix );
},
My initial reaction is that the fov is for the full view but should be adjusted for sub-views or that I should be dividing the zoom by some factor derived from the sub-view size but I'm not sure where to start.
Figured it out.
In my update function I was doing
this.zoom = zoom;
this.setViewOffset(
full.w,
full.h,
offset.x,
offset.y,
offset.w,
offset.h
);
this.controls.update();
but what I needed to do was change the zoom so that it was relative to the offset
this.zoom = zoom * (offset.h / full.h)