深入理解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

後話

希望上述講解能夠幫助到閱讀這篇博文的讀者!!!

發佈了19 篇原創文章 · 獲贊 4 · 訪問量 4288
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章