《Red Dead Redemption2》的大氣雲霧技術
2020年03月26日16:41

  技術一直行業領先,但是一直低調的Rockstar,終於在SIGGRAPH 2019放了大,做了《Red Dead Redemption2》(大表哥2,Red Dead: Redemption II)中的大氣雲霧技術分享。

  看得也是近幾年最過癮的一篇了,high點:

  是發售遊戲中實際使用的、完整的、系統化的技術合集

  代表當前最強的大氣系統

  技術探索&整合nice,積累深厚,運用純熟

  理論、實際開發已經性能優化有很好的平衡,堪稱R&D的典範

  motivation & overview

  這也是很多優秀工作室做事的一個方法,在處理開創性事情的時候,就會列出一些依據來進行“合理突破”。

  這裏筆者也是深有共鳴,是一個很有章法的做事方式。

  Rockstar這裏就包括:

  在《Red Dead Redemption1》中已經有了不錯的大氣系統,而且這個確實很重要,當然要在2中進一步發展。

  受到一些名畫的啟發,筆者也是在看一些繪畫,去一些景色壯觀的地方都會帶來很強的創作衝動(雖然我是寫程序)。

  以及基礎的atmosphere scattering系統中,現在確實還有很多可以完善的地方。

  通篇是分成data model、render、scene integration三個部分。

  data model

  這部分是一個知難行易的模塊,所以直接列下特性和做法。

  雲的分佈

  這塊比較類似Horizon Zero Dawn的做法:

  https://blog.csdn.net/toughbro/article/details/48844649

  使用分佈圖來定義雲的整體分佈:

  [ 出來效果這樣的,同時可以有多層的雲 ]

  霧的分佈

  類似雲的分佈,霧也是有一個分佈:

  [ 沒有fog map的版本 ]

  [ 有fog map的版本 ]

  雲的形狀定義

  這塊參考的15年的Horizon Zero Dawn的做法:

  https://blog.csdn.net/toughbro/article/details/48844649

  基本原理差不多,有一些自己的特色:

  這裏定義雲的形狀:

  1個lut定義雲的厚度

  1x3d noise,2x2d displacement

  效果目測要比Horizon Zero Dawn的好一些。

  render

  接下來我們看第二部分,這部分主要談渲染部分,包括scattering和lighting的render,相對內容也多一些。

  可以說這部分是本篇重點所在。

  voxel+ray marching

  處理大氣效果時候,為了兼顧近處的精度和場景的宏大,使用了混合方案:

  近處使用voxelization的方式,得到高精度的渲染結果,reference了Assassin's Creed的一個文章:

  https://blog.csdn.net/toughbro/article/details/46706837

  遠處使用ray marching的方式,平衡效果和效率

  光照模型

  這裏最終的光照模型,使用這樣的公式列出來,這個比較像大家所熟悉的PhysicallyBasedLighting中的macrofacet公式的模樣,其中三項如下:

  P:phase的縮寫,是光通過media時候的scattering的情況

  V:visibility,我們可以近似理解成shadow類的東西

  L:lighting,也就是光源,直接光,ambient lighting等等

  phase項

  這裏分成兩個層級:

  1、基礎phase模型,是基於Henyey-Greenstein phase function(簡稱HG),這個模型對於single forward scattering處理的比較好。

  2、多種scattering組合,基於上面的擅長處理single forward scattering的HG(heney-greenstein)模型。

  3、==使用多級HG模型來模擬multi scattering

  4、==使用一個clamp操作來模擬back scattering

  這裏稍微貼下HG模型的樣子:

  這裏g項是[-1,1]之間,代表從back scattering到forward scattering的情況,表示media的屬性。

  theta就是各個角度,phase function就是關於角度的函數麼。

  HG函數這部分還是比較物理的,但是multi scattering部分就是比較變通了,是多級HG來模擬multi scattering,各級之間的權重由美術定義。

  然後給定g,關於theta就可以預計算出來,放到LUT(look up tabble)貼圖中:

  最後放在一起的效果:

  只有1級HG function的時候:

  2級HG function模擬multi scattering+back scattering:

  “physically based“的度和變通

  這裏也是涉及到一個“physically based“的程度問題,原則上我們是要physically based這樣會儘可能的物理化,好處現在PBR已經論證的非常好了。

  但是實際開發中,我們會遇到各種需要折中的地方,或許是物理模型不夠好,或許計算過重等等。

  這時候,none-physically-based就還是需要了,這時候建議是,儘可能在高層去做hack和變通,保持底層原子項部分的“physically based“正如phase function這裏,底層是HG function,高層是美術來指定的函數。

  visibility項

  這一項就是光照信息中間被遮擋的情況,和直接光照有點不一樣的是,由於這個是一個scattering的過程,所以完整來講是光線一路射過來中間每一步的visibility情況的疊加。

  落實到實際計算中,就是ray marching中間每一步的visibility情況的疊加。

  這裏visibility主要針對影響大的兩個case:terrain、cloud來做計算。

  terrain使用ray marching的方式構建一個shadowmap信息;

  cloud使用exponential shadow map的方式,來encode shadow map信息,來達到非常軟陰影的信息,一共存了6mips(esm的使用在Assassin's Creed的文章里也有)。

  lighting項

  ambient lighting部分:

  遠處的ray marching部分,就是sky ambient,把sky scattering存到低精度的paraboloid貼圖裡面

  近處的frustum voxelization部分,sky light+light probe lighting*AO

  local light 部分,直接就讀light cluster volume。

  froxel

  froxel也是技術創造的名詞:這個的縮寫frustum voxel;

  也是用voxel的形式,存儲低精度的場景volume信息,然後用於低頻信息渲染,比如scattering;

  《Red Dead Redemption2》中的存了三種信息:

  shadow

  material

  lighting (結合前兩者來計算)

  shadow volume,注意這個不是陰影算法的shadow volume,就是存放shadow的volume信息,包括了普通shadow和cloud shadow;

  中間使用了temperal filtering來處理穩定的問題;

  material volume,各種材質信息,也帶上了wind交互等等(讓我想起了God of War的風力存在volume中)。

  也有temperal filter。

  ray marching

  可能有的讀者對ray marching還不是特別熟悉,ray marching特別常用於volume類的渲染中,鑒於一些計算硬件和數據的限製,有些情況難以很容易的使用ray trace的方式尋找交點,比如local reflection中要對depth buffer找交點。那麼就用步進的方式來找交點,這種方法就是ray marching;這裏的步長的選擇是應用ray marching的時候需要具體斟酌的地方。

  回到《Red Dead Redemption2》,ray marching的步長策略選擇也是頗費心思:

  考慮到場景深度、ground plane、cloud dome

  另外要仔細考慮到雲層的厚度信息

  即便這樣也很容易跳過比較薄的雲層。

  ray marching優化

  先看下最終的性能

  可以看到ray march是佔據著性能的大頭,而且這還是經過優化過之後的結果。

  這裏優化就基於兩個大的策略:low resolution + temperal,也就是在低解像度上做ray march計算,然後通過多幀來重建。

  這個部分很精彩,我們多展開。

  這裏ray march的起點是在froxel的末端,帶上blue noise(可以理解成一個頻率較高的noise了,感興趣可查下)做偏移。

  半解像度大小,然後分4幀來計算。

  ray march reconstruct

  由於是分4幀來構建,所以每幀只能ray march 2x2 像素中的一個,另外三個就要從history buffer中拿。

  這裏用了temperal相關的很多做法,一些在taa中頗為常見。

  1、使用了3x3像素color aabb clamp的方式

  2、大的深度斷裂的地方,臨接像素就不考慮了

  3、在深度斷裂(depth discrepancies)的地方,放更多的ray

  這裏能正確的判定出來depth discrepancy還是比較棘手的,要做的事情就是在6x6(2x2 ray, 3x3 neighbouhood, 所以一共6x6)像素中,正確的識別depth的min/max;

  嚐試1,uniform分佈

  可以看到在frame2裡面,min/max就錯了,這個會導致誤判。

  嚐試2,checker board方式

  能處理的case好很多:

  但是這種情況下還是不行:

  總之局部的分佈策略總是有cover不住的情況了,還是要引入整體的信息才行。

  嚐試3:checker board+depth neighborhood analysis

  先是拿到3x3tile(每個tile是2x2像素)的depth min/max,然後每一個tile中和其餘的8個點比,如果其餘的8個都是min,那麼這個就取一個max depth的點。

  up scaling

  up scale這裏是4taps dither,depth連續就平均,不連續就取最近

  效率

  長的ray march部分是最消耗的。

  scene integration

  第三部分,integration,也就是把計算好的光照等和場景集成起來。

  這裏是一個integration完整的示意圖,我們接下來可以一步步看看。

  sky scattering

  sky scattering算法上是Precomputed Atmospheric Scattering,三個特點:

  考慮了earth shadow

  分幀實時更新的

  存放在32x16x32的LUT中

  [ 用於sample sky scatter的深度信息 ]

  在sample sky scattering信息的時候,就不是ray march每一步都踩了,否則雖然更加正確,但是太費了。

  最終按照depth信息,就依據depth來sample一次。

  [ visibility信息 ]

  然後visibility信息(類似shadow)信息都是分離的。

  放在一起的效果:

  光照組成

  把前面列的放在這裏:

  frustum volume lookup

  ray march result

  sky scattering / transmittance

  sky irradiance probe

  地圖里32x32的3rd order spherical harmonics probe map, 每個probe覆蓋(256mx256m),這個用作sky irraidance probe。

  總結

  ppt本身的總結是有這麼幾條:

  volumetric效果是“一等公民”

  這是一個統一,基於物理,支持多種材質的scattering/transimitance系統

  近處是frustum align的volume based技術

  遠處是ray march based的技術

  個人的閱讀總結:除了第一篇的high點之外,有幾點印象非常深刻

  對大量的渲染技術運用的如此純熟靈活,非常給力

  能夠hold住如此複雜的系統,非常給力

  研發的本原的樣子

  一系列的筆記,可能是解讀技術文章以來最多的一次了,筆記部分基本上是大家看了原文之後大致能記住的部分,實際上原文涵蓋的內容要更多更雜,然後這背後還有更多的探索和嚐試,因為篇幅的原因沒有寫出來。

  讀的時候完全沒法像一些論文,尤其是少項目而重理論和demo向的,可以簡單的做抽像和總結,可以“一句話說清楚”。

  實際像《Red Dead Redemption2》這樣的項目,這個就是研發中所面臨的問題,理論摻雜著妥協與變通(hack),並且要覆蓋極高的複雜度。

  實際做的時候,宏觀的視野?是的;紮實的理論?是的;紮實的engineering?是的;充分的耐心?是的;靈活的變通?是的;

  像我個人之前做《天涯明月刀》《無限法則》相關的技術分享,ppt寫的時候往往寫得“重點突出”、“易聽易懂”甚至還帶著兩個笑話;

  而實際上,做項目開發中,就是一個複雜度高的多,繁雜的多的過程,但是那麼來寫ppt,往往觀眾會聽得雲裡霧裡,所以最終的結果還是“一句話說清楚”。

  《Red Dead Redemption2》,分享者也足夠耐心,列了方方面面,包括ray marching中優化的幾個失敗案例,確實更像研發原本的樣子。

  來源:騰訊遊戲學院

關注我們Facebook專頁
    相關新聞
      更多瀏覽