Three.js相机
在Threejs中相机的表示是THREE.Camera,它是相机的抽象基类,其子类有两种相机,分别是正投影相机THREE.OrthographicCamera和透视投影相机THREE.PerspectiveCamera。
正投影和透视投影的区别是:透视投影有一个基本点,就是远处的物体比近处的物体小。而正投影远近高低比例都相同。
【注】正投影和透视投影的显示方面的区别:比如有一个正方体,使用正投影则只能看到面向自己的那一面正方形,而使用透视投影则看起来是个正方形,因为远处的比近处的大。
一、正投影相机
正投影的构造函数如下所示:
OrthographicCamera( left, right, top, bottom, near, far )
结合下面一个图,我们来看看,各个参数的意思。
- left:左平面距离相机中心点的垂直距离。从图中可以看出,左平面是屏幕里面的那个平面。
- right:右平面距离相机中心点的垂直距离。从图中可以看出,右平面是屏幕稍微外面一点的那个平面。
- top:顶平面距离相机中心点的垂直距离。上图中的顶平面,是长方体头朝天的平面。
- bottom:底平面距离相机中心点的垂直距离。底平面是头朝地的平面。
- near:近平面距离相机中心点的垂直距离。近平面是左边竖着的那个平面。
- far:远平面距离相机中心点的垂直距离。远平面是右边竖着的那个平面。
有了这些参数和相机中心点,我们这里将相机的中心点又定义为相机的位置。通过这些参数,我们就能够在三维空间中唯一的确定上图的一个长方体。这个长方体也叫做视景体。投影变换的目的就是定义一个视景体,使得视景体外多余的部分裁剪掉,最终图像只是视景体内的有关部分。
好了,看一个简单的例子:
var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); scene.add( camera );
这个例子将浏览器窗口的宽度和高度作为了视景体的高度和宽度,相机正好在窗口的中心点上。这也是我们一般的设置方法,基本上为了方便,我们不会设置其他的值。
二、透视投影相机
透视投影相机的构造函数如下所示:
PerspectiveCamera( fov, aspect, near, far )
如图所示:
- 视角fov:可以理解为眼睛睁开的角度,即,视角的大小,如果设置为0,相当你闭上眼睛了,所以什么也看不到,如果为180,那么可以认为你的视界很广阔,但是在180度的时候,往往物体很小,因为他在你的整个可视区域中的比例变小了。
- 近平面near:这个呢,表示你近处的裁面的距离。补充一下,也可以认为是眼睛距离近处的距离。
- 远平面far:这个呢,表示你远处的裁面。
- 纵横比aspect:实际窗口的纵横比,即宽度除以高度。这个值越大,说明你宽度越大,那么你可能看的是宽银幕电影了,如果这个值小于1,那么可能你看到的是如下的图中的LED屏幕了。
例子如下所示:
var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); scene.add( camera );
三、例子
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/Three.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> var renderer; function initThree() { width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById('canvas-frame').clientHeight; renderer = new THREE.WebGLRenderer({ antialias : true }); renderer.setSize(width, height); document.getElementById('canvas-frame').appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF, 1.0); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); //camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 10, 1000 ); camera.position.x = 0; camera.position.y = 0; camera.position.z = 600; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt({ x : 0, y : 0, z : 0 }); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.AmbientLight(0xFF0000); light.position.set(100, 100, 200); scene.add(light); light = new THREE.PointLight(0x00FF00); light.position.set(0, 0,300); scene.add(light); } var cube; function initObject() { var geometry = new THREE.CylinderGeometry( 70,100,200); var material = new THREE.MeshLambertMaterial( { color:0xFFFFFF} ); var mesh = new THREE.Mesh( geometry,material); mesh.position = new THREE.Vector3(0,0,0); scene.add(mesh); } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); animation(); } function animation() { changeFov(); renderer.render(scene, camera); requestAnimationFrame(animation); } function setCameraFov(fov) { camera.fov = fov; camera.updateProjectionMatrix(); } function changeFov() { var txtFov = document.getElementById("txtFov").value; var val = parseFloat(txtFov); setCameraFov(val); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> <div> Fov:<input type="text" value="45" id="txtFov"/>(0到180的值) </div> </body> </html>