Threejs入門-燈光

calmound發表於2024-11-28

在 Three.js 中,燈光是非常重要的元素之一,它能夠模擬現實世界中的光照效果,幫助我們打造更加真實的三維場景。燈光的種類和配置方式可以影響整個場景的視覺效果,在不同的應用中,燈光的使用非常關鍵。

燈光概述

Three.js 提供了幾種常見的光源型別:環境光(Ambient Light)、平行光(Directional Light)、點光源(Point Light)、聚光燈(Spot Light)。每種光源型別都具有不同的光照特性,適用於不同的場景需求。

file

我們圍繞一個球體案例,做燈光的講解,首先,寫入以下程式碼,建立一個球體。

// 引入 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);
  1. 顏色(color):
    • 環境光的顏色,通常是一個十六進位制顏色值。比如,0xffffff 表示白色光。你也可以設定其他顏色,來模擬不同光源的環境光效果。
  2. 強度(intensity):
    • 環境光的強度,控制環境光的亮度。預設為 1,設定為 0 會導致沒有環境光。調整強度可以影響場景整體的亮度,但不會改變場景中光源的方向性或陰影效果。

使用方式:

const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 環境光,顏色為白色,強度為0.5
scene.add(ambientLight); // 將環境光新增到場景中

在最開的時候程式碼中,增加環境光後,我們就的得到了
file

可以看到,球體被均勻地照亮,沒有明顯的陰影。球體看起來也不立體,因為沒有明顯的光照方向。

平行光(Directional Light)

平行光類似於太陽光,其光線是平行的並且沒有衰減。它的方向性非常強,通常用於模擬太陽或遠處的光源。平行光可以產生陰影,特別適用於需要光線均勻照射的場景。

特點

  • 方向性: 平行光的光線具有固定的方向,所有物體接收到的光線都是平行的,光線的源頭位置並不重要。它模擬的是遠離物體的光源,比如太陽光或星光,這些光源的光線幾乎是平行的。
  • 沒有衰減: 與點光源和聚光燈不同,平行光的強度不會隨著距離的增加而衰減。光照強度在整個場景中是均勻的,無論光源距離物體有多遠。
  • 產生陰影: 平行光可以產生陰影,適用於需要定向光照的場景。你可以控制陰影的質量、透明度和偏移量等引數。
  • 用於模擬自然光: 平行光常常用於模擬太陽光、月光或任何遠處的恆定光源,它對整個場景的照明影響均勻,不會因為物體的大小或距離而發生變化。

屬性

new THREE.DirectionalLight(color, intensity);
  1. 顏色(color): 設定平行光的顏色,可以是一個十六進位制的顏色值或 THREE.Color 物件。預設是白色(0xffffff)。
  2. 強度(intensity): 設定光源的強度,預設為 1。調整這個值可以控制光的亮度。

使用方式:

const directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(10, 10, 10); // 設定光源的位置
scene.add(directionalLight);

file

可以看到,加入了平行光後,球體的光照效果更加立體,有了明顯的高光和陰影。光線的方向性也使得球體的表面更加立體感。

點光源(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);

file

點光源和平行光,雖然都可以產生陰影。但是我們在使用場景上還是有區別的,從場景考慮,點光源更適合模擬區域性光源,比如檯燈、蠟燭等,而平行光更適合模擬遠處的光源,比如太陽光。

特點 點光源(Point Light) 平行光(Directional Light)
光源型別 發光點,在場景中有位置 無位置的平行光線,模擬遠處的光源
光線傳播 向四面八方發射光線 光線是平行的,所有光線方向相同
光照衰減 會隨著距離衰減,強度會減弱 不衰減,光照強度保持恆定
光照方向 所有物體會被均勻照亮,方向是從光源向外發散 所有物體的光照方向相同,具有明確的方向性
光源位置 光源的位置是可設定的 無固定位置,光源的方向決定了光照的方向
適用場景 區域性光源,模擬檯燈、蠟燭、手電筒等小範圍照明 模擬日光、遠處的光源、大範圍照明(如太陽光)
是否影響陰影 會根據距離和位置影響陰影的強度和方向 影響陰影的方向,所有物體投射的陰影方向相同,但沒有衰減
常見用途 小範圍區域性照明、汽車燈光、室內燈光等 太陽光、遠光燈、大範圍均勻照明

聚光燈(Spot Light)

聚光燈(Spotlight)是一種具有方向性的光源,其光線從一個特定的點發射,並且有一個錐形的照射範圍。它通常用於模擬舞臺燈光、手電筒、汽車頭燈等聚焦的光源。與點光源(Point Light)和平行光(Directional Light)不同,聚光燈具有可調節的照射角度聚焦範圍,並且可以設定光的衰減效果。

特點

  1. 光源位置與方向:
    • 聚光燈是從一個點發射光線的,通常需要設定光源的位置,並透過 target 屬性指定光源的照射方向。
    • 聚光燈的光線形成一個錐形區域,只有這個區域內的物體能夠被照亮。
  2. 光照範圍:
    • 聚光燈的光照範圍是可調的,可以透過 角度 (angle) 來控制光錐的寬度。
    • 你可以設定 衰減範圍 (distancedecay),控制光源的影響範圍和衰減速率。
  3. 錐形區域:
    • 聚光燈的光照效果是錐形的,指定了一個 內角 (angle) 和 外角 (penumbra)。
      • angle 控制了光錐的半形。
      • penumbra 控制了光錐的邊緣模糊程度,值為 0 到 1 之間的浮動值,0 表示邊緣清晰,1 表示邊緣完全模糊。
  4. 光照衰減:
    • 與點光源相似,聚光燈也具有衰減效果。隨著距離的增加,光源的強度會衰減。
    • 你可以調整 衰減距離 (distance) 和 衰減係數 (decay),來設定光照的強度和範圍。
  5. 陰影:
    • 聚光燈可以投射陰影,適合用來建立光照集中在某個區域的效果。

場景

  1. 舞臺照明: 聚光燈通常用於舞臺表演,照亮特定區域或演員,使其更加突出。
  2. 汽車前燈: 汽車頭燈可以模擬聚光燈的效果,用來照亮前方的道路。
  3. 手電筒或探照燈: 手電筒的光照範圍通常是錐形的,類似於聚光燈,適合用來照亮小範圍區域。
  4. 遊戲中的聚焦效果: 在遊戲或虛擬現實中,可以用聚光燈來突出顯示某些重要物體或區域,比如在關卡中照亮目標物體或道具。
  5. 燈光特效: 在建築視覺化或電影製作中,聚光燈常常用於建立某種特殊的光影效果,例如光束穿透煙霧或光斑效果。

屬性

new THREE.SpotLight(color, intensity, distance, angle, penumbra, decay);
  • color: 光源的顏色,預設為 0xffffff(白色)。
  • intensity: 光源的強度,預設為 1
  • distance: 光源的照射範圍,預設為 0,即光源的光照沒有限制。
  • angle: 光錐的開口角度,單位為弧度。預設值是 Math.PI / 3(60 度)。
  • penumbra: 控制光錐邊緣的模糊程度,值在 01 之間,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)

燈光的屬性與配置

每種光源除了位置和強度之外,還有很多可以調整的屬性。瞭解這些屬性,有助於我們更好地控制場景中的光照效果。

  1. 顏色與強度
    光源的顏色決定了它照射的光線的顏色,強度決定了光線的亮度。通常,白色光線的強度會影響場景的亮度,而顏色的改變會影響整體的色調。

調整顏色和強度:

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 還允許我們使用光源與材質的結合,創造出更加複雜的光影效果。在此部分,我們將介紹一些常見的進階技巧。

  1. 光照貼圖
    光照貼圖(Lightmap)是一種預計算的光照資訊紋理,它可以儲存光照、陰影和反射等資訊,並將這些資訊應用到模型的表面。這種技術常用於靜態場景中,特別是在場景的複雜計算(如全域性光照、陰影等)較為消耗效能時,透過光照貼圖可以大大提高渲染效率。

  2. HDR 環境光貼圖
    HDR 環境光貼圖(High Dynamic Range environment map)是一種高動態範圍的紋理,它包含了更多的亮度和細節,能夠真實地模擬環境中的光照效果。HDR 環境光貼圖通常用於提供更高質量的反射、光照效果,適用於更真實的影像渲染。

  3. 反射與折射
    反射和折射是透過燈光與物體表面相互作用產生的效果。在 Three.js 中,我們可以使用鏡面反射或折射來增加場景的真實感。

  4. 光源的動畫效果
    燈光的動態效果可以透過修改光源的屬性(如位置、顏色、強度等)來實現。Three.js 提供了豐富的動畫機制,結合光源的屬性,可以製作出非常豐富的燈光動態效果。

    常見的燈光動畫:

    • 閃爍效果: 模擬燈光的閃爍,例如模擬霓虹燈或電燈的閃爍。
    • 漸變效果: 燈光的強度或顏色漸變,模擬燈光的逐漸變亮或變暗。
    • 移動光源: 讓光源在場景中移動,模擬手電筒、車燈等效果。

Three.js學習:https://www.threejs3d.com/

相關文章