欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Three.js相機(jī)Camera控件知識(shí)梳理

 更新時(shí)間:2023年05月11日 10:52:24   作者:士必弘毅  
這篇文章主要為大家介紹了Three.js相機(jī)Camera控件知識(shí)梳理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1. 相機(jī)類型

Three.js 主要提供了兩種類型的相機(jī):正交相機(jī)(OrthographicCamera)和透視相機(jī)(PerspectiveCamera)。

1.1 正交相機(jī)

正交相機(jī)(OrthographicCamera)使用正交投影進(jìn)行渲染。在正交投影中,物體的大小不會(huì)隨著距離的增加而減小,這意味著所有物體在渲染時(shí)保持相同的尺寸,不受距離的影響。這種相機(jī)在制作 2D 游戲和 CAD 工具等應(yīng)用中非常有用。

創(chuàng)建正交相機(jī)的代碼如下:

const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
// 正投影相機(jī)案例
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);
參數(shù)(屬性)含義
left渲染空間的左邊界
right渲染空間的右邊界
top渲染空間的上邊界
bottom渲染空間的下邊界
nearnear屬性表示的是從距離相機(jī)多遠(yuǎn)的位置開始渲染,一般情況會(huì)設(shè)置一個(gè)很小的值。 默認(rèn)值0.1
farfar屬性表示的是距離相機(jī)多遠(yuǎn)的位置截止渲染,如果設(shè)置的值偏小小,會(huì)有部分場景看不到。 默認(rèn)值2000

1.2 透視相機(jī)

透視相機(jī)(PerspectiveCamera)使用透視投影進(jìn)行渲染。在透視投影中,物體的大小會(huì)隨著距離的增加而減小,這使得遠(yuǎn)離相機(jī)的物體看起來更小,符合現(xiàn)實(shí)世界中的透視效果。這種相機(jī)在制作 3D 游戲和仿真應(yīng)用中非常常見。

創(chuàng)建透視相機(jī)的代碼如下:

const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
//透視相機(jī)案例
// width和height用來設(shè)置Three.js輸出的Canvas畫布尺寸(像素px)
const width = 800; //寬度
const height = 500; //高度
// 30:視場角度, width / height:Canvas畫布寬高比, 1:近裁截面, 3000:遠(yuǎn)裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
參數(shù)含義
fov相機(jī)視錐體豎直方向視野角度
aspect相機(jī)視錐體水平方向和豎直方向長度比,一般設(shè)置為Canvas畫布寬高比width / height
near相機(jī)視錐體近裁截面相對(duì)相機(jī)距離
far相機(jī)視錐體遠(yuǎn)裁截面相對(duì)相機(jī)距離,far-near構(gòu)成了視錐體高度方向

2. 相機(jī)屬性

Three.js 中的相機(jī)具有一些基本屬性,這些屬性決定了相機(jī)的視角和視野。

2.1 視角(FOV)

僅透視相機(jī)具有視角屬性(FOV)。視角表示相機(jī)的垂直視野范圍,單位為度。較大的視角值會(huì)導(dǎo)致更大的視野,但可能會(huì)產(chǎn)生畸變。較小的視角值則會(huì)產(chǎn)生更窄的視野和更低的畸變。

2.2 寬高比(Aspect)

僅透視相機(jī)具有寬高比屬性。寬高比表示相機(jī)水平視野范圍與垂直視野范圍的比值。通常,寬高比應(yīng)該與渲染目標(biāo)(如 Canvas 或 WebGLRenderTarget)的寬高比相同,以避免圖像被拉伸或壓縮。

2.3 近裁剪面(Near)和遠(yuǎn)裁剪面(Far)

近裁剪面和遠(yuǎn)裁剪面定義了相機(jī)的渲染范圍。位于近裁剪面之前的物體和位于遠(yuǎn)裁剪面之后的物體都不會(huì)被渲染。為了提高渲染性能,通常應(yīng)該盡量將近裁剪面和遠(yuǎn)裁剪面之間的距離設(shè)置得較小。

3. 不同方向的投影視圖

3.1 x軸方向觀察

// 通過UI按鈕改變相機(jī)觀察角度
document.getElementById('x').addEventListener('click', function () {
    camera.position.set(500, 0, 0); //x軸方向觀察
    camera.lookAt(0, 0, 0); //重新計(jì)算相機(jī)視線方向
})

3.2 y軸方向觀察

// 通過UI按鈕改變相機(jī)觀察角度
document.getElementById('y').addEventListener('click', function () {
    camera.position.set(0, 500, 0); //y軸方向觀察
    camera.lookAt(0, 0, 0); //重新計(jì)算相機(jī)視線方向
})

3.3 z軸方向觀察z軸方向觀察

// 通過UI按鈕改變相機(jī)觀察角度
document.getElementById('z').addEventListener('click', function () {
    camera.position.set(0, 0, 500); //z軸方向觀察
    camera.lookAt(0, 0, 0); //重新計(jì)算相機(jī)視線方向
})

4. 相機(jī)動(dòng)畫(.position和.lookAt())

通過相機(jī)對(duì)象Camera.position屬性和.lookAt()方法,可實(shí)現(xiàn)一段相機(jī)動(dòng)畫。

4.1 相機(jī)運(yùn)動(dòng)動(dòng)畫

改變相機(jī)的位置.position,三維場景在canvas畫布上呈現(xiàn)不同的效果,如果連續(xù)改變相機(jī)的位置.position,就可以獲得一個(gè)動(dòng)畫效果。

課件案例源碼是一個(gè)工廠模型,相機(jī)在空中俯視工廠,如果在渲染循環(huán)中不停地改變相機(jī)位置,這時(shí)候產(chǎn)生的視覺效果,就好比你在天上運(yùn)動(dòng),看地面的效果。

// 渲染循環(huán)
function render() {
    camera.position.z -= 0.3;//相機(jī)直線運(yùn)動(dòng)動(dòng)畫
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

4.2 相機(jī)圓周運(yùn)動(dòng)相機(jī)圓周運(yùn)動(dòng)

在渲染循環(huán)中,改變相機(jī)位置,在XOZ平面上繞著y軸圓周運(yùn)動(dòng)。

// 渲染循環(huán)
let angle = 0; //用于圓周運(yùn)動(dòng)計(jì)算的角度值
const R = 100; //相機(jī)圓周運(yùn)動(dòng)的半徑
function render() {
    angle += 0.01;
    // 相機(jī)y坐標(biāo)不變,在XOZ平面上做圓周運(yùn)動(dòng)
    camera.position.x = R * Math.cos(angle);
    camera.position.z = R * Math.sin(angle);
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

4.3 執(zhí)行l(wèi)ookAt()計(jì)算相機(jī)視線方向

改變.position屬性后,如果不執(zhí)行.lookAt()方法,相機(jī)的觀察方向默認(rèn)不變。

如果你希望相機(jī)圓周運(yùn)動(dòng)的同時(shí),改變相機(jī)視線方向,保持相機(jī)鏡頭始終指向坐標(biāo)原點(diǎn)或其它位置,需要每次改變.position屬性后,重新執(zhí)行一遍.lookAt()方法

function render() {
    angle += 0.01;
    camera.position.x = R * Math.cos(angle);
    camera.position.z = R * Math.sin(angle);
    // .position改變,重新執(zhí)行l(wèi)ookAt(0,0,0)計(jì)算相機(jī)視線方向
    camera.lookAt(0,0,0);
    requestAnimationFrame(render);
}
render();

5. 相機(jī)控件OrbitControls

通常需要為用戶提供一種直觀的方式來瀏覽和操作場景。OrbitControls 是 Three.js 提供的一種常用的相機(jī)控制器,允許用戶通過鼠標(biāo)或觸摸屏操作來旋轉(zhuǎn)、平移和縮放場景。

5.1 OrbitControls使用

  • 旋轉(zhuǎn):拖動(dòng)鼠標(biāo)左鍵
  • 縮放:滾動(dòng)鼠標(biāo)中鍵
  • 平移:拖動(dòng)鼠標(biāo)右鍵

OrbitControls本質(zhì)上就是改變相機(jī)的參數(shù),比如相機(jī)的位置屬性,改變相機(jī)位置也可以改變相機(jī)拍照?qǐng)鼍爸心P偷慕嵌?,?shí)現(xiàn)模型的360度旋轉(zhuǎn)預(yù)覽效果,改變透視投影相機(jī)距離模型的距離,就可以改變相機(jī)能看到的視野范圍。

// 引入軌道控制器擴(kuò)展庫OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 設(shè)置相機(jī)控件軌道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改變了相機(jī)參數(shù),重新調(diào)用渲染器渲染三維場景
controls.addEventListener('change', function () {
    renderer.render(scene, camera); //執(zhí)行渲染操作
    console.log('camera.position',camera.position);
});//監(jiān)聽鼠標(biāo)、鍵盤事件
//相關(guān)限制方法:
controls.enablePan = false; //禁止平移
controls.enableZoom = false;//禁止縮放
controls.enableRotate = false; //禁止旋轉(zhuǎn)
// 縮放范圍
controls.minZoom = 0.5;
controls.maxZoom = 2;
// 上下旋轉(zhuǎn)范圍
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI/2;
// 左右旋轉(zhuǎn)范圍
controls.minAzimuthAngle = -Math.PI/2;
controls.maxAzimuthAngle = Math.PI/2;
//更新方法
function animate() {
  requestAnimationFrame(animate);
  // 更新控制器
  controls.update();
  // 渲染場景
  renderer.render(scene, camera);
}

6. 相機(jī)控件MapControls

在某些 Three.js 應(yīng)用中,例如地圖、地形或者 GIS 類型的項(xiàng)目,需要為用戶提供一種直觀且符合習(xí)慣的方式來瀏覽和操作場景。MapControls 是一個(gè)類似于 Google Maps 風(fēng)格的相機(jī)控制器,允許用戶通過鼠標(biāo)和觸摸屏操作來平移、縮放和旋轉(zhuǎn)場景。

6.1 MapControls使用

  • 平移:鼠標(biāo)左鍵拖動(dòng)
  • 旋轉(zhuǎn):鼠標(biāo)右鍵拖動(dòng)
  • 縮放:鼠標(biāo)中鍵滾動(dòng)

MapControls本質(zhì)上就是改變相機(jī)的參數(shù),比如相機(jī)的位置屬性、相機(jī)目標(biāo)觀察點(diǎn)。

// 引入相機(jī)控件`MapControls`
import { MapControls } from 'three/addons/controls/OrbitControls.js';
const controls = new MapControls(camera, renderer.domElement);
controls.addEventListener('change', function () {
    // 鼠標(biāo)右鍵旋轉(zhuǎn)時(shí)候,查看.position變化
    // 鼠標(biāo)左鍵拖動(dòng)的時(shí)候,查看.position、.target的位置會(huì)變化
    console.log('camera.position',camera.position);
    console.log('controls.target',controls.target);
});
//相關(guān)限制方法:
controls.enablePan = false; //禁止平移
controls.enableZoom = false;//禁止縮放
controls.enableRotate = false; //禁止旋轉(zhuǎn)
//相機(jī)位置與觀察目標(biāo)點(diǎn)最小值
controls.minDistance = 200;
//相機(jī)位置與觀察目標(biāo)點(diǎn)最大值
controls.maxDistance = 500;
// 上下旋轉(zhuǎn)范圍
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI/2;
// 左右旋轉(zhuǎn)范圍
controls.minAzimuthAngle = -Math.PI/2;
controls.maxAzimuthAngle = Math.PI/2;
//更新方法
function animate() {
  requestAnimationFrame(animate);
  // 更新控制器
  controls.update();
  // 渲染場景
  renderer.render(scene, camera);
}

7. 窗口變化的自適應(yīng)渲染

在開發(fā) Three.js 項(xiàng)目時(shí),我們需要考慮到不同的設(shè)備和屏幕尺寸。當(dāng)用戶調(diào)整瀏覽器窗口大小時(shí),我們希望場景能夠自適應(yīng)地進(jìn)行調(diào)整,以保持正確的比例和尺寸。

要實(shí)現(xiàn)自適應(yīng)渲染,我們需要在瀏覽器窗口大小發(fā)生變化時(shí)更新相機(jī)和渲染器的設(shè)置。首先,我們需要為 window 對(duì)象添加一個(gè) resize 事件監(jiān)聽器:

window.addEventListener('resize', onWindowResize);

接下來,我們定義 onWindowResize 函數(shù)。在這個(gè)函數(shù)中,我們需要完成以下任務(wù):

  • 更新相機(jī)的寬高比(aspect)。
  • 更新相機(jī)的投影矩陣。
  • 更新渲染器的大小。

7.1 正投影相機(jī)OrthographicCamera自適應(yīng)渲染

// onresize 事件會(huì)在窗口被調(diào)整大小時(shí)發(fā)生
function onWindowResize(){
  // 重置渲染器輸出畫布canvas尺寸
  renderer.setSize(window.innerWidth,window.innerHeight);
  // 重置相機(jī)投影的相關(guān)參數(shù)
  k = window.innerWidth/window.innerHeight;//窗口寬高比
  camera.left = -s*k;
  camera.right = s*k;
  camera.top = s;
  camera.bottom = -s;
  // 渲染器執(zhí)行render方法的時(shí)候會(huì)讀取相機(jī)對(duì)象的投影矩陣屬性projectionMatrix
  // 但是不會(huì)每渲染一幀,就通過相機(jī)的屬性計(jì)算投影矩陣(節(jié)約計(jì)算資源)
  // 如果相機(jī)的一些屬性發(fā)生了變化,需要執(zhí)行updateProjectionMatrix ()方法更新相機(jī)的投影矩陣
  camera.updateProjectionMatrix ();
};

7.2 透視投影相機(jī)PerspectiveCamera自適應(yīng)渲染

// onresize 事件會(huì)在窗口被調(diào)整大小時(shí)發(fā)生
function onWindowResize(){
  // 重置渲染器輸出畫布canvas尺寸
  renderer.setSize(window.innerWidth,window.innerHeight);
  // 全屏情況下:設(shè)置觀察范圍長寬比aspect為窗口寬高比
  camera.aspect = window.innerWidth/window.innerHeight;
  // 渲染器執(zhí)行render方法的時(shí)候會(huì)讀取相機(jī)對(duì)象的投影矩陣屬性projectionMatrix
  // 但是不會(huì)每渲染一幀,就通過相機(jī)的屬性計(jì)算投影矩陣(節(jié)約計(jì)算資源)
  // 如果相機(jī)的一些屬性發(fā)生了變化,需要執(zhí)行updateProjectionMatrix ()方法更新相機(jī)的投影矩陣
  camera.updateProjectionMatrix ();
};

以上就是Three.js相機(jī)Camera的詳細(xì)內(nèi)容,更多關(guān)于Three.js相機(jī)Camera的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論