您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
一個(gè)場(chǎng)景之所以會(huì)呈現(xiàn)在我們眼前是因?yàn)槲覀兙哂醒劬?,眼睛提供了視覺(jué)。換句話說(shuō),如果three.js場(chǎng)景中沒(méi)有這雙眼睛,就像電影沒(méi)有攝像機(jī)一樣,場(chǎng)景就無(wú)法呈現(xiàn)在我們面前?這雙眼睛就是相機(jī),可見(jiàn)相機(jī)是Three.js場(chǎng)景中不可或缺的一個(gè)組件。Three.js庫(kù)提供了兩種不同的相機(jī):正交投影相機(jī)和透視投影相機(jī),接下來(lái)分別講解這兩種相機(jī)以及結(jié)合實(shí)例的應(yīng)用。
我們先來(lái)看一張示意圖:
由圖可知正交透視相機(jī)總共有6個(gè)面,其具備的特點(diǎn)是:場(chǎng)景中遠(yuǎn)處的物體和近處的物體是一樣大的,它并不像我們現(xiàn)實(shí)生活中看場(chǎng)景那樣,遠(yuǎn)小近大,而是遠(yuǎn)近皆一樣大;6個(gè)面分別為left(左面),right(右面),top(頂面),bottom(底面),near(近面),near(遠(yuǎn)面),右這六個(gè)面組成一個(gè)封閉的矩形空間,在這個(gè)空間內(nèi)的一切物體都可見(jiàn)。在設(shè)置其參數(shù)的時(shí)候,下面的關(guān)系式一定要成立:
| left / right | = 1,| top / buttom | = 1
正交相機(jī)的代碼實(shí)現(xiàn)為:
var camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
投射投影相機(jī)才是現(xiàn)實(shí)世界中我們看到的場(chǎng)景的體現(xiàn):遠(yuǎn)小近大,即我們所說(shuō)的透視效果。先來(lái)看一張示意圖:
如圖中所示,透視投影相機(jī)一共有4個(gè)參數(shù):fov(視場(chǎng),一個(gè)角度值), Horizonta Field of View(橫向視場(chǎng)),Vertical
Field of View(縱向視場(chǎng)),Near plane(近面), Far plane(遠(yuǎn)面);由這幾個(gè)因素,構(gòu)成一個(gè)六面體的封閉空間,在這個(gè)空間內(nèi)的一切物體可見(jiàn)。在設(shè)置參數(shù)時(shí),需滿足:
橫向視場(chǎng) / 縱向視場(chǎng) = 瀏覽器窗口的寬/瀏覽器窗口的高。
其代碼實(shí)現(xiàn)為:
var camera = new THREE.PerspectiveCamera(fov, width / height, near, far);
這里實(shí)現(xiàn)兩種相機(jī)的應(yīng)用,里面添加了一個(gè)簡(jiǎn)單的交互條,實(shí)現(xiàn)的效果如下圖:
本例代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>threejs-camera</title> <style> body{ font-family: Monospace; backgroud: #f0f0f0; margin: 0px; overflow: hidden; } </style> </head> <body> <script type="text/javascript" src="build/three.js"></script> <script type="text/javascript" src="js/Detector.js"></script> <script type="text/javascript" src="js/libs/dat.gui.min.js"></script> <script type="text/javascript"> //檢測(cè)webgl的支持情況 if(!Detector.webgl) {Detector.addGetWebGLMessage();} var container; var scene, camera, renderer; window.onload = function main(){ //添加一個(gè)div元素 container = document.createElement('div'); document.body.appendChild(container); //創(chuàng)建新場(chǎng)景 scene = new THREE.Scene(); //渲染 //antialias:true增加抗鋸齒效果 renderer = new THREE.WebGLRenderer({antialias:true}); renderer.setClearColor(new THREE.Color(0x3399CC));//設(shè)置窗口背景顏色為黑 renderer.setSize(window.innerWidth, window.innerHeight);//設(shè)置窗口尺寸 //將renderer關(guān)聯(lián)到container,這個(gè)過(guò)程類似于獲取canvas元素 container.appendChild(renderer.domElement); perCamera(); light(); myScene(); render(); }; //創(chuàng)建一個(gè)透視相機(jī) function perCamera(){ camera = new THREE.PerspectiveCamera(25, window.innerWidth/window.innerHeight, 1, 1000); camera.position.set(150, 180, 100);//設(shè)置相機(jī)位置 camera.lookAt(scene.position);//讓相機(jī)指向場(chǎng)景中心 } //創(chuàng)建一個(gè)正交投影相機(jī) function orthCamera(){ camera = new THREE.OrthographicCamera(window.innerWidth/-14.5,window.innerWidth/14.5, window.innerHeight/14.5,window.innerHeight/-14.5,-100,400); camera.position.set(150,180, 100);//設(shè)置相機(jī)坐標(biāo) camera.lookAt(scene.position);//讓相機(jī)指向場(chǎng)景中心 } //燈光 function light(){ //自然光 var ambientLight = new THREE.AmbientLight( 0x606060 ); scene.add( ambientLight ); //平行光源 var directionalLight = new THREE.DirectionalLight( 0xffffff ); directionalLight.position.set( 1, 1.75, 0.5 ).normalize(); scene.add( directionalLight ); } //創(chuàng)建一個(gè)立體場(chǎng)景 function myScene(){ //創(chuàng)建平面 var planeGeo = new THREE.PlaneGeometry(100,100,10,10);//創(chuàng)建平面 var planeMat = new THREE.MeshLambertMaterial({ //創(chuàng)建材料 color:0x999999, wireframe:false }); var planeMesh = new THREE.Mesh(planeGeo, planeMat);//創(chuàng)建網(wǎng)格模型 planeMesh.position.set(0, 0, -20);//設(shè)置平面的坐標(biāo) planeMesh.rotation.x = -0.5 * Math.PI;//將平面繞X軸逆時(shí)針旋轉(zhuǎn)90度 scene.add(planeMesh);//將平面添加到場(chǎng)景中 //創(chuàng)建立方體 var cubeGeo1 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//創(chuàng)建立方體 var cubeMat1 = new THREE.MeshLambertMaterial({//創(chuàng)建材料 color:0x333333, wireframe:false }); var cubeMesh2 = new THREE.Mesh(cubeGeo1, cubeMat1);//創(chuàng)建立方體網(wǎng)格模型 cubeMesh2.position.set(15, 10, 0);//設(shè)置立方體的坐標(biāo) scene.add(cubeMesh2);//將立方體添加到場(chǎng)景中 var cubeGeo2 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//創(chuàng)建立方體 var cubeMat2 = new THREE.MeshLambertMaterial({//創(chuàng)建材料 color:0x333333, wireframe:false }); var cubeMesh3 = new THREE.Mesh(cubeGeo2, cubeMat2);//創(chuàng)建立方體網(wǎng)格模型 cubeMesh3.position.set(-25, 16, 0);//設(shè)置立方體的坐標(biāo) scene.add(cubeMesh3);//將立方體添加到場(chǎng)景中 var cubeGeo3 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//創(chuàng)建立方體 var cubeMat3 = new THREE.MeshLambertMaterial({//創(chuàng)建材料 color:0x333333, wireframe:false }); var cubeMesh4 = new THREE.Mesh(cubeGeo3, cubeMat3);//創(chuàng)建立方體網(wǎng)格模型 cubeMesh4.position.set(10, 20, -40);//設(shè)置立方體的坐標(biāo) scene.add(cubeMesh4);//將立方體添加到場(chǎng)景中 } //添加交互工具條 var controls = new function(){ this.相機(jī) = false; }; var gui = new dat.GUI(); gui.add(controls, '相機(jī)', ["透視投影相機(jī)","正交投影相機(jī)"]).onChange(function(e){ switch (e) { case "正交投影相機(jī)": orthCamera(); break; case "透視投影相機(jī)": perCamera(); break; } }); function render(){ renderer.render(scene, camera); requestAnimationFrame(render); } </script> </body> </html>
讀到這里,這篇“three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。