2015年8月26日 星期三

淺談Unity Blacksmith專案中的大氣散射

作者:TORBJORN LAEDRE 
原文:http://blogs.unity3d.com/2015/05/28/atmospheric-scattering-in-the-blacksmith/ 
翻譯:Eric

早在Blacksmith的規劃階段,我們就想要一個能比內建的霧氣選項提供更多控制和細節的大氣散射方案。而且,我們想要一些如同電影般著重表現波瀾壯闊的空中透視效果。

在我們著手專案的散射方案之初,我們首先參考了來自Tomoyuki Nishita的幾篇論文,實現並測試了裡面所提到的一些模擬方案。在對各分鏡進行了初步的實驗和原型建模後,我們覺得最好能夠採用一個能在各個分鏡中都有出色美術表現的方案。

我們所需要的,是一個能夠從各方面逼真表現物理模型的解決方案,同時它應該允許我們能根據需求對規則作出修改。同時希望該方案不會對短片的運行效率帶來太大的負擔,所以我們當時定下的目標是能基於每個頂點,而不是各個像素來進行運算。

我們目標是對物理模型進行瑞利(Rayleigh)散射和米氏(Mie)散射的綜合模擬。同時,我們還添加了用於表現各種低海拔散射的第三個元素;我們將之統稱為高度散射。

另一個物理基礎模型分歧的關鍵就是我們決定繼續使用HDR天空紋理,而不是通過程式去產生天空和雲彩。顯而易見,這樣的選擇所帶來的最大缺點就是:動態表現日夜變化會變得更加困難(所幸我們在Blacksmith中並沒有這方面的需求)。而它帶來的最大優勢就是:充分保留了我們在美術細節上的控制能力。 



瑞利散射 RAYLEIGH SCATTERING


在現實世界中,因為有瑞利散射的存在,我們才能在白天的時候看見明朗的藍天、在日出和日落的時候目睹一片緋紅。而在我們的模擬中,我們忽略了太陽本身,僅僅關注構建由於日光的輸入輸出帶來的散射所產生的色彩和黯淡。


太陽的視覺呈現可以添加在天空的紋理中,或者作為為米氏散射的一部分,或者利用一個太陽耀斑的圖片,或它們的任意組合。在最基礎的核心部分,瑞利散射的密度被歸結成一個由瑞利相位函數調制的輝度指數。當然,我們在輸入和提取的數據當中添加了一些額外的控制。

由於我們並不模擬不同波長的光穿過大氣層的情況,所以我們所計算的密度都是一些標量值。我們採用了一個HDR顏色斜坡,以允許入射散射光在水平到竪直向上範圍內能夠取到不同的色調,並採用了一個距離感知函數用於合成最終的色相。


不同散射配置下的瑞利散射分量

米氏散射 MIE SCATTERING


陽光在大氣中的米氏散射造就了太陽的光暈、灰白色外觀的雲彩,以及我們看到的那些受污染城市上空的霧霾。與瑞利散射對所有的方向均勻地散射光線不同,米氏散射具有很強的方向性。

在我們的模擬中,我們利用米氏散射來呈現霧霾和環繞太陽的光暈。因此,我們對它非常頻繁地進行著色,來彌補我們在瑞利散射中對太陽的忽略。從技術上說,我們的瑞利散射和米氏散射所用的函數非常相似,施加到輸出的相位函數是它們之間最為顯著的區別。

和許多的其他實現一樣,我們使用Henyey-Greenstein散射函數來控制米氏散射的各向異性或其方向性。


不同散射配置下的米氏散射分量

那些研讀過有關論文的行家可能會笑話我們所採用的一些名詞,不過我們還是希望大家不要在意這些細節,在這方面給我們一些小小的「自由」。我們發現,在早些時候,人們在描述「天空散射」時採用「瑞利」這個名詞,在描述「太陽光暈」時採用「米氏」這個名詞。因此,即使從物理模型到執行模型的過程中這些名詞被簡化了,在這裡,我們還是決定繼續沿用它們。

高度散射 HEIGHT SCATTERING


高度散射呈現了大量低海拔散射效果的混合形態,包括了輻射霧、地面霾和低窪雲。在我們的實現中,對高度散射的實現相當簡單:直接通過一個定義的海平面和高度衰減得出高度散射的密度。然後,這將基於距離的指數密度縮放,整個著色的色調正是我們所期望的。


不同散射配置下的高度散射分量


散射遮擋 SCATTER OCCLUSION


由於我們的散射主要由陽光向觀察者的角度散射所引起——當它們離觀察者較遠,或者在往觀察者的路上顆粒被吸收時 - 如果物體擋住了太陽的光芒,那麼就應該引發一些合理的遮擋。

為了處理這種情況,我們在一個縮減的、屏幕外的緩衝區內,對定向光的級聯陰影貼圖進行射線匹配,並累計在射線方向上由遮擋所引起的縮減量。當把散射應用到輸出像素時,我們利用一個邊緣感知濾波器對此遮擋貼圖進行上採樣,並用它合成像素的最終顏色。

在合成階段我們遇到了一點小麻煩:因為我們的解決方案僅適用於是單散射,所以我們不能簡單地屏蔽掉所有的入射散射光,因為這將讓我們有一個非常黯淡的、不自然的圖像。我們也不希望因此將整個方案擴展成更為複雜和代價高昂的多重散射。最後,我們發明瞭一個「間接因數」,指明一個特定參數來處理散射的比例,這樣便不會顯得過於直接。


不同散射配置下的正確遮擋


最終整合


現在剩下的就是結合不同的分量來合成最終圖像了。將瑞利散射,米氏散射和高度散射的分量疊加起來,我們就得到一個還算不錯的顏色組合。


將瑞利散射、米氏散射和高度散射結合起來

接下來,我們需要確保我們充分利用了前面提到的遮擋緩衝區。我們使用不同的強度參數來調整被施加到直接散射、間接散射、雲和天空的散射量的遮擋強度。


組合完成後含有遮擋的散射


最後,唯一剩下的事情就是將混合好的散射與所繪制的圖像結合起來。我們通過累計的總消光將所傳輸的圖像變暗,再通過累積的入射散射來亮化它。這就產生了我們的示例場景的最終合成。



最終的合成

演示時間!


我們將大氣散射部分抽離到了一個獨立的專案,你可以透過Asset Store下載它。

除了所有構成這個專案的程式碼和著色器,專案還包含產生文中圖片效果的所有圖像預設值。其中包含的readme文檔說明瞭這些不同配置選項的含義。

沒有留言:

張貼留言

關於我自己

我的相片
Unity台灣官方部落格 請上Facebook搜尋Unity Taiwan取得Unity中文的最新資訊