因項目問題,對webgl進行了探索,當進行到3d相機時,對camera的up,position屬性有部分難以理解的地方,因此做下了記錄。
代碼如下:

1 import React, {Component} from 'react'; 2 import * as Three from "three"; 3 4 const {Vector3} = Three; 5 6 let scene, camera, renderer, container, width, height, light; 7 8 class Lesson3 extends Component { 9 10 initThree = () => { 11 container = document.getElementById('lesson3map'); 12 width = container.clientWidth; 13 height = container.clientHeight; 14 width = width > 1440 ? 1440 : width; 15 height = height > 600 ? 600 : height; 16 renderer = new Three.WebGLRenderer({ 17 antialias: true 18 }); 19 renderer.setSize(width, height); 20 container.appendChild(renderer.domElement); 21 renderer.setClearColor(0xffffff, 1.0) 22 }; 23 24 initCamera = () => { 25 camera = new Three.PerspectiveCamera(45, width / height, 1, 10000); 26 camera.position.set(0, 2000, 0); 27 // camera.up.set(0, 0, 0); 28 camera.lookAt(0, 0, 0); 29 }; 30 31 initScene = () => { 32 scene = new Three.Scene(); 33 }; 34 35 initLight = () => { 36 light = new Three.DirectionalLight(0xff0000, 1.0, 0); 37 light.position.set(100, 100, 200); 38 scene.add(light); 39 }; 40 41 initObject = () => { 42 const geometry = new Three.Geometry(); 43 const p1 = new Vector3(-400, 0, 0); 44 const p2 = new Vector3(400, 0, 0); 45 geometry.vertices.push(p1, p2); 46 47 for (let i = 0; i < 21; i++) { 48 const line = new Three.Line(geometry, new Three.LineBasicMaterial({color: 0x000000, opacity: 0.2})); 49 line.position.z = (i * 40) - 400; 50 scene.add(line); 51 52 const lineV = new Three.Line(geometry, new Three.LineBasicMaterial({color: 0x000000, opacity: 0.2})); 53 lineV.position.x = (i * 40) - 400; 54 lineV.rotation.y = 90 * Math.PI / 180; 55 scene.add(lineV); 56 } 57 }; 58 59 tRender = () => { 60 renderer.clear(); 61 renderer.render(scene, camera); 62 requestAnimationFrame(this.tRender); 63 }; 64 65 draw = () => { 66 this.initThree(); 67 this.initCamera(); 68 this.initScene(); 69 this.initLight(); 70 this.initObject(); 71 this.tRender(); 72 }; 73 74 componentDidMount() { 75 setTimeout(() => { 76 this.draw(); 77 }); 78 } 79 80 render() { 81 return ( 82 <div id="lesson3map" style={{width: '100%', height: '100vh'}}/> 83 ) 84 } 85 } 86 87 export default Lesson3;
initObject:可以看出這是一個在xz二維坐標軸上的20*20方塊,x方向為-400到400,z方向也為-400到400。
initCamera:
PerspectiveCamera(fov?: number, aspect?: number, near?: number, far?: number)有四個參數,我做一下簡單介紹,詳情可自行查閱相關資料。
- fov:眼球張開的角度,0°時相當於閉眼。
- aspect:可視區域橫縱比。
- near:眼睛能看到的最近垂直距離。
- far:眼睛能看到的最遠垂直距離。
camera.position.set(0, 2000, 0); // camera.up.set(0, 0, 0); camera.lookAt(0, 0, 0);
camera.position:設置相機的擺放位置。
camera.lookAt:設置相機望向哪里。
從相機設置可以看出,我們是在y軸上高度為2000的位置,望向原點(0,0,0),因此,觀察到的將是一個正對我們的正方形20*20格子圖。
為了便於理解,我們假設在y軸上俯視原點,我們將看到一個x正方向向右,z正方向像下的坐標系。此處牽扯到camera中up這個屬性的設定,此屬性表示我們以哪個方向作為圖的上方。由於z軸正方向是向下,因此,此圖的up方向為z軸負方向,即可寫為(0,0,-1)。
此時,調整camera.position中的y軸位置,會改變觀察到的方塊大小。相機往左移動時,x值變小;相機往右x值變大;相機往下z值變大;相機往上z值變小,。
因此,我們調整參數為:
camera.position.set(-2000, 2000, 0);
camera.up.set(0, 0, -1);
camera.lookAt(0, 0, 0);
相機此刻在往左移動,由相機位置望向原點,會有一個45°的角度,將會看到一個左邊近,右邊遠的側身圖:
分別調整參數,將會得到其他三種圖以作參考。
// 左側觀察 // camera.position.set(-2000, 2000, 0); // 右側觀察 camera.position.set(2000, 2000, 0); // 上側觀察 // camera.position.set(0, 2000, -2000); // 下側觀察 // camera.position.set(0, 2000, 2000);
於此,相信大家對camera透視相機的position,up參數有一定了解了吧,動手試驗一下吧。有問題可以留言!