深入理解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 ...
随机推荐
- npm install 安装很慢
npm install 安装很慢 设置国内镜像 npm config set registry https://registry.npm.taobao.org npm install
- Collectors.toMap不允许Null Value导致NPE
背景 线上某任务出现报警,报错日志如下: java.lang.NullPointerException: null at java.util.HashMap.merge(HashMap.java:12 ...
- JAVA 获取时间段内的每一天
public class day { public static void main(String[] args) { // TODO Auto-generated method stub Strin ...
- python 10 动态参数
目录 1. 函数的动态参数 1.1 动态位置参数(*arges) 1.2 动态关键字参数 (**kwargs) 1.3 万能传参: 2. 函数的注释 3. 名称空间 4. 函数嵌套 5. 函数变量修改 ...
- 快应用list组件 scrollTo 方法的调用方式
例如,滚动到list 的第4个list-item: this.$element('alist').scrollTo({index:3})
- Python之变量的创建过程
Python之变量的创建过程 一.变量创建过程 首先,当我们定义了一个变量name = 'Kwan'的时候,在内存中其实是做了这样一件事: 程序开辟了一块内存空间,将'Kwan'存储进去,再让变量名n ...
- ResourceManager基本职能和内部架构
YARN也采用了Master/Slave结构,其中,Master实现为ResourceManager,负责整个集群资源的管理与调度:Slave实现为NodeManager,负责单个节点的资源管理与任务 ...
- 【第一篇】spring boot 快速入门
1.开发环境 开发工具:IDEA2018.2.1 JDK:1.9 Maven : 3.3.9 操作系统:window 7 / window 10 2.项目结构 3.详细步骤 3.1 使用IDEA新建M ...
- 使用GPU跑Tensorflow代码实录
使用conda创建一个新的虚拟环境 输入 conda create -n intelligent-judge python=3.6 创建一个python版本为3.6的名字是intelligent-ju ...
- gin-jwt对API进行权限控制
前言 之前文章简单介绍了如何运行gin+vue的前后端分离开源项目,该项目是学习了Gin实践教程后结合vue-element-admin写的,该教程讲得很详细,适合入门Gin.本篇文章将介绍gin+v ...