天天看點

Lightmass分析(三) 核心流程Intro核心流程簡單說明參考文獻

Intro

Lightmass分析 系列文章前言及目錄

Lightmass 是 Unreal Engine 裡用于烘焙靜态全局光照的工具. 全局光照 (Lightmass) 建立具有複雜光互動作用的光照圖, 例如區域陰影和漫反射. 它用于預計算具有固定和靜止運動性的光源的照明貢獻部分. UE4 Lightmass 手冊.

Lightmass 借用 PhotonMapping 算法的思想, 實作了自己的全局光照工具. 正常的 PhotonMapping 是一種渲染方法, 尤其是其 render-pass, 借助 PathTracing 最終渲染出某一視角下的場景. 而 Lightmass 更多的是為了産生光照貼圖, 在實時渲染過程中的全局光照提供資料. 這也導緻 Lightmass 的後半部分與正常的 PhotonMapping 有一定的差别.

個人認為 Lightmass 的代碼之是以難以閱讀, 一是過程中涉及的類和函數繁多, 二是用于儲存中間結果的資料結構與其産生的作用難以建立聯系, 三是流程中除了核心邏輯外, 穿插着很多為了優化運作效率的部分.

繁雜的處理過程和資料流動會分散我們的精力, 幹擾整體分析. 是以下面先将核心流程抽取出來, 并隐藏各種複雜的實作細節, 隻關注輸入輸出, 讓我們可以在有一個整體的了解之後再嘗試深入研究具體細節.

核心流程

  • 發射光子(直接, 間接), 計算光子的輻照度并建立光子圖
  • 緩存物體表面的光照資訊
  • 評估幾何表面的光照(直接光照, 間接光照)
  • 将光照結果編碼為光照貼圖
Lightmass分析(三) 核心流程Intro核心流程簡單說明參考文獻
Lightmass分析(三) 核心流程Intro核心流程簡單說明參考文獻

簡單說明

"發射光子"之後我們會得到三個光子圖以及一個輻照度光子圖. 三個光子圖分别是 DirectPhotonMap, FirstBouncePhotonMap, SecondBouncePhotonMap. 分别表示直接光照光子圖, 間接光照第一次反彈光子圖, 間接光照其餘反彈光子圖. 輻照度光子圖在一般情況下近似為上面三張光子圖的合集, 用來儲存場景中光子的輻照度, 為最後的光照評估提供資料.

由于通過不同方式産生的光子, 在影響範圍, 光照貢獻等很多方面都存在差異, 是以在發射光子的時候直接進行區分對後續流程非常友好.

PS: 這裡所謂的"光子圖"實際上都是八叉樹

光子輻照度評估公式: 光子輻照度 = 直接光子輻照度 + 第一次反彈輻照度 + 第二次及後續反彈輻照度.

其中直接光子輻照度預設不使用光子評估(公式中對應項的值不被累加到結果中), 後面的項是否生效與反彈次數的設定有關. 最後光子的輻照度根據其附近的光子的 Power 經過 ConeFilter 計算得出.

為什麼要使用表面緩存? 我們對場景的一個基本假設就是場景中物體表面的光照是連續且平滑過渡的. 這讓我們可以使用少量樣本采樣其周圍環境, 再通過插值的方式擷取完整的全局光照資訊. 可以看出這個過程中存在很多的均值操作需要計算, 每個離散位置的光照都會多次參與運算. 是以提前緩存部分資料是明智且必要的操作.

Lightmass 中的直接光照和陰影預設通過 RayTracing 方式計算, 間接光照則使用 Final Gather 的方法計算. 在這之後将經過球諧編碼的資料儲存到 Lightmap 中即可在實時渲染的時候使用. (詳情請移步系列後續文章)

參考文獻

Jiff:Lightmass分析之 經典Photon Mapping算法介紹

Jiff:LightMass源碼分析之光子追蹤實作

Jiff:LightMass源碼分析之光照評估