three.js中正交与透视投影相机的实战应用指南
作者:coder_路远
前言
一个场景之所以会呈现在我们眼前是因为我们具有眼睛,眼睛提供了视觉。换句话说,如果three.js场景中没有这双眼睛,就像电影没有摄像机一样,场景就无法呈现在我们面前?这双眼睛就是相机,可见相机是Three.js场景中不可或缺的一个组件。Three.js库提供了两种不同的相机:正交投影相机和透视投影相机,接下来分别讲解这两种相机以及结合实例的应用。
1 正交投影相机
我们先来看一张示意图:
由图可知正交透视相机总共有6个面,其具备的特点是:场景中远处的物体和近处的物体是一样大的,它并不像我们现实生活中看场景那样,远小近大,而是远近皆一样大;6个面分别为left(左面),right(右面),top(顶面),bottom(底面),near(近面),near(远面),右这六个面组成一个封闭的矩形空间,在这个空间内的一切物体都可见。在设置其参数的时候,下面的关系式一定要成立:
| left / right | = 1,| top / buttom | = 1
正交相机的代码实现为:
var camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
2 投射投影相机
投射投影相机才是现实世界中我们看到的场景的体现:远小近大,即我们所说的透视效果。先来看一张示意图:
如图中所示,透视投影相机一共有4个参数:fov(视场,一个角度值), Horizonta Field of View(横向视场),Vertical
Field of View(纵向视场),Near plane(近面), Far plane(远面);由这几个因素,构成一个六面体的封闭空间,在这个空间内的一切物体可见。在设置参数时,需满足:
横向视场 / 纵向视场 = 浏览器窗口的宽/浏览器窗口的高。
其代码实现为:
var camera = new THREE.PerspectiveCamera(fov, width / height, near, far);
3 实例
这里实现两种相机的应用,里面添加了一个简单的交互条,实现的效果如下图:
本例代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>threejs-camera</title> <style> body{ font-family: Monospace; backgroud: #f0f0f0; margin: 0px; overflow: hidden; } </style> </head> <body> <script type="text/javascript" src="build/three.js"></script> <script type="text/javascript" src="js/Detector.js"></script> <script type="text/javascript" src="js/libs/dat.gui.min.js"></script> <script type="text/javascript"> //检测webgl的支持情况 if(!Detector.webgl) {Detector.addGetWebGLMessage();} var container; var scene, camera, renderer; window.onload = function main(){ //添加一个div元素 container = document.createElement('div'); document.body.appendChild(container); //创建新场景 scene = new THREE.Scene(); //渲染 //antialias:true增加抗锯齿效果 renderer = new THREE.WebGLRenderer({antialias:true}); renderer.setClearColor(new THREE.Color(0x3399CC));//设置窗口背景颜色为黑 renderer.setSize(window.innerWidth, window.innerHeight);//设置窗口尺寸 //将renderer关联到container,这个过程类似于获取canvas元素 container.appendChild(renderer.domElement); perCamera(); light(); myScene(); render(); }; //创建一个透视相机 function perCamera(){ camera = new THREE.PerspectiveCamera(25, window.innerWidth/window.innerHeight, 1, 1000); camera.position.set(150, 180, 100);//设置相机位置 camera.lookAt(scene.position);//让相机指向场景中心 } //创建一个正交投影相机 function orthCamera(){ camera = new THREE.OrthographicCamera(window.innerWidth/-14.5,window.innerWidth/14.5, window.innerHeight/14.5,window.innerHeight/-14.5,-100,400); camera.position.set(150,180, 100);//设置相机坐标 camera.lookAt(scene.position);//让相机指向场景中心 } //灯光 function light(){ //自然光 var ambientLight = new THREE.AmbientLight( 0x606060 ); scene.add( ambientLight ); //平行光源 var directionalLight = new THREE.DirectionalLight( 0xffffff ); directionalLight.position.set( 1, 1.75, 0.5 ).normalize(); scene.add( directionalLight ); } //创建一个立体场景 function myScene(){ //创建平面 var planeGeo = new THREE.PlaneGeometry(100,100,10,10);//创建平面 var planeMat = new THREE.MeshLambertMaterial({ //创建材料 color:0x999999, wireframe:false }); var planeMesh = new THREE.Mesh(planeGeo, planeMat);//创建网格模型 planeMesh.position.set(0, 0, -20);//设置平面的坐标 planeMesh.rotation.x = -0.5 * Math.PI;//将平面绕X轴逆时针旋转90度 scene.add(planeMesh);//将平面添加到场景中 //创建立方体 var cubeGeo1 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体 var cubeMat1 = new THREE.MeshLambertMaterial({//创建材料 color:0x333333, wireframe:false }); var cubeMesh1 = new THREE.Mesh(cubeGeo1, cubeMat1);//创建立方体网格模型 cubeMesh1.position.set(15, 10, 0);//设置立方体的坐标 scene.add(cubeMesh1);//将立方体添加到场景中 var cubeGeo2 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体 var cubeMat2 = new THREE.MeshLambertMaterial({//创建材料 color:0x333333, wireframe:false }); var cubeMesh2 = new THREE.Mesh(cubeGeo2, cubeMat2);//创建立方体网格模型 cubeMesh2.position.set(-25, 16, 0);//设置立方体的坐标 scene.add(cubeMesh2);//将立方体添加到场景中 var cubeGeo3 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体 var cubeMat3 = new THREE.MeshLambertMaterial({//创建材料 color:0x333333, wireframe:false }); var cubeMesh3 = new THREE.Mesh(cubeGeo3, cubeMat3);//创建立方体网格模型 cubeMesh3.position.set(10, 20, -40);//设置立方体的坐标 scene.add(cubeMesh3);//将立方体添加到场景中 } //添加交互工具条 var controls = new function(){ this.相机 = false; }; var gui = new dat.GUI(); gui.add(controls, '相机', ["透视投影相机","正交投影相机"]).onChange(function(e){ switch (e) { case "正交投影相机": orthCamera(); break; case "透视投影相机": perCamera(); break; } }); function render(){ renderer.render(scene, camera); requestAnimationFrame(render); } </script> </body> </html>
总结
到此这篇关于three.js中正交与透视投影相机的文章就介绍到这了,更多相关three.js正交与透视投影相机内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!