在完成高光反射的 GGX 預過濾后,我們還需要處理環境光的漫反射部分。本階段(Stage 3)將基于 Lambert 分布對環境貼圖進行無權重預過濾,生成用于漫反射計算的環境數據。與高光反射的方向性不同,漫反射是光線在粗糙表面的均勻散射,因此需要用更適合均勻分布的 Lambert 模型進行預過濾。
核心目標
漫反射的核心特性是 “光線在表面向所有方向均勻散射”,其強度僅與光線入射角(與法線的夾角)相關。本階段的目標是:
- 基于 Lambert 分布生成均勻的半球采樣方向;
- 對環境貼圖進行 “無權重平均”(所有方向貢獻均等),得到漫反射環境光的預過濾結果;
- 將結果存儲在環境圖集的指定區域,與之前的高光數據形成完整的 PBR 環境數據集合。
準備工作
- 前置條件:已完成 Stage 1(基礎環境圖集)和 Stage 2(GGX 高光預過濾),獲得包含多級數據的
envAtlas
; - 輸入資源:
sourceCube
(原始立方體貼圖)、envAtlas
(待寫入漫反射數據的圖集); - 工具依賴:Three.js 環境(
renderer
、scene
、camera
)、SampleGenerator
(已實現 Lambert 樣本生成); - 理論基礎:了解 Lambert 漫反射模型(
diffuse = (albedo / π) * irradiance
),其中irradiance
是環境光在半球上的平均強度(本階段預計算的核心)。
Lambert 漫反射與無權重預過濾
Lambert 模型描述了理想漫反射表面的反射規律:光線入射后向所有方向均勻散射,反射強度僅與光線與法線的夾角余弦(n·l
)成正比。對于環境光的漫反射計算,需要預計算輻照度(Irradiance)—— 即環境光在半球上的平均強度(對所有方向的環境光進行積分)。
與 GGX 高光預過濾的 “加權平均” 不同,Lambert 預過濾是 **“無權重平均”**:所有方向的環境光貢獻均等(僅需考慮方向是否在半球上),因此采樣時不需要按分布權重加權,直接取平均即可。
實現步驟詳解
步驟 1:明確 Stage 3 的圖集存儲區域
漫反射預過濾結果通常只需一個級別(因為漫反射對細節不敏感,低分辨率即可滿足需求)。以 512x512 圖集為例,存儲位置為:
用途 | 圖集內位置(x,y) | 分辨率(寬 x 高) | 說明 |
---|---|---|---|
漫反射輻照度 | (128s, 384s) | 64x32 | 位于 Stage 1 和 Stage 2 數據的中間區域,尺寸為 64x32(2:1 等矩形比例) |
s = size / 512
:適配不同圖集尺寸(如 512x512 時s=1
,256x256 時s=0.5
)。
步驟 2:生成 Lambert 樣本
漫反射的均勻特性決定了采樣方向需要在半球上均勻分布,SampleGenerator.generateLambertSamples
負責生成這些樣本:
// 生成2048個Lambert樣本(均勻分布在半球上)
const samples = SampleGenerator.generateLambertSamples(2048, sourceTotalPixels);
// 將樣本打包為紋理,供片段著色器解碼
const samplesTex = SampleGenerator.createSampleTexture(samples);
- 樣本內容:每個樣本包含一個均勻分布在半球上的方向向量(
L
)和對應的 MIP 級別(控制環境貼圖采樣精度); - 2048 個樣本:平衡精度與性能(樣本