前言

深入理解Three.js中透视投影照相机PerspectiveCamera那篇文章中讲解了透视投影摄像机的工作原理以及对应一些参数的解答,那篇文章中也说了会单独讲解Three.js中另一种常用的摄像机正交摄像机OrthographicCamera,这篇文章将会详细的讲解正交摄像机的工作原理和其对应参数的用法,当然,为了能够让读者更加直观的理解正交摄像机,我会制作一个与正交摄像机相关的demo来直观的让读者感受正交摄像机的魅力。

原理说明

深入理解Three.js中透视投影照相机PerspectiveCamera文章中提到过正交摄像机和透视投影摄像机最大的区别是投影到的物体大小不受距离的影响,说直白点就是透视投影摄像机投影物体是通过点(下图a),相当于我们的眼睛,距离越远,能够看到的部分也就越小。正交摄像机投影物体是通过平面(下图b),无论距离有多远,投射到二维平面的线始终的是平行的,所以看上去就会感觉物体的大小没有受到任何影响。

正交摄像机参数说明

实现一个简单正交摄像机的代码如下:

1 var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
2 scene.add( camera );

new THREE.OrthographicCamera()构造函数用于创建一个正交摄像机,该构造函数中有六个参数,分别是leftrighttopbottomnearfar

left — 摄像机视锥体左侧面。
right — 摄像机视锥体右侧面。
top — 摄像机视锥体上侧面。
bottom — 摄像机视锥体下侧面。
near — 摄像机视锥体近端面。
far — 摄像机视锥体远端面。

其中,left的值不能够大于right的值,而且leftright设置的值必须位于摄像机position中x坐标的两侧,否则将看不到影像。对应的topbottom也一样,bottom值不能大于top值,且位于摄像机position坐标y值两边,否则也会看不到投影影像。nearfar分别用来设置摄像机近端面和远端面,也就是通常说的最近距离和最远距离。near设置越小,投影的影像就越大,反之则越小。但是near值并不是影响投影物体大小最大的,影响投影物体尺寸最大的还是leftrighttopbottom四个参数,而且也影响投影物体的形状,所以在设置这四个参数的时候,leftright之间的距离和topbottom之间的距离的比例一定要和原始的canvas画布比例相等,不然会导致投影的物体形状变形。

为了能够更好的理解正交摄像机,写了一个小demo,代码如下,代码中我们统一设置摄像机的位置对应xyz坐标为0,15,70。为了能够有比对性,在场景中我创建了一个网格,在网格上创建了一个黄色的球体。接下来我们依次比较下不同情况下的投影。

 1 var scene = new THREE.Scene();
 2 console.log(scene)
 3 var dom = document.getElementById('starry-frame');
 4 //var camera = new THREE.OrthographicCamera( dom.clientWidth / - 15, dom.clientWidth / 15, dom.clientHeight / 15, dom.clientHeight / - 15, 1, 1000 );
 5 var camera = new THREE.PerspectiveCamera( 45, dom.clientWidth / dom.clientHeight, 0.1, 1000 );
 6 camera.position.set(0,15,70);
 7 var renderer = new THREE.WebGLRenderer();
 8 renderer.setSize( dom.clientWidth, dom.clientHeight );
 9 dom.appendChild( renderer.domElement );
10 var geometry = new THREE.SphereGeometry( 5, 32, 32 );
11 var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
12 var sphere = new THREE.Mesh( geometry, material );
13 sphere.position.set(0,5,0)
14 scene.add( sphere );
15 var gridHelper = new THREE.GridHelper(50, 60);
16 gridHelper.rotation.y = -Math.PI / 2;
17 scene.add(gridHelper);
18 function render() {
19   renderer.render(scene,camera)
20   requestAnimationFrame(render)
21 }
22 render()

1 透视投影摄像机模式

其中,第一张图是设置了球体position为0,5,0;第二张图图是设置球体position为0,5,-30。可以看出,在透视投影模式下,物体的大小随着物体距离摄像机的距离而变化,距离越大物体大小越小。

 深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园                    深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园

2 正交投影中leftright距离与topbottom距离比例与原始canvas画布比例关系。

第一张图为leftright距离与topbottom距离比例与原始canvas画布比例相等;第二张图为leftright距离与topbottom距离比例比原始canvas比例大;第三张图为leftright距离与topbottom距离比例小于原始canvas画布比例。从中可以得出我们在使用正交摄像机的时候比例必须要和原始的比例一致,防止映射出的图形变形。

深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园                    深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园          深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园

3 正交摄像机中leftright相加,topbottom相加值与摄像机positionxy坐标关系。

第一张图表示leftright相加值小于摄像机x坐标;第二张图表示leftright值相加大于摄像机x坐标值;第三张图为topbottom相加值大于摄像机y坐标值;第四张图为topbottom相加值小于摄像机y坐标值。可以看出leftrighttopbottom相加值与摄像机中心点坐标有便宜的时候物体的图像和位置都会出现较大误差。

深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园                    深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园          深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园                   深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园

4 正交摄像机中leftrighttopbottom值与摄像机坐标关系。

left值大于摄像机x坐标值,right小于摄像机x坐标值,top大于摄像机y坐标值,bottom小于摄像机y坐标值都将会导致摄像机映射不出物体图像,如下图,可以看到场景中一片漆黑。

深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园

正交摄像机实例

说一说做这个实例的初衷,单纯为了理解正交摄像机的原理通过上面讲述的那个例子就可以了,所以下面的这个实例不仅仅是为了能够让读者更好的理解正交摄像机才去写的。为了能够更好的理解Three.js中正交摄像机,所以就在官网中浏览对应的案例,感觉无论是场景,还是视觉都挺不错的,再加上当时我女儿特别喜欢Three.js中实例中的那只鸟,所以我就决定将两个实力合并在一起,纯粹是为了讨女儿喜欢,要知道女儿高兴了才能不打搅我学习,还望读者海涵。实例中移动的山使用的就是正交摄像机,所以可以看到无论如何移动,对应的山的高度和大小都是不会发生变化的,空中飞翔的鸟通过透视投影摄像机。

实例示意图如下:

深入理解Three.js中正交摄像机OrthographicCamera-冯金伟博客园

实例预览地址:深入理解Three.js中的正交摄像机OrthographicCamera

后话

希望上述讲解能够帮助到阅读这篇博文的读者!!!