本文 AI 產出,尚未審核

Three.js 後製特效 (Post‑Processing) 教學 – Bloom、Depth of Field、Motion Blur


簡介

在 3D 網頁應用中,光影與鏡頭效果往往是決定視覺品質的關鍵。即使模型、材質已經非常細緻,缺少後製特效仍會讓畫面顯得平板、缺乏層次感。Post‑Processing(後製特效)正是透過在渲染完成後對畫面做一次或多次的濾鏡運算,為場景加入光暈、景深、動態模糊等效果,讓作品瞬間升級為「專業級」的視覺體驗。

在 Three.js 生態系中,EffectComposer 與一系列 Pass(通道)提供了彈性極高的後製管線。本文將聚焦 Bloom、Depth of Field(景深)與 Motion Blur(運動模糊) 三大常見特效,說明概念、示範程式碼,並分享實務上常見的陷阱與最佳實踐,幫助初學者快速上手、進階開發者優化效能。


核心概念

1. 後製管線的基本組件

元件 功能說明
EffectComposer 負責管理多個 Pass,將渲染結果依序傳遞、合成最終影像。
RenderPass 首個 Pass,將 Three.js 場景渲染到緩衝區,供後續 Pass 使用。
ShaderPass / Pass 以自訂或內建的 shader 進行影像處理,如模糊、顏色校正等。
RenderTarget 離屏緩衝區,存放每一次 Pass 的輸出,避免直接寫回螢幕。

重點:後製特效不是在 WebGLRenderer 直接完成,而是透過 EffectComposer 把渲染結果「再加工」一次或多次。


2. Bloom(光暈)

Bloom 會將亮部的光能向周圍擴散,模擬相機鏡頭或人眼在強光下的光暈。Three.js 官方提供 UnrealBloomPass,適合大多數需求。

2.1 主要參數

參數 說明
strength 光暈強度。數值越大,光暈越明顯。
radius 擴散半徑,控制光暈的範圍。
threshold 亮度門檻,低於此值的像素不會產生光暈。

2.2 範例程式碼

// 基本設定
import * as THREE from 'three';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';

// 建立 renderer、scene、camera(此處略過)...

// 1. 建立 EffectComposer
const composer = new EffectComposer(renderer);

// 2. 加入 RenderPass(渲染場景本身)
composer.addPass(new RenderPass(scene, camera));

// 3. 設定 BloomPass
const bloomPass = new UnrealBloomPass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    1.5,   // strength
    0.4,   // radius
    0.85   // threshold
);
composer.addPass(bloomPass);

// 4. 渲染循環
function animate() {
    requestAnimationFrame(animate);
    // 更新物件...
    composer.render();
}
animate();

小技巧:若只想讓特定物件產生光暈,可使用 渲染層 (layers)自訂遮罩 (mask),將不需要 Bloom 的物件排除。


3. Depth of Field(景深)

景深模擬相機聚焦點前後的模糊程度,使觀者的視線自然聚焦於關鍵區域。Three.js 常用 BokehPassDOFPass(來自 postprocessing 套件)實作。

3.1 主要參數

參數 說明
focus 聚焦距離(相機到聚焦點的距離)。
aperture 光圈大小,光圈越大(數值越小)模糊越明顯。
maxblur 最大模糊半徑,限制過度模糊。

3.2 範例程式碼(使用 BokehPass

import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js';

// ...先前的 composer、renderPass 已建立

const bokehPass = new BokehPass(scene, camera, {
    focus: 1.0,          // 聚焦在 1 單位距離
    aperture: 0.025,     // 光圈
    maxblur: 0.01,       // 最大模糊半徑
    width: window.innerWidth,
    height: window.innerHeight
});

// 若需要先渲染一次以取得深度緩衝區
bokehPass.renderToScreen = true; // 最後一個 Pass 才需要渲染到螢幕
composer.addPass(bokehPass);

注意BokehPass 需要深度緩衝區支援(renderer.getDepthTexture()),在建立 WebGLRenderer 時請設定 depth: true


4. Motion Blur(運動模糊)

Motion Blur 讓快速移動的物體產生拖尾感,提升畫面的真實感。Three.js 有兩種常見實作方式:

  1. 基於速度緩衝區的模糊ShaderPass + 自訂速度貼圖)
  2. 累積緩衝區 (Accumulation Buffer):將前幾幀畫面混合,產生簡易的模糊。

下面示範使用 ShaderPass 搭配 VelocityPass(來自 postprocessing 套件):

import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
import { VelocityPass } from 'three/examples/jsm/postprocessing/VelocityPass.js';
import { MotionBlurPass } from 'three/examples/jsm/postprocessing/MotionBlurPass.js';

// 1. VelocityPass 先算出每個像素的螢幕空間速度
const velocityPass = new VelocityPass(scene, camera);
composer.addPass(velocityPass);

// 2. MotionBlurPass 依速度貼圖產生模糊
const motionBlurPass = new MotionBlurPass({
    blendFunction: THREE.AdditiveBlending,
    intensity: 0.8   // 模糊強度
});
composer.addPass(motionBlurPass);

實務建議:若場景中有大量粒子或快速相機移動,累積緩衝區的方式較省資源;但若需要根據物件速度做精細控制,請使用速度緩衝區方案。


常見陷阱與最佳實踐

陷阱 說明 解決方式
效能急遽下降 多個 Pass 同時執行會導致 GPU 計算量翻倍。 只保留必要的特效,使用 setSize 動態調整解析度;在低階裝置上關閉 Bloom 或降低 radius
深度緩衝區缺失 BokehPassDepthOfFieldPass 需要深度貼圖。 建立 WebGLRenderer({ antialias:true, depth:true }),或手動加入 depthTexture
光暈洩漏到 UI Bloom 會把 UI(HTML overlay)也渲染進緩衝區,產生不必要的光暈。 把 UI 放在 renderer.domElement 之上,或在 composer 前後分別渲染 3D 與 UI。
畫面抖動 Motion Blur 使用累積緩衝區時,若相機或物件位置在每幀不夠平滑會出現抖動。 確保更新邏輯在 requestAnimationFrame 前完成,或使用時間插值 (interpolation)。
通道順序錯誤 Pass 的加入順序會影響最終結果,例如 Bloom 必須在景深之前。 依需求測試,常見順序:RenderPass → BloomPass → DepthOfFieldPass → MotionBlurPass

最佳實踐

  1. 分辨率縮放:對非核心特效使用 composer.setSize(width/2, height/2),再上采樣回螢幕,能顯著降低 GPU 負擔。
  2. 層級控制:利用 camera.layersobject.layers 把需要 Bloom 的物件放在獨立層,搭配 MaskPass 只對該層做後製。
  3. 自適應品質:根據 navigator.deviceMemoryperformance.now() 的幀率,動態調整特效參數(如 strengthmaxblur)。

實際應用場景

場景 推薦特效組合 為何使用
科幻射擊遊戲 Bloom + Motion Blur 光暈強化激光、子彈的光線感;運動模糊提升彈道速度感。
寫實建築漫遊 Depth of Field + subtle Bloom 景深讓觀者聚焦在入口或焦點建築,柔和光暈提升光線散射真實感。
音樂視覺化 Bloom + Motion Blur (high intensity) 音浪與粒子在節奏中快速移動,模糊與光暈創造動感氛圍。
教育模擬 (如顯微鏡) Depth of Field 只聚焦在樣本的特定層面,其他區域自然模糊,模擬實驗室光學效果。
虛擬展覽 低強度 Bloom + optional DOF 提升展品的光澤感,同時保持整體流暢度,避免過度特效影響觀展體驗。

總結

Three.jsPost‑Processing 為 3D 網頁應用提供了「相機」與「鏡頭」層面的視覺調整。

  • Bloom 讓亮部光暈自然擴散,提升光源與金屬材質的視覺衝擊。
  • Depth of Field 透過聚焦與模糊,導引使用者的視線,營造寫實或戲劇化的氛圍。
  • Motion Blur 為快速移動的物件或相機增添動態感,使畫面更具臨場感。

掌握 EffectComposerPass 的組合與參數調校,並留意效能、深度緩衝區與渲染順序的細節,就能在不同的專案中靈活運用這些特效,為你的 Three.js 作品增添專業級的視覺魅力。祝你玩得開心,創作出令人驚豔的 Web 3D 體驗!