如何将正交相机转换为透视相机并恢复?

4
我正在使用CombinedCamera.js和OrbitControls.js。链接如下: https://github.com/mrdoob/three.js/blob/master/examples/js/cameras/CombinedCamera.js https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js 我已经成功切换相机,并且两者都可以缩放,但是orbitcontrols会重新定位透视相机以模拟缩放,而不是像正交相机那样改变fov等属性。
这导致了透视模式下视锥远平面的移动(我需要这个功能),而在正交模式下则没有移动(我需要它移动)。
我通过重新定位透视和正交相机来解决这个问题。正交相机并不使用位置来确定缩放因此存在问题。
问题在于当我在两个相机之间切换时,它们的缩放程度似乎不同。
我的问题是如何让正交相机依赖相机位置来确定缩放量,以便它始终具有与透视相机类似的缩放程度?
1个回答

1

好的,经过多次尝试,我找到了一个近似的方法来获得结果。我意外地发现,如果远截面值设置为25,它将完美地工作...所以我制定了一个方程来补偿如果值不同。虽然不是完美的,但也足够接近了,也许有人可以看出它在哪里可以改进?

我在combinedcamera.js中进行了替换。

halfHeight /= this.zoom;
halfWidth /= this.zoom;

带有。
halfHeight /= ((this.cameraP.far/25)*this.zoom);
halfWidth /= ((this.cameraP.far/25)*this.zoom);

我在combinedcamera.js中添加了这一行代码。

this.cameraO.far = this.cameraP.far+((this.cameraP.far/25)*this.zoom)-0.5;

在此之前

this.cameraO.updateProjectionMatrix();

这是完整的部分。
 THREE.CombinedCamera.prototype.toOrthographic = function () {

// Switches to the Orthographic camera estimating viewport from Perspective

var fov = this.fov;
var aspect = this.cameraP.aspect;
var near = this.cameraP.near;
var far = this.cameraP.far;

// The size that we set is the mid plane of the viewing frustum

var hyperfocus = ( near + far ) / 2;

var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
var planeHeight = 2 * halfHeight;
var planeWidth = planeHeight * aspect;
var halfWidth = planeWidth / 2;

halfHeight /= ((this.cameraP.far/25)*this.zoom);
halfWidth /= ((this.cameraP.far/25)*this.zoom);

this.cameraO.left = -halfWidth;
this.cameraO.right = halfWidth;
this.cameraO.top = halfHeight;
this.cameraO.bottom = -halfHeight;

// this.cameraO.left = -farHalfWidth;
// this.cameraO.right = farHalfWidth;
// this.cameraO.top = farHalfHeight;
// this.cameraO.bottom = -farHalfHeight;

// this.cameraO.left = this.left / this.zoom;
// this.cameraO.right = this.right / this.zoom;
// this.cameraO.top = this.top / this.zoom;
// this.cameraO.bottom = this.bottom / this.zoom;

this.cameraO.far = this.cameraP.far+((this.cameraP.far/25)*this.zoom)-0.5;
this.cameraO.updateProjectionMatrix();

this.near = this.cameraO.near;
this.far = this.cameraO.far;
this.projectionMatrix = this.cameraO.projectionMatrix;

this.inPerspectiveMode = false;
this.inOrthographicMode = true;

 };

我将this.zoom更改为透视相机的1。

 THREE.CombinedCamera.prototype.toPerspective = function () {

// Switches to the Perspective Camera

this.near = this.cameraP.near;
this.far = this.cameraP.far;

this.cameraP.fov =  this.fov / 1 ;

this.cameraP.updateProjectionMatrix();

this.projectionMatrix = this.cameraP.projectionMatrix;

this.inPerspectiveMode = true;
this.inOrthographicMode = false;

 };

另外,我不得不调整orbitcontrols。
this.dollyIn = function ( dollyScale ) {

    if ( dollyScale === undefined ) {

        dollyScale = getZoomScale();

    }

        scale /= dollyScale;
        scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom * dollyScale ) );
};

this.dollyOut = function ( dollyScale ) {

    if ( dollyScale === undefined ) {

        dollyScale = getZoomScale();

    }

        scale *= dollyScale;
        scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / dollyScale ) );
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接