深入理解Three.js中正交摄像机OrthographicCamera
前言
在深入理解Three.js中透视投影照相机PerspectiveCamera那篇文章中讲解了透视投影摄像机的工作原理以及对应一些参数的解答,那篇文章中也说了会单独讲解Three.js中另一种常用的摄像机正交摄像机OrthographicCamera,这篇文章将会详细的讲解正交摄像机的工作原理和其对应参数的用法,当然,为了能够让读者更加直观的理解正交摄像机,我会制作一个与正交摄像机相关的demo来直观的让读者感受正交摄像机的魅力。
原理说明
深入理解Three.js中透视投影照相机PerspectiveCamera文章中提到过正交摄像机和透视投影摄像机最大的区别是投影到的物体大小不受距离的影响,说直白点就是透视投影摄像机投影物体是通过点(下图a),相当于我们的眼睛,距离越远,能够看到的部分也就越小。正交摄像机投影物体是通过平面(下图b),无论距离有多远,投射到二维平面的线始终的是平行的,所以看上去就会感觉物体的大小没有受到任何影响。
正交摄像机参数说明
实现一个简单正交摄像机的代码如下:
- var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
- scene.add( camera );
new THREE.OrthographicCamera()构造函数用于创建一个正交摄像机,该构造函数中有六个参数,分别是left,right,top,bottom,near,far。
left — 摄像机视锥体左侧面。
right — 摄像机视锥体右侧面。
top — 摄像机视锥体上侧面。
bottom — 摄像机视锥体下侧面。
near — 摄像机视锥体近端面。
far — 摄像机视锥体远端面。
其中,left的值不能够大于right的值,而且left和right设置的值必须位于摄像机position中x坐标的两侧,否则将看不到影像。对应的top和bottom也一样,bottom值不能大于top值,且位于摄像机position坐标y值两边,否则也会看不到投影影像。near和far分别用来设置摄像机近端面和远端面,也就是通常说的最近距离和最远距离。near设置越小,投影的影像就越大,反之则越小。但是near值并不是影响投影物体大小最大的,影响投影物体尺寸最大的还是left,right,top,bottom四个参数,而且也影响投影物体的形状,所以在设置这四个参数的时候,left与right之间的距离和top与bottom之间的距离的比例一定要和原始的canvas画布比例相等,不然会导致投影的物体形状变形。
为了能够更好的理解正交摄像机,写了一个小demo,代码如下,代码中我们统一设置摄像机的位置对应xyz坐标为0,15,70。为了能够有比对性,在场景中我创建了一个网格,在网格上创建了一个黄色的球体。接下来我们依次比较下不同情况下的投影。
- var scene = new THREE.Scene();
- console.log(scene)
- var dom = document.getElementById('starry-frame');
- //var camera = new THREE.OrthographicCamera( dom.clientWidth / - 15, dom.clientWidth / 15, dom.clientHeight / 15, dom.clientHeight / - 15, 1, 1000 );
- var camera = new THREE.PerspectiveCamera( 45, dom.clientWidth / dom.clientHeight, 0.1, 1000 );
- camera.position.set(0,15,70);
- var renderer = new THREE.WebGLRenderer();
- renderer.setSize( dom.clientWidth, dom.clientHeight );
- dom.appendChild( renderer.domElement );
- var geometry = new THREE.SphereGeometry( 5, 32, 32 );
- var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
- var sphere = new THREE.Mesh( geometry, material );
- sphere.position.set(0,5,0)
- scene.add( sphere );
- var gridHelper = new THREE.GridHelper(50, 60);
- gridHelper.rotation.y = -Math.PI / 2;
- scene.add(gridHelper);
- function render() {
- renderer.render(scene,camera)
- requestAnimationFrame(render)
- }
- render()
1 透视投影摄像机模式
其中,第一张图是设置了球体position为0,5,0;第二张图图是设置球体position为0,5,-30。可以看出,在透视投影模式下,物体的大小随着物体距离摄像机的距离而变化,距离越大物体大小越小。
2 正交投影中left,right距离与top,bottom距离比例与原始canvas画布比例关系。
第一张图为left,right距离与top,bottom距离比例与原始canvas画布比例相等;第二张图为left,right距离与top,bottom距离比例比原始canvas比例大;第三张图为left,right距离与top,bottom距离比例小于原始canvas画布比例。从中可以得出我们在使用正交摄像机的时候比例必须要和原始的比例一致,防止映射出的图形变形。
3 正交摄像机中left,right相加,top与bottom相加值与摄像机position中x,y坐标关系。
第一张图表示left与right相加值小于摄像机x坐标;第二张图表示left与right值相加大于摄像机x坐标值;第三张图为top与bottom相加值大于摄像机y坐标值;第四张图为top与bottom相加值小于摄像机y坐标值。可以看出left,right与top,bottom相加值与摄像机中心点坐标有便宜的时候物体的图像和位置都会出现较大误差。
4 正交摄像机中left,right,top,bottom值与摄像机坐标关系。
left值大于摄像机x坐标值,right小于摄像机x坐标值,top大于摄像机y坐标值,bottom小于摄像机y坐标值都将会导致摄像机映射不出物体图像,如下图,可以看到场景中一片漆黑。
正交摄像机实例
说一说做这个实例的初衷,单纯为了理解正交摄像机的原理通过上面讲述的那个例子就可以了,所以下面的这个实例不仅仅是为了能够让读者更好的理解正交摄像机才去写的。为了能够更好的理解Three.js中正交摄像机,所以就在官网中浏览对应的案例,感觉无论是场景,还是视觉都挺不错的,再加上当时我女儿特别喜欢Three.js中实例中的那只鸟,所以我就决定将两个实力合并在一起,纯粹是为了讨女儿喜欢,要知道女儿高兴了才能不打搅我学习,还望读者海涵。实例中移动的山使用的就是正交摄像机,所以可以看到无论如何移动,对应的山的高度和大小都是不会发生变化的,空中飞翔的鸟通过透视投影摄像机。
实例示意图如下:
实例预览地址:深入理解Three.js中的正交摄像机OrthographicCamera
后话
希望上述讲解能够帮助到阅读这篇博文的读者!!!
深入理解Three.js中正交摄像机OrthographicCamera的更多相关文章
- 深入理解Three.js中透视投影照相机PerspectiveCamera
前言 在开始正式讲解透视摄像机前,我们先来理理three.js建模的流程.我们在开始创建一个模型的时候,首先需要创建我们模型需要的物体,这个物体可以是three.js中已经为我们封装好的,比如正方体, ...
- 深入理解Node.js中的垃圾回收和内存泄漏的捕获
深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...
- 深入理解three.js中光源
前言: Three.js 是一个封装了 WebGL 接口的非常好的库,简化了 WebGL 很多细节,降低了学习成本,是当前前端开发者完成3D绘图的得力工具,那么今天我就给大家详细讲解下 Three.j ...
- 深入理解Three.js中线条Line,LinLoop,LineSegments
前言 在可视化开发中,无论是2d(canvas)开发还是3d开发,线条的绘制应用都是比较普遍的.比如绘制城市之间的迁徙图,运行轨迹图等.本文主要讲解的是Three.js中三种线条Line,LineLo ...
- 深入理解 React JS 中的 setState
此文主要探讨了 React JS 中的 setState 背后的机制,供深入学习 React 研究之用. 在课程 React.js入门基础与案例开发 中,有些同学会发现 React JS 中的 set ...
- 从两个角度理解为什么 JS 中没有函数重载
函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数.类型.顺序)的函数,这组函数被称为重载函数.重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空 ...
- 深入理解 Node.js 中 EventEmitter源码分析(3.0.0版本)
events模块对外提供了一个 EventEmitter 对象,即:events.EventEmitter. EventEmitter 是NodeJS的核心模块events中的类,用于对NodeJS中 ...
- 理解 Node.js 中 Stream(流)
Stream(流) 是 Node.js 中处理流式数据的抽象接口. stream 模块用于构建实现了流接口的对象. Node.js 提供了多种流对象. 例如,对 HTTP 服务器的request请求和 ...
- 理解 backbone.js 中的 bind 和 bindAll 方法,关于如何在方法中指定其中的 this,包含apply方法的说明[转载]
转载自:http://gxxsite.com/content/view/id/132.html 在backbone.js的学习过程中,被bind和bindAll弄得有点晕,这里包括underscore ...
随机推荐
- react native 8081 端口号被占
McAfee Agent 占用8081 端口号 公司电脑被标装,McAfee Agent关不掉 sudo lsof -n -i4TCP:8081 sudo launchctl list | grep ...
- DES加解密工具类
这两天在跟友商对接接口,在对外暴露接口的时候,因为友商不需要登录即可访问对于系统来说存在安全隐患,所以需要友商在调用接口的时候需要将数据加密,系统解密验证后才执行业务.所有的加密方式并不是万能的,只是 ...
- python 33 多进程(一)
目录 多进程 1. 进程创建的两种方式 multiprocessing 2. 进程pid (process id) 3. 验证进程之间的空间隔离 4. 进程对象join方法 5. 进程对象其他属性 6 ...
- HDU 1517
题意略. 思路: 我们分别来考虑n取到的各个区间,从而发现其中的规律: [2,9] 明显 Stan 必胜. 但是当n = 9 + 1时,Stan无论如何也不能取胜,并且此时,假设 Stan 取值 x ...
- 算法与数据结构基础 - 贪心(Greedy)
贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...
- python批量处理压缩文件
python批量处理压缩文件 博客小序:在数据的处理中,下载的数据很有可能是许多个压缩文件,自己一个一个解压较为麻烦,最近几日自己在处理一次下载的数据时,遇到大量的压缩数据需要处理,于是利用pytho ...
- Android Studio安卓学习笔记(一)安卓与Android Studio运行第一个项目
一:什么是安卓 1.Android是一种基于Linux的自由及开放源代码的操作系统. 2.Android操作系统最初由AndyRubin开发,主要支持手机. 3.Android一词的本义指“机器人”, ...
- HDU 6364 Ringland
Ringland 题意: 在一个环上有n个男生, n个女生, 现在要求每一个男生与女生配对, 求总代价最小. 题解: 如果2个男生到女生的路交叉了, 那么我们交换这2个男生的路, 总代价是一定会变得小 ...
- codeforces 876 D. Sorting the Coins(线段树(不用线段树写也行线段树写比较装逼))
题目链接:http://codeforces.com/contest/876/problem/D 题解:一道简单的类似模拟的题目.其实就是看右边连出来有多少连续不需要换的假设位置为pos只要找pos- ...
- Codeforces 468 B Two Sets
Two Sets 题意:就是将一对数放进setA, setB中, 如果放进setA的话要求满足 x与a-x都在这个集合里面, 如果放进setB中要求满足x与b-x都在这个集合中. 题解:我们将能放进B ...