本章將介紹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 :陰影的高度用多少像素繪製
例子
最後是個人制作的一個小案列