原文:https://juejin.cn/post/7231089453695238204?searchId=20241217193043D32C9115C2057FE3AD64
1. 相機類型
Three.js 主要提供了兩種類型的相機:正交相機(OrthographicCamera)和透視相機(PerspectiveCamera)。
1.1 正交相機
正交相機(OrthographicCamera)使用正交投影進行渲染。在正交投影中,物體的大小不會隨著距離的增加而減小,這意味著所有物體在渲染時保持相同的尺寸,不受距離的影響。這種相機在制作 2D 游戲和 CAD 工具等應用中非常有用。

創建正交相機的代碼如下:
1 2 3 4 5 6 7 | const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far); // 正投影相機案例 const width = window.innerWidth; //canvas畫布寬度 const height = window.innerHeight; //canvas畫布高度 const k = width / height; //canvas畫布寬高比 const s = 600; //控制left, right, top, bottom范圍大小 const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000); |
參數(屬性) | 含義 |
---|
left | 渲染空間的左邊界 |
right | 渲染空間的右邊界 |
top | 渲染空間的上邊界 |
bottom | 渲染空間的下邊界 |
near | near屬性表示的是從距離相機多遠的位置開始渲染,一般情況會設置一個很小的值。 默認值0.1 |
far | far屬性表示的是距離相機多遠的位置截止渲染,如果設置的值偏小小,會有部分場景看不到。 默認值2000 |
1.2 透視相機
透視相機(PerspectiveCamera)使用透視投影進行渲染。在透視投影中,物體的大小會隨著距離的增加而減小,這使得遠離相機的物體看起來更小,符合現實世界中的透視效果。這種相機在制作 3D 游戲和仿真應用中非常常見。

創建透視相機的代碼如下:
1 2 3 4 5 6 7 | const camera = new THREE.PerspectiveCamera(fov, aspect, near, far); //透視相機案例 // width和height用來設置Three.js輸出的Canvas畫布尺寸(像素px) const width = 800; //寬度 const height = 500; //高度 // 30:視場角度, width / height:Canvas畫布寬高比, 1:近裁截面, 3000:遠裁截面 const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000); |
參數 | 含義 |
---|
fov | 相機視錐體豎直方向視野角度 |
aspect | 相機視錐體水平方向和豎直方向長度比,一般設置為Canvas畫布寬高比width / height |
near | 相機視錐體近裁截面相對相機距離 |
far | 相機視錐體遠裁截面相對相機距離,far-near構成了視錐體高度方向 |
2. 相機屬性
Three.js 中的相機具有一些基本屬性,這些屬性決定了相機的視角和視野。
2.1 視角(FOV)
僅透視相機具有視角屬性(FOV)。視角表示相機的垂直視野范圍,單位為度。較大的視角值會導致更大的視野,但可能會產生畸變。較小的視角值則會產生更窄的視野和更低的畸變。
2.2 寬高比(Aspect)
僅透視相機具有寬高比屬性。寬高比表示相機水平視野范圍與垂直視野范圍的比值。通常,寬高比應該與渲染目標(如 Canvas 或 WebGLRenderTarget)的寬高比相同,以避免圖像被拉伸或壓縮。
2.3 近裁剪面(Near)和遠裁剪面(Far)
近裁剪面和遠裁剪面定義了相機的渲染范圍。位于近裁剪面之前的物體和位于遠裁剪面之后的物體都不會被渲染。為了提高渲染性能,通常應該盡量將近裁剪面和遠裁剪面之間的距離設置得較小。
3. 不同方向的投影視圖
3.1 x軸方向觀察
1 2 3 4 5 | // 通過UI按鈕改變相機觀察角度 document.getElementById( 'x' ).addEventListener( 'click' , function () { ???? camera.position.set(500, 0, 0); //x軸方向觀察 ???? camera.lookAt(0, 0, 0); //重新計算相機視線方向 }) |
3.2 y軸方向觀察
1 2 3 4 5 | // 通過UI按鈕改變相機觀察角度 document.getElementById( 'y' ).addEventListener( 'click' , function () { ???? camera.position.set(0, 500, 0); //y軸方向觀察 ???? camera.lookAt(0, 0, 0); //重新計算相機視線方向 }) |
3.3 z軸方向觀察z軸方向觀察
1 2 3 4 5 | // 通過UI按鈕改變相機觀察角度 document.getElementById( 'z' ).addEventListener( 'click' , function () { ???? camera.position.set(0, 0, 500); //z軸方向觀察 ???? camera.lookAt(0, 0, 0); //重新計算相機視線方向 }) |
4. 相機動畫(.position和.lookAt())
通過相機對象Camera
的.position
屬性和.lookAt()
方法,可實現一段相機動畫。
4.1 相機運動動畫
改變相機的位置.position
,三維場景在canvas畫布上呈現不同的效果,如果連續改變相機的位置.position
,就可以獲得一個動畫效果。
課件案例源碼是一個工廠模型,相機在空中俯視工廠,如果在渲染循環中不停地改變相機位置,這時候產生的視覺效果,就好比你在天上運動,看地面的效果。
1 2 3 4 5 6 7 | // 渲染循環 function render() { ???? camera.position.z -= 0.3; //相機直線運動動畫 ???? renderer.render(scene, camera); ???? requestAnimationFrame(render); } render(); |
4.2 相機圓周運動相機圓周運動
在渲染循環中,改變相機位置,在XOZ平面上繞著y軸圓周運動。
1 2 3 4 5 6 7 8 9 10 11 12 | // 渲染循環 let angle = 0; //用于圓周運動計算的角度值 const R = 100; //相機圓周運動的半徑 function render() { ???? angle += 0.01; ???? // 相機y坐標不變,在XOZ平面上做圓周運動 ???? camera.position.x = R * Math.cos(angle); ???? camera.position.z = R * Math.sin(angle); ???? renderer.render(scene, camera); ???? requestAnimationFrame(render); } render(); |
4.3 執行lookAt()計算相機視線方向
改變.position
屬性后,如果不執行.lookAt()
方法,相機的觀察方向默認不變。
如果你希望相機圓周運動的同時,改變相機視線方向,保持相機鏡頭始終指向坐標原點或其它位置,需要每次改變.position
屬性后,重新執行一遍.lookAt()
方法
1 2 3 4 5 6 7 8 9 | function render() { ???? angle += 0.01; ???? camera.position.x = R * Math.cos(angle); ???? camera.position.z = R * Math.sin(angle); ???? // .position改變,重新執行lookAt(0,0,0)計算相機視線方向 ???? camera.lookAt(0,0,0); ???? requestAnimationFrame(render); } render(); |
5. 相機控件OrbitControls
通常需要為用戶提供一種直觀的方式來瀏覽和操作場景。OrbitControls 是 Three.js 提供的一種常用的相機控制器,允許用戶通過鼠標或觸摸屏操作來旋轉、平移和縮放場景。
5.1 OrbitControls使用
- 旋轉:拖動鼠標左鍵
- 縮放:滾動鼠標中鍵
- 平移:拖動鼠標右鍵
OrbitControls本質上就是改變相機的參數,比如相機的位置屬性,改變相機位置也可以改變相機拍照場景中模型的角度,實現模型的360度旋轉預覽效果,改變透視投影相機距離模型的距離,就可以改變相機能看到的視野范圍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // 引入軌道控制器擴展庫OrbitControls.js import { OrbitControls } from 'three/addons/controls/OrbitControls.js' ; // 設置相機控件軌道控制器OrbitControls const controls = new OrbitControls(camera, renderer.domElement); // 如果OrbitControls改變了相機參數,重新調用渲染器渲染三維場景 controls.addEventListener( 'change' , function () { ???? renderer.render(scene, camera); //執行渲染操作 ???? console.log( 'camera.position' ,camera.position); }); //監聽鼠標、鍵盤事件 //相關限制方法: controls.enablePan = false ; //禁止平移 controls.enableZoom = false ; //禁止縮放 controls.enableRotate = false ; //禁止旋轉 // 縮放范圍 controls.minZoom = 0.5; controls.maxZoom = 2; // 上下旋轉范圍 controls.minPolarAngle = 0; controls.maxPolarAngle = Math.PI/2; // 左右旋轉范圍 controls.minAzimuthAngle = -Math.PI/2; controls.maxAzimuthAngle = Math.PI/2; //更新方法 function animate() { ?? requestAnimationFrame(animate); ?? // 更新控制器 ?? controls.update(); ?? // 渲染場景 ?? renderer.render(scene, camera); } |
6. 相機控件MapControls
在某些 Three.js 應用中,例如地圖、地形或者 GIS 類型的項目,需要為用戶提供一種直觀且符合習慣的方式來瀏覽和操作場景。MapControls 是一個類似于 Google Maps 風格的相機控制器,允許用戶通過鼠標和觸摸屏操作來平移、縮放和旋轉場景。
6.1 MapControls使用
- 平移:鼠標左鍵拖動
- 旋轉:鼠標右鍵拖動
- 縮放:鼠標中鍵滾動
MapControls本質上就是改變相機的參數,比如相機的位置屬性、相機目標觀察點。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // 引入相機控件`MapControls` import { MapControls } from 'three/addons/controls/OrbitControls.js' ; const controls = new MapControls(camera, renderer.domElement); controls.addEventListener( 'change' , function () { ???? // 鼠標右鍵旋轉時候,查看.position變化 ???? // 鼠標左鍵拖動的時候,查看.position、.target的位置會變化 ???? console.log( 'camera.position' ,camera.position); ???? console.log( 'controls.target' ,controls.target); }); //相關限制方法: controls.enablePan = false ; //禁止平移 controls.enableZoom = false ; //禁止縮放 controls.enableRotate = false ; //禁止旋轉 //相機位置與觀察目標點最小值 controls.minDistance = 200; //相機位置與觀察目標點最大值 controls.maxDistance = 500; // 上下旋轉范圍 controls.minPolarAngle = 0; controls.maxPolarAngle = Math.PI/2; // 左右旋轉范圍 controls.minAzimuthAngle = -Math.PI/2; controls.maxAzimuthAngle = Math.PI/2; //更新方法 function animate() { ?? requestAnimationFrame(animate); ?? // 更新控制器 ?? controls.update(); ?? // 渲染場景 ?? renderer.render(scene, camera); } |
7. 窗口變化的自適應渲染
在開發 Three.js 項目時,我們需要考慮到不同的設備和屏幕尺寸。當用戶調整瀏覽器窗口大小時,我們希望場景能夠自適應地進行調整,以保持正確的比例和尺寸。
要實現自適應渲染,我們需要在瀏覽器窗口大小發生變化時更新相機和渲染器的設置。首先,我們需要為?window
?對象添加一個?resize
?事件監聽器:
1 | window.addEventListener( 'resize' , onWindowResize); |
接下來,我們定義?onWindowResize
?函數。在這個函數中,我們需要完成以下任務:
- 更新相機的寬高比(
aspect
)。 - 更新相機的投影矩陣。
- 更新渲染器的大小。
7.1 正投影相機OrthographicCamera自適應渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // onresize 事件會在窗口被調整大小時發生 function onWindowResize(){ ?? // 重置渲染器輸出畫布canvas尺寸 ?? renderer.setSize(window.innerWidth,window.innerHeight); ?? // 重置相機投影的相關參數 ?? k = window.innerWidth/window.innerHeight; //窗口寬高比 ?? camera.left = -s*k; ?? camera.right = s*k; ?? camera.top = s; ?? camera.bottom = -s; ?? // 渲染器執行render方法的時候會讀取相機對象的投影矩陣屬性projectionMatrix ?? // 但是不會每渲染一幀,就通過相機的屬性計算投影矩陣(節約計算資源) ?? // 如果相機的一些屬性發生了變化,需要執行updateProjectionMatrix ()方法更新相機的投影矩陣 ?? camera.updateProjectionMatrix (); }; |
7.2 透視投影相機PerspectiveCamera自適應渲染
1 2 3 4 5 6 7 8 9 10 11 | // onresize 事件會在窗口被調整大小時發生 function onWindowResize(){ ?? // 重置渲染器輸出畫布canvas尺寸 ?? renderer.setSize(window.innerWidth,window.innerHeight); ?? // 全屏情況下:設置觀察范圍長寬比aspect為窗口寬高比 ?? camera.aspect = window.innerWidth/window.innerHeight; ?? // 渲染器執行render方法的時候會讀取相機對象的投影矩陣屬性projectionMatrix ?? // 但是不會每渲染一幀,就通過相機的屬性計算投影矩陣(節約計算資源) ?? // 如果相機的一些屬性發生了變化,需要執行updateProjectionMatrix ()方法更新相機的投影矩陣 ?? camera.updateProjectionMatrix (); }; |
以上就是Three.js相機Camera的詳細內容,更多關于Three.js相機Camera的資料請關注腳本之家其它相關文章!
您可能感興趣的文章:
- Three.js引用和環境搭建過程詳解
- Three.js概述和基礎知識學習
- Three.js材質Material類型示例詳解
- Three.js?PBR物理渲染屬性及使用介紹
- Three.js?中的屏幕空間環境光遮蔽SSAO
- Three.js物理引擎Cannon.js創建簡單應用程序
- Three.js中實現Bloom效果及完整示例
- THREE.js添加多個castShadow光源報錯解決及原因分析