前言

在深入理解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的更多相关文章

  1. 深入理解Three.js中透视投影照相机PerspectiveCamera

    前言 在开始正式讲解透视摄像机前,我们先来理理three.js建模的流程.我们在开始创建一个模型的时候,首先需要创建我们模型需要的物体,这个物体可以是three.js中已经为我们封装好的,比如正方体, ...

  2. 深入理解Node.js中的垃圾回收和内存泄漏的捕获

    深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...

  3. 深入理解three.js中光源

    前言: Three.js 是一个封装了 WebGL 接口的非常好的库,简化了 WebGL 很多细节,降低了学习成本,是当前前端开发者完成3D绘图的得力工具,那么今天我就给大家详细讲解下 Three.j ...

  4. 深入理解Three.js中线条Line,LinLoop,LineSegments

    前言 在可视化开发中,无论是2d(canvas)开发还是3d开发,线条的绘制应用都是比较普遍的.比如绘制城市之间的迁徙图,运行轨迹图等.本文主要讲解的是Three.js中三种线条Line,LineLo ...

  5. 深入理解 React JS 中的 setState

    此文主要探讨了 React JS 中的 setState 背后的机制,供深入学习 React 研究之用. 在课程 React.js入门基础与案例开发 中,有些同学会发现 React JS 中的 set ...

  6. 从两个角度理解为什么 JS 中没有函数重载

    函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数.类型.顺序)的函数,这组函数被称为重载函数.重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空 ...

  7. 深入理解 Node.js 中 EventEmitter源码分析(3.0.0版本)

    events模块对外提供了一个 EventEmitter 对象,即:events.EventEmitter. EventEmitter 是NodeJS的核心模块events中的类,用于对NodeJS中 ...

  8. 理解 Node.js 中 Stream(流)

    Stream(流) 是 Node.js 中处理流式数据的抽象接口. stream 模块用于构建实现了流接口的对象. Node.js 提供了多种流对象. 例如,对 HTTP 服务器的request请求和 ...

  9. 理解 backbone.js 中的 bind 和 bindAll 方法,关于如何在方法中指定其中的 this,包含apply方法的说明[转载]

    转载自:http://gxxsite.com/content/view/id/132.html 在backbone.js的学习过程中,被bind和bindAll弄得有点晕,这里包括underscore ...

随机推荐

  1. Python day02 课堂笔记

    今天是第二天学习Python课程,主要从格式化输出,逻辑运算,编码,数据类型 这几个方面来学习. 1.格式化输出: % : 占位符 %s:字符串 %d:数字 注意: 在格式化的输出中,如果要输出%(因 ...

  2. 部署Kettle做ETL开发并使用Crontab制作调度系统

    背景说明: 在数据量较小,且数据源和装载地都是关系型数据库时,使用Kettle做ETL较为简便. 由于调度系统产品因为服务器环境方面的因素,而无法部署,故使用Linux的crontab定时器来制作简易 ...

  3. 设置ABP默认使用中文

    ABP提供的启动模板, 默认使用是英文: 虽然可以通过右上角的菜单切换成中文, 但是对于国内项目来说, 默认使用中文是很正常的需求. 本文介绍了如何实现默认语言的几种方法, 希望能对ABP爱好者有所帮 ...

  4. MSIL实用指南-生成break和continue

    break和continue本质都是标签的跳转

  5. FineReport - 软件安装部署

    FineReport 软件安装与部署 FineReport试用码申请 在浏览器中输入网址:http://www.finereport.com/,进入帆软官网首页,点击免费试用,填写相关信息后,既可以收 ...

  6. netcore 之动态代理(微服务专题)

    动态代理配合rpc技术调用远程服务,不用关注细节的实现,让程序就像在本地调用以用. 因此动态代理在微服务系统中是不可或缺的一个技术.网上看到大部分案例都是通过反射自己实现,且相当复杂.编写和调试相当不 ...

  7. 转载-SpringBoot开发案例之整合日志管理

    转载:https://cloud.tencent.com/developer/article/1097579 有一种力量无人能抵挡,它永不言败生来倔强.有一种理想照亮了迷茫,在那写满荣耀的地方. 00 ...

  8. liunx安装jdk

    jdk 安装包  https://pan.baidu.com/s/1cKnUQGU2Sk2nsARAzzVAHw [root@localhost ~]# tar -zxvf jdk-8u152-lin ...

  9. (二)springMvc原理和手写springMvc框架

    我们从两个方面了解springmvc执行原理,首先我们去熟悉springmvc执行的过程,然后知道原理后通过手写springmvc去深入了解代码中执行过程. (一)SpringMVC流程图 (二)Sp ...

  10. IT项目经理入门心法