在 Three.js 中,燈光是非常重要的元素之一,它能夠模擬現實世界中的光照效果,幫助我們打造更加真實的三維場景。燈光的種類和配置方式可以影響整個場景的視覺效果,在不同的應用中,燈光的使用非常關鍵。
燈光概述
Three.js 提供了幾種常見的光源型別:環境光(Ambient Light)、平行光(Directional Light)、點光源(Point Light)、聚光燈(Spot Light)。每種光源型別都具有不同的光照特性,適用於不同的場景需求。
我們圍繞一個球體案例,做燈光的講解,首先,寫入以下程式碼,建立一個球體。
// 引入 Three.js 基礎模組
import * as THREE from "three";
// 建立場景
const scene = new THREE.Scene();
// 建立相機 (視角:45度,寬高比,近裁剪面,遠裁剪面)
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.z = 5; // 設定相機位置
// 建立渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight); // 設定渲染器大小
document.body.appendChild(renderer.domElement); // 將渲染器新增到頁面中
// 建立球體
const geometry = new THREE.SphereGeometry(1, 32, 32); // 球體幾何體
const material = new THREE.MeshStandardMaterial({ color: 0x0077ff }); // 球體材質,使用標準材質
const sphere = new THREE.Mesh(geometry, material); // 建立球體網格
scene.add(sphere); // 將球體新增到場景中
renderer.render(scene, camera);
透過上面的程式碼,我們已經建立一個場景、相機、渲染器和一個球體。但是執行起來環境是黑暗的,我們需要新增燈光來照亮場景。
環境光(Ambient Light)
環境光是最基礎的一種光源,它不具備方向性,也不會產生陰影。它的作用是全域性地照亮場景中的所有物體,確保沒有完全黑暗的區域。環境光通常用於模擬場景中的“全域性光照”,比如自然光在房間內的反射或天空光等。
特點
- 無方向性: 環境光沒有特定的方向,照亮所有物體的所有面。
- 無陰影: 環境光不產生陰影,因為它是均勻的、全域性的光。
- 全域性光照: 它在場景中均勻地影響所有物體,確保沒有區域是完全黑暗的。
- 無法模擬光源的特定效果: 由於環境光的均勻性,它無法模擬物體的光照衰減、反射或投射陰影,因此常常與其他型別的光源結合使用。
屬性
new THREE.AmbientLight(color, intensity);
- 顏色(color):
- 環境光的顏色,通常是一個十六進位制顏色值。比如,
0xffffff
表示白色光。你也可以設定其他顏色,來模擬不同光源的環境光效果。
- 環境光的顏色,通常是一個十六進位制顏色值。比如,
- 強度(intensity):
- 環境光的強度,控制環境光的亮度。預設為
1
,設定為0
會導致沒有環境光。調整強度可以影響場景整體的亮度,但不會改變場景中光源的方向性或陰影效果。
- 環境光的強度,控制環境光的亮度。預設為
使用方式:
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 環境光,顏色為白色,強度為0.5
scene.add(ambientLight); // 將環境光新增到場景中
在最開的時候程式碼中,增加環境光後,我們就的得到了
可以看到,球體被均勻地照亮,沒有明顯的陰影。球體看起來也不立體,因為沒有明顯的光照方向。
平行光(Directional Light)
平行光類似於太陽光,其光線是平行的並且沒有衰減。它的方向性非常強,通常用於模擬太陽或遠處的光源。平行光可以產生陰影,特別適用於需要光線均勻照射的場景。
特點
- 方向性: 平行光的光線具有固定的方向,所有物體接收到的光線都是平行的,光線的源頭位置並不重要。它模擬的是遠離物體的光源,比如太陽光或星光,這些光源的光線幾乎是平行的。
- 沒有衰減: 與點光源和聚光燈不同,平行光的強度不會隨著距離的增加而衰減。光照強度在整個場景中是均勻的,無論光源距離物體有多遠。
- 產生陰影: 平行光可以產生陰影,適用於需要定向光照的場景。你可以控制陰影的質量、透明度和偏移量等引數。
- 用於模擬自然光: 平行光常常用於模擬太陽光、月光或任何遠處的恆定光源,它對整個場景的照明影響均勻,不會因為物體的大小或距離而發生變化。
屬性
new THREE.DirectionalLight(color, intensity);
- 顏色(color): 設定平行光的顏色,可以是一個十六進位制的顏色值或
THREE.Color
物件。預設是白色(0xffffff
)。 - 強度(intensity): 設定光源的強度,預設為
1
。調整這個值可以控制光的亮度。
使用方式:
const directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(10, 10, 10); // 設定光源的位置
scene.add(directionalLight);
可以看到,加入了平行光後,球體的光照效果更加立體,有了明顯的高光和陰影。光線的方向性也使得球體的表面更加立體感。
點光源(Point Light)
點光源是從一個特定點發射光線,光線會以球形的方式擴散開來。點光源會隨著距離的增加而衰減,因此可以模擬類似燈泡的效果。點光源通常用於場景中的區域性照明。
特點
- 光源位置: 點光源從一個特定的位置發出光線,光線向所有方向均勻傳播。你可以透過設定點光源的
position
屬性來定義光源的位置。 - 光照衰減: 點光源的光照強度會隨著距離光源的遠近而衰減,通常會使用距離衰減模型(如平方反比衰減)來模擬自然界中的光照衰減。它的亮度會隨著距離的增加逐漸減弱。
- 產生陰影: 點光源可以產生陰影,這使得場景的光照效果更加立體和真實。透過配置
castShadow
屬性,可以控制是否啟用陰影。 - 全向光照: 點光源向四面八方發射光線,照亮周圍的物體,適用於模擬小範圍的區域性光源。
屬性
new THREE.PointLight(color, intensity, distance, decay);
- 顏色(color): 設定光源的顏色,通常使用十六進位制顏色值。預設是白色(
0xffffff
)。 - 強度(intensity): 設定光源的亮度,預設是
1
。增大強度會使光源變得更亮,減小則變暗。 - 距離(distance): 設定光照的衰減範圍。光照的強度隨著距離的增加而減弱。如果設定為
0
,光源會無限制地照亮場景中的所有物體。 - 衰減(decay): 控制光照衰減的速率,預設值為
2
。較大的衰減值會讓光照更快衰減。
使用方式:
const pointLight = new THREE.PointLight(0xffffff, 300, 0); // 點光源,顏色為白色,強度為200, 距離為0
pointLight.position.set(5, 5, 5);
scene.add(pointLight);
點光源和平行光,雖然都可以產生陰影。但是我們在使用場景上還是有區別的,從場景考慮,點光源更適合模擬區域性光源,比如檯燈、蠟燭等,而平行光更適合模擬遠處的光源,比如太陽光。
特點 | 點光源(Point Light) | 平行光(Directional Light) |
---|---|---|
光源型別 | 發光點,在場景中有位置 | 無位置的平行光線,模擬遠處的光源 |
光線傳播 | 向四面八方發射光線 | 光線是平行的,所有光線方向相同 |
光照衰減 | 會隨著距離衰減,強度會減弱 | 不衰減,光照強度保持恆定 |
光照方向 | 所有物體會被均勻照亮,方向是從光源向外發散 | 所有物體的光照方向相同,具有明確的方向性 |
光源位置 | 光源的位置是可設定的 | 無固定位置,光源的方向決定了光照的方向 |
適用場景 | 區域性光源,模擬檯燈、蠟燭、手電筒等小範圍照明 | 模擬日光、遠處的光源、大範圍照明(如太陽光) |
是否影響陰影 | 會根據距離和位置影響陰影的強度和方向 | 影響陰影的方向,所有物體投射的陰影方向相同,但沒有衰減 |
常見用途 | 小範圍區域性照明、汽車燈光、室內燈光等 | 太陽光、遠光燈、大範圍均勻照明 |
聚光燈(Spot Light)
聚光燈(Spotlight)是一種具有方向性的光源,其光線從一個特定的點發射,並且有一個錐形的照射範圍。它通常用於模擬舞臺燈光、手電筒、汽車頭燈等聚焦的光源。與點光源(Point Light)和平行光(Directional Light)不同,聚光燈具有可調節的照射角度和聚焦範圍,並且可以設定光的衰減效果。
特點
- 光源位置與方向:
- 聚光燈是從一個點發射光線的,通常需要設定光源的位置,並透過
target
屬性指定光源的照射方向。 - 聚光燈的光線形成一個錐形區域,只有這個區域內的物體能夠被照亮。
- 聚光燈是從一個點發射光線的,通常需要設定光源的位置,並透過
- 光照範圍:
- 聚光燈的光照範圍是可調的,可以透過 角度 (
angle
) 來控制光錐的寬度。 - 你可以設定 衰減範圍 (
distance
和decay
),控制光源的影響範圍和衰減速率。
- 聚光燈的光照範圍是可調的,可以透過 角度 (
- 錐形區域:
- 聚光燈的光照效果是錐形的,指定了一個 內角 (
angle
) 和 外角 (penumbra
)。angle
控制了光錐的半形。penumbra
控制了光錐的邊緣模糊程度,值為 0 到 1 之間的浮動值,0 表示邊緣清晰,1 表示邊緣完全模糊。
- 聚光燈的光照效果是錐形的,指定了一個 內角 (
- 光照衰減:
- 與點光源相似,聚光燈也具有衰減效果。隨著距離的增加,光源的強度會衰減。
- 你可以調整 衰減距離 (
distance
) 和 衰減係數 (decay
),來設定光照的強度和範圍。
- 陰影:
- 聚光燈可以投射陰影,適合用來建立光照集中在某個區域的效果。
場景
- 舞臺照明: 聚光燈通常用於舞臺表演,照亮特定區域或演員,使其更加突出。
- 汽車前燈: 汽車頭燈可以模擬聚光燈的效果,用來照亮前方的道路。
- 手電筒或探照燈: 手電筒的光照範圍通常是錐形的,類似於聚光燈,適合用來照亮小範圍區域。
- 遊戲中的聚焦效果: 在遊戲或虛擬現實中,可以用聚光燈來突出顯示某些重要物體或區域,比如在關卡中照亮目標物體或道具。
- 燈光特效: 在建築視覺化或電影製作中,聚光燈常常用於建立某種特殊的光影效果,例如光束穿透煙霧或光斑效果。
屬性
new THREE.SpotLight(color, intensity, distance, angle, penumbra, decay);
- color: 光源的顏色,預設為
0xffffff
(白色)。 - intensity: 光源的強度,預設為
1
。 - distance: 光源的照射範圍,預設為
0
,即光源的光照沒有限制。 - angle: 光錐的開口角度,單位為弧度。預設值是
Math.PI / 3
(60 度)。 - penumbra: 控制光錐邊緣的模糊程度,值在
0
到1
之間,0
表示銳利的邊緣,1
表示完全模糊的邊緣。 - decay: 控制光照的衰減速率,預設為
2
。
使用方式:
const spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(10, 10, 10);
spotLight.target = scene; // 設定聚光燈的目標
scene.add(spotLight); 5. 區域光(RectArea Light)
燈光的屬性與配置
每種光源除了位置和強度之外,還有很多可以調整的屬性。瞭解這些屬性,有助於我們更好地控制場景中的光照效果。
- 顏色與強度
光源的顏色決定了它照射的光線的顏色,強度決定了光線的亮度。通常,白色光線的強度會影響場景的亮度,而顏色的改變會影響整體的色調。
調整顏色和強度:
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 強度為 1
directionalLight.color.set(0xff0000); // 設定光源為紅色 2. 光衰減
光源通常會隨著距離的增加而衰減。點光源和聚光燈都可以設定衰減因子,模擬現實世界中光線衰減的效果。衰減通常包括常規衰減(距離的平方)和最大衰減距離。
點光源衰減:
const pointLight = new THREE.PointLight(0xffffff, 1, 100); // 衰減距離為 100 3. 陰影
某些光源(如平行光、點光源和聚光燈)能夠產生陰影。陰影的產生有助於提高場景的真實感。我們可以設定光源產生陰影的開關、陰影的強度以及陰影的質量。
設定陰影:
directionalLight.castShadow = true; // 開啟陰影
renderer.shadowMap.enabled = true; // 開啟渲染器的陰影對映 4. 光線投射
聚光燈的投射角度可以透過 angle 和 penumbra 控制,angle 設定聚光燈的錐形角度,penumbra 用於調整邊緣的柔和度。
設定聚光燈的投射角度:
spotLight.angle = Math.PI / 4; // 設定聚光燈的角度為 45 度
spotLight.penumbra = 0.2; // 設定陰影邊緣柔和度
燈光的進階應用
除了基礎的光照效果外,Three.js 還允許我們使用光源與材質的結合,創造出更加複雜的光影效果。在此部分,我們將介紹一些常見的進階技巧。
-
光照貼圖
光照貼圖(Lightmap)是一種預計算的光照資訊紋理,它可以儲存光照、陰影和反射等資訊,並將這些資訊應用到模型的表面。這種技術常用於靜態場景中,特別是在場景的複雜計算(如全域性光照、陰影等)較為消耗效能時,透過光照貼圖可以大大提高渲染效率。 -
HDR 環境光貼圖
HDR 環境光貼圖(High Dynamic Range environment map)是一種高動態範圍的紋理,它包含了更多的亮度和細節,能夠真實地模擬環境中的光照效果。HDR 環境光貼圖通常用於提供更高質量的反射、光照效果,適用於更真實的影像渲染。 -
反射與折射
反射和折射是透過燈光與物體表面相互作用產生的效果。在 Three.js 中,我們可以使用鏡面反射或折射來增加場景的真實感。 -
光源的動畫效果
燈光的動態效果可以透過修改光源的屬性(如位置、顏色、強度等)來實現。Three.js 提供了豐富的動畫機制,結合光源的屬性,可以製作出非常豐富的燈光動態效果。常見的燈光動畫:
- 閃爍效果: 模擬燈光的閃爍,例如模擬霓虹燈或電燈的閃爍。
- 漸變效果: 燈光的強度或顏色漸變,模擬燈光的逐漸變亮或變暗。
- 移動光源: 讓光源在場景中移動,模擬手電筒、車燈等效果。
Three.js學習:https://www.threejs3d.com/