03.光源與陰影

本章將介紹4種常見的光源以及光源與物體的陰影關係

threejs中常見的光源有以下4種 :

PointLight(點光源)

AmbientLight(環境光)

SpotLight(聚光燈)

DirectionalLight(平行光)

 

PointLight

從一個點向各個方向發射的光源。一個常見的例子是模擬一個燈泡發出的光。該光源可以投射陰影

構造函數

PointLight( color : Integer, intensity : Float, distance : Number, decay : Float )

color - (可選參數)) 十六進制光照顏色。 缺省值 0xffffff (白色)。
intensity - (可選參數) 光照強度。 缺省值 1。 
distance - 這個距離表示從光源到光照強度爲0的位置。 當設置爲0時,光永遠不會消失(距離無窮大)。缺省值 0.
decay - 沿着光照距離的衰退量。缺省值 1。 在 physically correct 模式中,decay = 2。

創建代碼 

let pointLight = new THREE.PointLight(0xffffff,1,5,2);
pointLight.position.set(2.5, 1, 0); 
scene.add(pointLight); 

例子

點光源

 

AmbientLight

環境光會均勻的照亮場景中的所有物體的每個面,環境光不能用來投射陰影,因爲它沒有方向。如下圖 :

該圖我們沒辦法,找到具體的光源在哪裏,但是整個場景我們還是可以看的見的。每個物體,每個人的光照面積都是均勻的。

構造函數

AmbientLight( color : Integer, intensity : Float )

color - (參數可選)顏色的rgb數值。缺省值爲 0xffffff。
intensity - (參數可選)光照的強度。缺省值爲 1。

創建代碼 

let ambient = new THREE.AmbientLight(0x444444,1);
scene.add(ambient);

例子

環境光

環境光+點光源

 

SpotLight

聚光燈是從一個方向上的一個點發出,沿着一個圓錐體,它離光越遠,它的尺寸就越大。該光源可以投射陰影

構造函數

SpotLight( color : Integer, intensity : Float, distance : Float, angle : Radians, penumbra : Float, decay : Float )

color - (可選參數) 十六進制光照顏色。 缺省值 0xffffff (白色)。
intensity - (可選參數) 光照強度。 缺省值 1。
distance - 從光源發出光的最大距離,其強度根據光源的距離線性衰減。 
angle - 光線散射角度,最大爲Math.PI/2。
penumbra - 聚光錐的半影衰減百分比。在0和1之間的值。默認爲0。
decay - 沿着光照距離的衰減量。

創建代碼 

let spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(0, 15, 0);
spotLight.angle = Math.PI / 10;
spotLight.penumbra = 1;
scene.add(spotLight);

例子

聚光燈

 

DirectionalLight

平行光是沿着特定方向發射的光。這種光的表現像是無限遠,從它發出的光線都是平行的。常常用平行光來模擬太陽光 的效果; 太陽足夠遠,因此我們可以認爲太陽的位置是無限遠,所以我們認爲從太陽發出的光線也都是平行的。平行光可以投射陰影

構造函數

DirectionalLight( color : Integer, intensity : Float )

color - (可選參數) 16進製表示光的顏色。 缺省值爲 0xffffff (白色)。
intensity - (可選參數) 光照的強度。缺省值爲1。

創建代碼 

let directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(0, 5000, 10000);
scene.add(directionalLight);

注意這裏的位置屬性,因爲平行光是可以看作很遠的光源,所以物體受到平行光照射的面積都是均勻的。所以這裏的位置y軸5000,z軸

10000,在同等的比例下,怎麼修改位置,物體受到的光照面級都不會改變。比如y軸改成0.5,z軸改成1

例子

平行光

 

陰影

由於計算陰影是一件很消耗性能的一件工作,threejs默認關閉了物體的陰影特性。若要開啓,分以下四個步驟 :

1. 渲染器的shadowMap.enabled屬性設置爲true

2. 網格模型的castShadow屬性設置爲true

3. 光源的castShadow屬性設置爲true

4. 接受陰影的物體的receiveShadow屬性設置爲true

例子

點光源陰影

聚光燈陰影

平行光陰影

其中,平行光的陰影比較特殊。點開上面平行光的陰影鏈接可以看到,立方體生成的陰影不全。這是因爲平行光照射的範圍是整個場景,如果被照射到的物體都生成陰影,這實在太損耗性能。所以在threejs中,若要給平行光照射到的物體產生陰影,需要設置一個“陰影矩形”,在這個矩形下的物體纔會產生陰影。

具體設置

let directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(10, 5, 0);
scene.add(directionalLight);

directionalLight.castShadow = true;

/* 
  設置計算陰影的區域,最好剛好緊密包圍在對象周圍
  計算陰影的區域過大:模糊  過小:看不到或顯示不完整
*/
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 100;
directionalLight.shadow.camera.left = -25;
directionalLight.shadow.camera.right = 25;
directionalLight.shadow.camera.top = 25;
directionalLight.shadow.camera.bottom = -25;

例子

解決平行光陰影不全問題

上面的例子中還存在陰影模糊的問題,我們可以調用光源的shadow.mapSize.set方法,該方法需要2個參數 :

shadowWidth :陰影的寬度用多少像素繪製

shadowHeight :陰影的高度用多少像素繪製

例子

解決陰影模糊問題

最後是個人制作的一個小案列

移動的光源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章