深入理解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 ...
随机推荐
- 一文看懂ConstraintLayout的用法
ConstraintLayout 相对于 RelativeLayout来说性能更好,布局上也更加灵活.在最新的Google Android开发文档中是推荐使用 ConstraintLayout的,下面 ...
- 使用CodeBenchmark对逻辑代码进行并发测试
一直对性能测试比较感兴趣,所以也写了不少的测试工具有WebApiBenchmark和TcpBenchmark等;但这些工具测试都是有针对性和配置的方式来进行功能有限所以很难适用更多的场景,所以单独开发 ...
- 怒改springMVC项目为springBoot项目
背景:公司最近在做项目升级,融合所有项目,但是目前使用的一个系统还是最原始的框架 springMVC+spring+mybatis ,前端还是jsp,easyui(技术老的掉牙),终于出手了,结果.. ...
- [Python] Scrapy爬虫框架入门
说明: 本文主要学习Scrapy框架入门,介绍如何使用Scrapy框架爬取页面信息. 项目案例:爬取腾讯招聘页面 https://hr.tencent.com/position.php?&st ...
- php中++ --运算
$x = 5; echo $x; echo "---"; // echo ++$x + $x; //6+6=12 $x=6 // echo ++$x + 5; //6+5=12 $ ...
- HTML 参考手册(摘自菜鸟教程)
标签 描述 基础 <!DOCTYPE> 定义文档类型. <html> 定义一个 HTML 文档 <title> 为文档定义一个标题 <body> ...
- 微信小程序那些令人眼泪汪汪的坑儿
前言 最近做了一个麻雀虽小,五脏俱全的微信小程序项目.一看就会,一用就废的小程序.有些坑真的坑的你两眼泪汪汪.我就爱干前人栽树后人乘凉的事儿,看到文章的你,也许是同道中人,相视一笑:亦或是小程序外围人 ...
- About 睡觉觉吃饭饭
rdc 的日常作息: 11:50 左右起床,洗漱后飞奔到超市买咖啡饼干,然后飞奔到实验室. 开始被比赛打:比赛前期觉没睡醒,题没读懂就开始乱写,签到签不上,比赛中期处于要被饿死的状态. 赛后吃饭饭,随 ...
- 【占坑】IDEA从github 导入并运行 SpringBoot + VUE项目
最近工程实践的项目内容是开发一个类似于博客和bbs论坛的系统,在github上找了一个类似的项目可以照着写一写.所以这里先占着坑,等把后端的数据库连接学完了再来填坑. github项目链接:githu ...
- 快速构建第一个Flink工程
本文简述通过maven和gradle快速构建的Flink工程.建议安装好Flink以后构建自己的Flink项目,安装与示例运行请查看:Flink快速入门--安装与示例运行. 在安装好Flink以后,只 ...