聊一下球諧函數(Spherical Harmonics)計算光照

使用球諧函數(Spherical Harmonics, i.e. SH)模擬動態全局光照是遊戲引擎里通用的解決方案。針對SH的介紹大部分過於偏學術,在實際的應用中去理解會更淺顯易懂一些。

實時計算間接光照是一個難題,因為要計算最少一次積分。數學上常常把很難在某個空間得到求解的問題,轉換到另外一個空間里,利用新空間的某些特性,降低求解難度。其中泛函分析是以函數空間為研究對象,利用某些已知函數空間的特性,去簡化問題求解。其中SH為基的函數空間就是常用的工具之一。SH除了滿足作為函數空間basis的基本條件外,還有以下特性:

  • 針對處處光滑連續的問題,SH basis的解快速收斂。這個性質說明,像間接光照這樣的低頻問題(高頻的問題可以用小波求解),可以在SH空間用極少的basis項去快速得到近似解(3 bands, 9 coefficients)。
  • 旋轉不變。這個性質保證當環境光照發生相對旋轉的時候,不會出現計算結果的閃爍。
  • Lighting function和max(cos(theta), 0) transfer function的卷積(即我們要求解的環境光照的積分)正好可以壓縮存貯在一個Matrix4x4里,對法線運算後重構環境光照。另外光滑連續函數在3D空間的卷積等於SH空間的點積。這個性質可以用來計算更複雜的動態光照效果(Precomputed Radiance Transfer)。

以Unity為例,其對天空盒的SH計算參考《Stupid Spherical Harmonics(SH) Tricks》里的演算法。實現的步驟首先是Prefiltering,先對環境貼圖的像素逐個對SH Basis做一次加權採樣投影。第二步是提取用於法線重構光照環境需要的矩陣信息。《An Efficient Representation for Irradiance Environment Maps》里有完整的推導過程。這一步Unity的演算法和Paper里給出的常數C1-C5差了一個PI,是在實際運算中抵消了。

知道原理後,可以把引擎的這部分功能提取出來給美術人員使用。一個應用場景就是角色的光照。比如有些遊戲里在夜晚的場景為了突顯角色, 想讓角色的受光強度和色調比場景要明亮強烈一些,即自定義天光。

一種方案是單獨一個角色編輯場景烘培SH,然後直接從引擎中提取unity已經計算好的SH。這種方案優點是烘培速度快。缺點是不直觀,美術人員不能立即查看角色在關卡場景里的最終效果,需要反覆在兩個場景之間切換,調整參數。另外一種方案是在關卡場景里烘培和查看角色的天光效果,每次把調好的天光烘培完以後,提取給角色使用,然後再把關卡場景測試角色用的light probe信息revert。這種方案優點是可以在關卡場景直接查看角色的天光效果色調強度是否合適。缺點是unity 5.0以後的版本不能單獨烘培light probe, 每次場景的光照烘培時間都很長, 調整反饋慢。

下圖是一個自定義烘培角色光照結果(左邊是Unity引擎烘培的天光。 中間是直接從同樣的Irradiance Map計算的結果,和Unity的計算結果是一樣的,但是更快,方便在場景里預覽。 右邊是隨意指定的一張HDR Irradiance Map的結果。) 另外角色的Glossy Reflection Map也可以單獨指定,方便自定義一些金屬質感的表現,同樣是一鍵烘培,不再需要引擎計算。

推薦閱讀:

《全局光照技術》眾籌最後6天!
More DETAILS! PBR的下一個發展在哪裡?
線下技術分享活動計劃

TAG:渲染 | Unity遊戲引擎 | 全局光照 |