将threejs透视相机转换为正交

时间:2018-02-13 03:28:55

标签: javascript three.js camera perspective orthographic

我有将透视相机转换为正交相机的代码。问题是,当我转换它们时,模型变得非常小,很难看到。

我根据距离和FOV计算了正交相机的缩放系数。我需要在正交相机上设置任何其他属性。即剪裁平面等。我相信位置保持不变。我不确定还需要计算什么。

                fieldOfView = viewInfo.fov;
                var getCameraPosition = function() {
                    return viewer._viewport._implementation.getCamera()._nativeCamera.position;
                };

                // Calculate the delta position between the camera and the object
                var getPositionDelta = function(position1, position2) {
                    return {
                        x: position1.x - position2.x,
                        y: position1.y - position2.y,
                        z: position1.z - position2.z
                    }
                };

                var getDistance = function(positionDelta, cameraDirection) {
                    return dot(positionDelta, cameraDirection);
                };

                distance = getDistance(positionDelta, cameraDirection),
                var depth = distance;

                var viewportWidth = view.getDomRef().getBoundingClientRect().width;
                var viewportHeight = view.getDomRef().getBoundingClientRect().height;
                var aspect = viewportWidth / viewportHeight;

                var height_ortho = depth * 2 * Math.atan( fieldOfView * (Math.PI/180) / 2 )
                var width_ortho  = height_ortho * aspect;

                var near = viewInfo.near, far = viewInfo.far;
                var newCamera = new THREE.OrthographicCamera(
                    width_ortho  / -2, width_ortho   /  2,
                    height_ortho /  2, height_ortho  / -2,
                    near, far );


                newCamera.position.copy( viewInfo.position );
                var sCamera = new vk.threejs.OrthographicCamera(); //framework creatio of threejs cam

                sCamera.setZoomFactor(orthoZoomFactor);
                sCamera.setCameraRef(newCamera);
                view.getViewport().setCamera(sCamera);                  


                fieldOfView = viewInfo.fov;
                var getCameraPosition = function() {
                    return viewer._viewport._implementation.getCamera()._nativeCamera.position;
                };

                // Calculate the delta position between the camera and the object
                var getPositionDelta = function(position1, position2) {
                    return {
                        x: position1.x - position2.x,
                        y: position1.y - position2.y,
                        z: position1.z - position2.z
                    }
                };

                var getDistance = function(positionDelta, cameraDirection) {
                    return dot(positionDelta, cameraDirection);
                };

                distance = getDistance(positionDelta, cameraDirection),
                var depth = distance;

                var viewportWidth = view.getDomRef().getBoundingClientRect().width;
                var viewportHeight = view.getDomRef().getBoundingClientRect().height;
                var aspect = viewportWidth / viewportHeight;

                var height_ortho = depth * 2 * Math.atan( fieldOfView * (Math.PI/180) / 2 )
                var width_ortho  = height_ortho * aspect;

                var near = viewInfo.near, far = viewInfo.far;
                var newCamera = new THREE.OrthographicCamera(
                    width_ortho  / -2, width_ortho   /  2,
                    height_ortho /  2, height_ortho  / -2,
                    near, far );


                newCamera.position.copy( viewInfo.position );
                var sCamera = new vk.threejs.OrthographicCamera(); //framework creatio of threejs cam

                sCamera.setZoomFactor(orthoZoomFactor);
                sCamera.setCameraRef(newCamera);
                view.getViewport().setCamera(sCamera);

我也尝试设置相同的相机属性,即剪切平面等正视的透视,我仍然有同样的问题。我想我错过了将对象置于透视摄像机视图中的相同位置所需的一些属性或计算。

1 个答案:

答案 0 :(得分:1)

假设您有一个具有给定垂直视角fov_y(以度为单位)的透视图,并且您知道视口widthheight的大小。此外,您拥有nearfar平面。这些是您用于设置THREE.PerspectiveCamera

的值
perspCamera = new THREE.PerspectiveCamera( fov_y, width / height, near, far );

另外,您知道物体的位置和相机的位置。物体不只有一个位置,但您必须为其深度选择一个代表性位置。

首先,您必须计算对象的depth

var v3_object = .... // THREE.Vector3 : positon of the object
var v3_camera = perspCamera.position;

var line_of_sight = new THREE.Vector3();
perspCamera.getWorldDirection( line_of_sight );

var v3_distance = v3_object.clone().sub( v3_camera );
depth = v3_distance.dot( line_of_sight );

然后你必须计算"尺寸"投影到depth处的视口的矩形:

enter image description here

aspect = width / height;

height_ortho = depth * 2 * Math.atan( fov_y*(Math.PI/180) / 2 )
width_ortho  = height_ortho * aspect;

使用这些值可以设置THREE.OrthographicCamera,如下所示:

var orthoCamera = new THREE.OrthographicCamera(
    width_ortho  / -2, width_ortho   /  2,
    height_ortho /  2, height_ortho  / -2,
    near, far );
orthoCamera.position.copy( perspCamera.position ); 


透视摄像机的位置和方向可以像这样对照正交相机:

orthoCamera.position.copy( perspCamera.position );
orthoCamera.quaternion.copy( perspCamera.quaternion ); 

另请参阅stackoverflow问题Three.js - Find the current LookAt of a camera?