Three.js學習:https://www.threejs3d.com/
在 Three.js 中,燈光是非常重要的元素之一,它能夠模擬現(xiàn)實世界中的光照效果,幫助我們打造更加真實的三維場景。燈光的種類和配置方式可以影響整個場景的視覺效果,在不同的應用中,燈光的使用非常關(guān)鍵。
燈光概述
Three.js 提供了幾種常見的光源類型:環(huán)境光(Ambient Light)、平行光(Directional Light)、點光源(Point Light)、聚光燈(Spot Light)。每種光源類型都具有不同的光照特性,適用于不同的場景需求。

我們圍繞一個球體案例,做燈光的講解,首先,寫入以下代碼,創(chuàng)建一個球體。
// 引入 Three.js 基礎模塊
import * as THREE from "three";
// 創(chuàng)建場景
const scene = new THREE.Scene();
// 創(chuàng)建相機 (視角:45度,寬高比,近裁剪面,遠裁剪面)
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.z = 5; // 設置相機位置
// 創(chuàng)建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight); // 設置渲染器大小
document.body.appendChild(renderer.domElement); // 將渲染器添加到頁面中
// 創(chuàng)建球體
const geometry = new THREE.SphereGeometry(1, 32, 32); // 球體幾何體
const material = new THREE.MeshStandardMaterial({ color: 0x0077ff }); // 球體材質(zhì),使用標準材質(zhì)
const sphere = new THREE.Mesh(geometry, material); // 創(chuàng)建球體網(wǎng)格
scene.add(sphere); // 將球體添加到場景中
renderer.render(scene, camera);
通過上面的代碼,我們已經(jīng)創(chuàng)建一個場景、相機、渲染器和一個球體。但是運行起來環(huán)境是黑暗的,我們需要添加燈光來照亮場景。
環(huán)境光(Ambient Light)
環(huán)境光是最基礎的一種光源,它不具備方向性,也不會產(chǎn)生陰影。它的作用是全局地照亮場景中的所有物體,確保沒有完全黑暗的區(qū)域。環(huán)境光通常用于模擬場景中的“全局光照”,比如自然光在房間內(nèi)的反射或天空光等。
特點
- 無方向性: 環(huán)境光沒有特定的方向,照亮所有物體的所有面。
- 無陰影: 環(huán)境光不產(chǎn)生陰影,因為它是均勻的、全局的光。
- 全局光照: 它在場景中均勻地影響所有物體,確保沒有區(qū)域是完全黑暗的。
- 無法模擬光源的特定效果: 由于環(huán)境光的均勻性,它無法模擬物體的光照衰減、反射或投射陰影,因此常常與其他類型的光源結(jié)合使用。
屬性
new THREE.AmbientLight(color, intensity);
-
顏色(color):
- 環(huán)境光的顏色,通常是一個十六進制顏色值。比如,
0xffffff表示白色光。你也可以設置其他顏色,來模擬不同光源的環(huán)境光效果。
- 環(huán)境光的顏色,通常是一個十六進制顏色值。比如,
-
強度(intensity):
- 環(huán)境光的強度,控制環(huán)境光的亮度。默認為
1,設置為0會導致沒有環(huán)境光。調(diào)整強度可以影響場景整體的亮度,但不會改變場景中光源的方向性或陰影效果。
- 環(huán)境光的強度,控制環(huán)境光的亮度。默認為
使用方式:
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 環(huán)境光,顏色為白色,強度為0.5
scene.add(ambientLight); // 將環(huán)境光添加到場景中
在最開的時候代碼中,增加環(huán)境光后,我們就的得到了

可以看到,球體被均勻地照亮,沒有明顯的陰影。球體看起來也不立體,因為沒有明顯的光照方向。
平行光(Directional Light)
平行光類似于太陽光,其光線是平行的并且沒有衰減。它的方向性非常強,通常用于模擬太陽或遠處的光源。平行光可以產(chǎn)生陰影,特別適用于需要光線均勻照射的場景。
特點
- 方向性: 平行光的光線具有固定的方向,所有物體接收到的光線都是平行的,光線的源頭位置并不重要。它模擬的是遠離物體的光源,比如太陽光或星光,這些光源的光線幾乎是平行的。
- 沒有衰減: 與點光源和聚光燈不同,平行光的強度不會隨著距離的增加而衰減。光照強度在整個場景中是均勻的,無論光源距離物體有多遠。
- 產(chǎn)生陰影: 平行光可以產(chǎn)生陰影,適用于需要定向光照的場景。你可以控制陰影的質(zhì)量、透明度和偏移量等參數(shù)。
- 用于模擬自然光: 平行光常常用于模擬太陽光、月光或任何遠處的恒定光源,它對整個場景的照明影響均勻,不會因為物體的大小或距離而發(fā)生變化。
屬性
new THREE.DirectionalLight(color, intensity);
-
顏色(color): 設置平行光的顏色,可以是一個十六進制的顏色值或
THREE.Color對象。默認是白色(0xffffff)。 -
強度(intensity): 設置光源的強度,默認為
1。調(diào)整這個值可以控制光的亮度。
使用方式:
const directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(10, 10, 10); // 設置光源的位置
scene.add(directionalLight);

可以看到,加入了平行光后,球體的光照效果更加立體,有了明顯的高光和陰影。光線的方向性也使得球體的表面更加立體感。
點光源(Point Light)
點光源是從一個特定點發(fā)射光線,光線會以球形的方式擴散開來。點光源會隨著距離的增加而衰減,因此可以模擬類似燈泡的效果。點光源通常用于場景中的局部照明。
特點
-
光源位置: 點光源從一個特定的位置發(fā)出光線,光線向所有方向均勻傳播。你可以通過設置點光源的
position屬性來定義光源的位置。 - 光照衰減: 點光源的光照強度會隨著距離光源的遠近而衰減,通常會使用距離衰減模型(如平方反比衰減)來模擬自然界中的光照衰減。它的亮度會隨著距離的增加逐漸減弱。
-
產(chǎn)生陰影: 點光源可以產(chǎn)生陰影,這使得場景的光照效果更加立體和真實。通過配置
castShadow屬性,可以控制是否啟用陰影。 - 全向光照: 點光源向四面八方發(fā)射光線,照亮周圍的物體,適用于模擬小范圍的局部光源。
屬性
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);

點光源和平行光,雖然都可以產(chǎn)生陰影。但是我們在使用場景上還是有區(qū)別的,從場景考慮,點光源更適合模擬局部光源,比如臺燈、蠟燭等,而平行光更適合模擬遠處的光源,比如太陽光。
| 特點 | 點光源(Point Light) | 平行光(Directional Light) |
|---|---|---|
| 光源類型 | 發(fā)光點,在場景中有位置 | 無位置的平行光線,模擬遠處的光源 |
| 光線傳播 | 向四面八方發(fā)射光線 | 光線是平行的,所有光線方向相同 |
| 光照衰減 | 會隨著距離衰減,強度會減弱 | 不衰減,光照強度保持恒定 |
| 光照方向 | 所有物體會被均勻照亮,方向是從光源向外發(fā)散 | 所有物體的光照方向相同,具有明確的方向性 |
| 光源位置 | 光源的位置是可設置的 | 無固定位置,光源的方向決定了光照的方向 |
| 適用場景 | 局部光源,模擬臺燈、蠟燭、手電筒等小范圍照明 | 模擬日光、遠處的光源、大范圍照明(如太陽光) |
| 是否影響陰影 | 會根據(jù)距離和位置影響陰影的強度和方向 | 影響陰影的方向,所有物體投射的陰影方向相同,但沒有衰減 |
| 常見用途 | 小范圍局部照明、汽車燈光、室內(nèi)燈光等 | 太陽光、遠光燈、大范圍均勻照明 |
聚光燈(Spot Light)
聚光燈(Spotlight)是一種具有方向性的光源,其光線從一個特定的點發(fā)射,并且有一個錐形的照射范圍。它通常用于模擬舞臺燈光、手電筒、汽車頭燈等聚焦的光源。與點光源(Point Light)和平行光(Directional Light)不同,聚光燈具有可調(diào)節(jié)的照射角度和聚焦范圍,并且可以設置光的衰減效果。
特點
-
光源位置與方向:
- 聚光燈是從一個點發(fā)射光線的,通常需要設置光源的位置,并通過
target屬性指定光源的照射方向。 - 聚光燈的光線形成一個錐形區(qū)域,只有這個區(qū)域內(nèi)的物體能夠被照亮。
- 聚光燈是從一個點發(fā)射光線的,通常需要設置光源的位置,并通過
-
光照范圍:
- 聚光燈的光照范圍是可調(diào)的,可以通過 角度 (
angle) 來控制光錐的寬度。 - 你可以設置 衰減范圍 (
distance和decay),控制光源的影響范圍和衰減速率。
- 聚光燈的光照范圍是可調(diào)的,可以通過 角度 (
-
錐形區(qū)域:
- 聚光燈的光照效果是錐形的,指定了一個 內(nèi)角 (
angle) 和 外角 (penumbra)。-
angle控制了光錐的半角。 -
penumbra控制了光錐的邊緣模糊程度,值為 0 到 1 之間的浮動值,0 表示邊緣清晰,1 表示邊緣完全模糊。
-
- 聚光燈的光照效果是錐形的,指定了一個 內(nèi)角 (
-
光照衰減:
- 與點光源相似,聚光燈也具有衰減效果。隨著距離的增加,光源的強度會衰減。
- 你可以調(diào)整 衰減距離 (
distance) 和 衰減系數(shù) (decay),來設置光照的強度和范圍。
-
陰影:
- 聚光燈可以投射陰影,適合用來創(chuàng)建光照集中在某個區(qū)域的效果。
場景
- 舞臺照明: 聚光燈通常用于舞臺表演,照亮特定區(qū)域或演員,使其更加突出。
- 汽車前燈: 汽車頭燈可以模擬聚光燈的效果,用來照亮前方的道路。
- 手電筒或探照燈: 手電筒的光照范圍通常是錐形的,類似于聚光燈,適合用來照亮小范圍區(qū)域。
- 游戲中的聚焦效果: 在游戲或虛擬現(xiàn)實中,可以用聚光燈來突出顯示某些重要物體或區(qū)域,比如在關(guān)卡中照亮目標物體或道具。
- 燈光特效: 在建筑可視化或電影制作中,聚光燈常常用于創(chuàng)建某種特殊的光影效果,例如光束穿透煙霧或光斑效果。
屬性
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. 區(qū)域光(RectArea Light)
燈光的屬性與配置
每種光源除了位置和強度之外,還有很多可以調(diào)整的屬性。了解這些屬性,有助于我們更好地控制場景中的光照效果。
- 顏色與強度
光源的顏色決定了它照射的光線的顏色,強度決定了光線的亮度。通常,白色光線的強度會影響場景的亮度,而顏色的改變會影響整體的色調(diào)。
調(diào)整顏色和強度:
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 強度為 1
directionalLight.color.set(0xff0000); // 設置光源為紅色 2. 光衰減
光源通常會隨著距離的增加而衰減。點光源和聚光燈都可以設置衰減因子,模擬現(xiàn)實世界中光線衰減的效果。衰減通常包括常規(guī)衰減(距離的平方)和最大衰減距離。
點光源衰減:
const pointLight = new THREE.PointLight(0xffffff, 1, 100); // 衰減距離為 100 3. 陰影
某些光源(如平行光、點光源和聚光燈)能夠產(chǎn)生陰影。陰影的產(chǎn)生有助于提高場景的真實感。我們可以設置光源產(chǎn)生陰影的開關(guān)、陰影的強度以及陰影的質(zhì)量。
設置陰影:
directionalLight.castShadow = true; // 開啟陰影
renderer.shadowMap.enabled = true; // 開啟渲染器的陰影映射 4. 光線投射
聚光燈的投射角度可以通過 angle 和 penumbra 控制,angle 設置聚光燈的錐形角度,penumbra 用于調(diào)整邊緣的柔和度。
設置聚光燈的投射角度:
spotLight.angle = Math.PI / 4; // 設置聚光燈的角度為 45 度
spotLight.penumbra = 0.2; // 設置陰影邊緣柔和度
燈光的進階應用
除了基礎的光照效果外,Three.js 還允許我們使用光源與材質(zhì)的結(jié)合,創(chuàng)造出更加復雜的光影效果。在此部分,我們將介紹一些常見的進階技巧。
光照貼圖
光照貼圖(Lightmap)是一種預計算的光照信息紋理,它可以存儲光照、陰影和反射等信息,并將這些信息應用到模型的表面。這種技術(shù)常用于靜態(tài)場景中,特別是在場景的復雜計算(如全局光照、陰影等)較為消耗性能時,通過光照貼圖可以大大提高渲染效率。HDR 環(huán)境光貼圖
HDR 環(huán)境光貼圖(High Dynamic Range environment map)是一種高動態(tài)范圍的紋理,它包含了更多的亮度和細節(jié),能夠真實地模擬環(huán)境中的光照效果。HDR 環(huán)境光貼圖通常用于提供更高質(zhì)量的反射、光照效果,適用于更真實的圖像渲染。反射與折射
反射和折射是通過燈光與物體表面相互作用產(chǎn)生的效果。在 Three.js 中,我們可以使用鏡面反射或折射來增加場景的真實感。-
光源的動畫效果
燈光的動態(tài)效果可以通過修改光源的屬性(如位置、顏色、強度等)來實現(xiàn)。Three.js 提供了豐富的動畫機制,結(jié)合光源的屬性,可以制作出非常豐富的燈光動態(tài)效果。常見的燈光動畫:
- 閃爍效果: 模擬燈光的閃爍,例如模擬霓虹燈或電燈的閃爍。
- 漸變效果: 燈光的強度或顏色漸變,模擬燈光的逐漸變亮或變暗。
- 移動光源: 讓光源在場景中移動,模擬手電筒、車燈等效果。