1. 程式人生 > 實用技巧 >Three.js光源、相機知識梳理

Three.js光源、相機知識梳理

光源

Threejs場景物件Scene主要是由模型物件和光源物件Light構成,在實際開發過程中,多數三維場景往往需要設定光源物件,Threejs虛擬光源是對自然界光照的模擬。

1、環境光(AmbientLight):會均勻的照亮場景中的所有物體。環境光不能用來投射陰影,因為它沒有方向。

2、平行光(DirectionalLight):它發出的光線都是平行的。經常用平行光來模擬太陽光的效果。

3、點光源(PointLight):常見的例子是模擬一個燈泡發出的光。

4、聚光燈(SpotLight):從一個方向上的一個點發出,照射範圍在三維空間中構成一個圓錐體,它離光越遠,它的尺寸就越大。

陰影

支援陰影的有:平行光、點光源、聚光燈。

由於陰影的計算是非常消耗效能的,因此陰影預設是不計算不顯示的;需要顯示陰影,有以下幾個條件:

1、渲染器需要開啟陰影計算
renderer.shadowMap.enabled = true;
2、光照支援陰影,光照開啟陰影
light.castShadow = true;
3、需要計算陰影的物體開啟陰影
cube.castShadow = true;
4、需要有接收陰影的物體
plane.receiveShadow = true;

相機

機械、工業設計領域常常採用正投影(平行投影),大型遊戲場景往往採用透視投影(中心投影)。

對於正投影而言,一條直線放置的角度不同,投影在投影面上面的長短不同;對於透視投影而言,投影的結果除了與幾何體的角度有關,還和距離相關, 人的眼睛觀察世界就是透視投影,比如你觀察一條鐵路距離越遠你會感到兩條軌道之間的寬度越小。

正投影相機(OrthographicCamera):

/**
 * 正投影相機設定
 */
var width = window.innerWidth; //視窗寬度
var height = window.innerHeight; //視窗高度
var k = width / height; //視窗寬高比
var s = 150; //三維場景顯示範圍控制係數,係數越大,顯示的範圍越大(場景會大,物體會小)
//建立相機物件
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //
設定相機位置 camera.lookAt(scene.position); //設定相機方向(指向的場景物件)
// 建構函式格式
OrthographicCamera( left, right, top, bottom, near, far )
//left、right、top、bottom渲染空間的左、右、上、下邊界,
//near從距離相機多遠的位置開始渲染,
//far距離相機多遠的位置截止渲染

引數leftright、引數topbottom互為相反數,這樣做的目的是lookAt指向的物件能夠顯示在canvas畫布的中間位置。

透視投影相機PerspectiveCamera:

/**
 * 透視投影相機設定
 */
var width = window.innerWidth; //視窗寬度
var height = window.innerHeight; //視窗高度
/**透視投影相機物件*/
var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
camera.position.set(200, 300, 200); //設定相機位置
camera.lookAt(scene.position); //設定相機方向(指向的場景物件)
// 建構函式格式
PerspectiveCamera( fov, aspect, near, far )
//fov表示視場,所謂視場就是能夠看到的角度範圍,人的眼睛大約能夠看到180度的視場,視角大小設定要根據具體應用,一般遊戲會設定60~90度
//aspect表示渲染視窗的長寬比

效果對比:

圖一為正投影,圖二為透視投影


相機位置.posiiotn.lookAt(相機拍攝目標位置)

camera.position可以設定相機的位置。

camera.lookAt設定相機拍攝目標的位置。你希望相機對準哪個物件,就返回那個物件的位置屬.posiiotn。所以同於scene.position,等同於mesh.position。

camera.position.set(200, 300, 200); //設定相機位置
camera.lookAt(scene.position); //設定相機方向(指向的場景物件)

相機位置與觀察目標位置間隔距離越小,場景中的三維模型放大倍數越大,準確地說是透視投影相機可以拍攝的範圍更小。

如果是觀察一個產品外觀效果,相機就位於幾何體的外面,如果是室內漫遊預覽,就把相機放在房間三維模型的內部。

視窗尺寸變化(自適應渲染)

正投影相機OrthographicCamera自適應渲染

// onresize 事件會在視窗被調整大小時發生
window.onresize=function(){
  // 重置渲染器輸出畫布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 ();
};

透視投影相機PerspectiveCamera自適應渲染

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