首頁 > 書法

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

作者:由 GameRes遊資網 發表于 書法日期:2022-10-10

復步數怎麼計算

暴雨、狂風、雷電,相信大家都十分熟悉現實中的這些天氣現象。這些現象體現了大自然的威能,給人極大的感官衝擊。在如今的端遊大作中,我們經常能感受到遊戲製作組在這方面下的大功夫,然而在手游上,由於手機的元件的功效遠低於PC端,如何平衡效能並充分利用手機上的裝置來進行模擬渲染,就成為了開發者重要的研究課題。

在由騰訊遊戲學堂舉辦的TGDC2022騰訊遊戲開發者大會上,騰訊互娛魔方工作室群引擎中心專家工程師陳家銘以手遊《暗區突圍》為例,向大家展示瞭如何通技術渲染最佳化手段使得手遊獲得了只有主機遊戲才能享受的特性。

以下是演講實錄:

大家好我是魔方引擎中心的技術專家陳家銘,很榮幸今年又可以在TGDC分享自己的工作成果,這一次要和大家分享的是手遊《暗區突圍》裡的動態天氣渲染技術。

首先介紹一下我所屬於的Studio魔方工作室群它成立於2010年是騰訊IEG四大遊戲工作室群之一,魔方包括了魔術師、魔鏡、魔王還有我所在的技術中心,我們擁有多個全球頂級的IP專案,包括了知名的《火影忍者》《航海王》《一人之下》《秦時明月世界》。還有自研的IP,包括《暗區突圍》《洛克王國》《王牌戰士》等等。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

《暗區突圍》是一款擬真的第一人稱射擊遊戲,為了讓玩家有更深的代入感,策劃希望把以前只有主機遊戲才能享受的特性都放在這款手遊裡面,也包括了今天的我要講的主題,動態天氣效果和體積雲等效果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

上圖是今天的內容大綱,首先我會講講大氣產生的基礎原理,以及我們在放到手裡面最後的一些相關定製以及最佳化,之後會講體積雲的渲染系統,還有裡面的一些技術細節,最後是一些相關的天氣效果的分享。我們先從天空大氣開始。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

大家可能會問為什麼我們手遊的天空不能簡單地用曲線來定義天空的顏色就好,而要搞很複雜的大氣呈現呢?其實天空的顏色是千變萬化的,會受到時間、地理位置、天氣和汙染等因素所影響。舉個例子,同樣是黃昏有可能這像左邊這一張圖,天空大部分的顏色都是藍色,而只有接近地平線的才呈現橙色,也有可能像右邊的圖片,整個天空都是偏紅色的。所以在寫實的遊戲裡面,如果要模擬各種的天氣變化,單單只是以曲線去做這個模擬,它的組合性是爆炸的,很難去編輯和維護。因此我們就會透過一個物理的方法去計算,那麼我們是如何計算呢?其實大氣是由不同的大小的粒子所組成的,天空的顏色都是由這些粒子對太陽光所構成的散射現象所確定的。為了渲染出大氣散射的效果,我們一般都需要在視點以光線行進來計算每個方向所得到的顏色。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

比如說在大氣層的A點方向到B點,我們就需要在這條射線上的位置,P0, P1, P2 利用相位函式算出所接受到的散射,然後呢再計算他們的積,那就是這個方向可以看到天空顏色的結果。然而這個方法其實在遊戲裡面實時算是很難實現的, 因為每個方向都可能要考慮到幾十到上百個取樣點。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們再看看虛幻引擎裡面是怎麼解決這個效能問題的。它利用了一系列的查詢表來減少計算量,具體而言,虛幻引擎在每一幀裡面可以使用這個計算著色器來生成4個基本的查詢表分別為:透光度的查詢表,它記錄了光線在場景裡面的傳遞情況。另外一個是多重散射的查詢表,就是用來快速算出多重散射的結果;還有一個是天空圖示的查詢表,它是基於透光度還有多重散射兩個表格,預先算好一個天空顏色;以及我們最終會有一張用來算天空透視效果的一個3D紋理表。

虛幻引擎的方案不單是基於物理的,對美術也挺友好,在中高階的移動裝置上也有良好的效能。可是在比較老的手機上,因為它們的頻寬非常有限也負擔不起每幀計算這麼多的查詢表,所以我們對它做了一些最佳化。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

首先我們會捨棄了空氣透視的資料,就改成用高度霧來代替它的效果,這樣的話我們場景裡的shader也可以節省一次的3D紋理的取樣,同時呢,捨棄了這一部分的資料之後,所剩下的查詢表都是二維的,因此我們可以利用上述著色器來更新它。

這是非常重要的,因為有許多的移動裝置依然對這個計算著色器的支援不太完善。由於我們遊戲裡面的局內時間變化比較慢,所以呢我們也可以分幀去計算每個LUT。就是說,我們每幀只計算裡面的一部分的畫素,這樣的話在低端的移動裝置上也可以承受。

為了做進一步的最佳化,我們也將天空圖示的查詢表改用了半八面體的引數化,同時也丟棄了地平線以下的內容。這不但節省了50%的光線行進的計算,也避免了查詢這個結果的時候,需要呼叫一個平方根指令的步驟。做了以上最佳化之後我們發現其實也可以把這個(shader)移植到CPU裡面去計算,而每幀的耗時大概是0。5ms左右吧,所以呢我們預留了這個方法在最老的手機上去使用。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

這是原始版本以及經過我們最佳化版本之後,在一天裡面三個不同時間段的一個比較。我們可以看到其實在太陽周圍稍微有一點點的偏差,但是在遊戲中其實是不容易觀測出來的。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們再看看最佳化之後天空渲染的效能,就從原始的1。35毫秒就降到了最佳化之後的0。78毫秒。所以,我們用半八面體投影之後節省了大概是40%的GPU耗時,同時效能也有一個明顯的提升。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

接下來我會繼續分享體積雲的處理。

有同學也可能會問,既然是手遊,為什麼不可以用帶法線貼圖的面片雲?

而要搞體積雲呢?我們主要有兩個原因,第一 ,我們剛開始的時候我們其實也嘗試過面片雲這個方案的,但美術覺得不太能表現他們要求的體積感,而且面片雲也比較難去模擬多重散射獨有的光照特性。第二個是面片雲一般都是預先烘焙的,而我們的遊戲要求在局內的天氣有一個實時的變化,雲的密度也會跟隨著天氣所改變的,面片雲就比較難去支援這樣的效果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

所以我們的方案參考了《地平線:零之曙光》團隊在2015年GDC上分享的案例,我在這裡做一個快速的回顧。當我們要從一個固定的方向望向雲層的時候,雲的顏色是從這個方向所散射而來的陽光和環境光所確定的。我們一般只考慮地面上距離2。4到6公里之間的雲層。因此我們在這兩個高度之間以光線行進來計算出這個方向而來的一個散射的亮度。

首先我們會在這條射線上平均分佈一些取樣點,然後計算出每個點上我們所可以接受的一個光照,之後呢我們會根據雲層的密度算出該點有多少個光可以散射到相機裡面,再把所有散射過來的光線能量相加就可以得到雲從這個方向散射而來的顏色。

但是我們還有三個疑問:

第一是雲層的密度是怎麼去定義呢?

第二個就是取樣點所接受到的光照到底有多少,如何給散射?

第三個是怎麼可以把這一個計算的效能最佳化到可以在手機上去跑?

我們後面會一個一個展開來討論。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

首先是雲的建模,就是怎麼去定義雲層的密度。我們會使用Worley噪聲生成3D紋理,然後呢讓它平鋪在天空中,這樣就可以定義出基礎的雲的密度。我們使用了基礎和細節兩層的噪聲,最終的結果都是把基礎的噪聲再減去細節所得到的結果。細節的噪聲會平鋪更多的次數,這樣的話,我們就不需要一個特別高的解析度就可以獲得足夠的細節。

但是僅僅是這樣的話也不可以創造出整個覆蓋天空的雲層。所以我們引入了一張稱為Weather Map的貼圖,這樣美術可以控制不同天氣狀態之下,雲的形狀以及分佈。它其實是一張正交投影的2D紋理,覆蓋了大概是地面40公里的一個範圍。Weather Map的R通道是雲的覆蓋率,這代表它的數字越高雲的密度也等於越高,G通道是用來定義雲的種類。此外我們還有一張稱為Cloud profile的2D紋理,主要是用來模擬雲在不同高度有不同形態的一個特性。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

剛才提到,我們是透過動態生成的Weather Map來控制雲層隨著天氣的變化。在我們的系統裡面,Weather Map是由Cloud Mask所組成的。美術可以在地圖中擺放的各種的Cloud Mask,就像右邊的動圖所展示的一樣。每個Cloud Mask都有一個材質來定義它所繪製到Weather Map裡面的內容,例如當材質輸出一個白色的圓形的一個特效的時候,對應的雲層就會變得更密集。

我們也可以輸出黑色則該位置的雲將被擦除。為了方便控制不同天氣下的雲層我們有兩個全域性的引數,一個是全域性的雲的覆蓋率,一個是全域性的雲的形態。這兩個值我們作為材質輸入傳遞給Cloud Mask並且進行內容的繪製。

一般情況下,我們會以Worley噪聲生成一個很大的Cloud Mask來定義基礎的密度,之後再補一些小的mask作為區域性的調優。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

在進一步講解雲的光照之前,我先介紹一下光吸收的物理定律:比爾-朗伯定律。假如陽光的亮度是1。0,當它經過雲層照射到取樣點的時候,取樣點所接受到的亮度是多少呢?而最終能到達相機的又有多少呢?要回答這個問題,我們首先要算出陽光到達取樣點,以及取樣點到達相機的透光度Transmittance。

根據這個比爾·朗伯定律,透光度是由光線的光學深度Optica Depth所計算的,而這個光學深度就是從這個路徑上雲層的密度的積所得到的,單次散射其實就是一般透過太陽光陰影和三維函式相乘出來的一個結果,我們是用了四個樣本來評估太陽方向的光學深度,所計算出來的透光度就等於雲層的自陰影。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

就像上圖所示,我們是用了四個樣本,就分別以一個2次方的距離來分佈。主要是優化了比較接近的一個遮擋效果。作為一個LOD策略在陰影取樣雲層的時候,我們也會忽略了細節噪聲。剛才提到的相位函式,我們是用了一個經典的方法,就是把兩個相反方向的HG函式混合作為最終的相函式這裡列出了我們的一些預設引數,其中的VoL就是太陽跟視線的方向的一個點積。

為了節省效能,環境光方面我們採用了一個比較簡單的處理方法。天空的環境光是參考UE4中的方法,根據取樣點的高度來計算相關的顏色,就是說雲越高,天空環境光的亮度就會越亮。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

上圖就是天空環境光效果的對比。我們發現如果沒有環境光,雲大部分在陰影的時候都會很難區別它的形狀。而在開啟了環境光之後,雲在陰影部分的造型也清晰很多了。我們也加了一個用來模擬地面反射光線的地面環境光,主要是用來模擬地面反彈到雲層的光線。

這也是以同樣的方法來計算,但就是把高度的引數反轉,就是說越低的雲層就可以接收到越多的地面環境光。地面環境光的顏色是透過是透過將地面視為一個純Lambertian的表面計算出光源的反彈所得到的。舉個例子SkyLight的底部顏色就是作為地面環境光很好的一個數據。

這裡我們可以看到沒有地面環境光的時候,雲的底部是比較暗的,而開啟地面環境光之後雲層的底部會變得更亮,更接近我們在日常生活中看到的一個結果。接著是多次散射模擬,也是計算出雲正確光照非常重要的一環。因為雲主要是從水蒸氣和小的冰塊所組成的,當陽光進入到比較薄的雲層的時候會經歷過很多遍的散射才到達我們的眼睛裡面。從這一張照片裡面我們可以觀察到一個很有趣的現象。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

雲深處會比外面更亮。這是因為深處的雲會經歷過更多遍的散射。我們參考了彼思動畫和寒霜引擎中用來計算多次散射的一個近似值的方法。我嘗試簡單說一下它的思路。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

假設每一次散射的時候,陽光和陰影都會有一定程度的衰減,而相位函式也會越來越接近一個均向性。在這個公式中,我們定義了ABC三個0到1之間的引數來控制這個衰減的關係。注意一下為了保持能量守恆呢,A是需要小於B的,因此在光線行進的時候,我們就利用這個方法對每一個取樣點計算出三遍的多次散射的一個亮度,在寒霜和虛幻引擎的實現裡面,基於效能的關係,一般只會算3遍的散射。

針對這一點我們做了一個小小的改進。透過固定的ABC三個引數,我們可以預先算出一張查詢表用來算出任何次數的散射效果,這個查詢表是在歸一化的亮度所計算出來的。我們是透過取樣點的光學深度和太陽與視線的點積來進行一個索引。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

這是沒有多重散射的結果,因為光線沒法到達雲層的深度,因為光線沒辦法到達雲層的深處,雲層看起來會有點不太真實。有了多重散射之後,雲層的整體亮度可以變得更為準確,效果也更為逼真。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

除了多次散射之外,我們剛才也提到雲的邊緣部分會因為比較少的散射而顯得會比較暗。我們也參考了地平線在2017年提出的方案,又添加了暗邊的效果。

思路就是透過取樣更小細節的雲密度LOD從而評估出取樣點出現散射的機率。雖然這個不是物理正確的,但它給出了歸一化的輸出結果,同時在不同的光線行進的步數之下也有同樣的結果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

這是沒有加入暗邊效果的一個截圖,可以注意圓圈中的部分。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

當我們加入了這個暗邊效果之後,會看到整個雲層會呈現出更多的細節。

在這裡我稍微總結一下是如何把剛才的理論總彙在一起。

我們從這一段處理單個射線的shader程式碼開始吧。FinalScattering 是我們最終看到的顏色,初始為零。TransmittanceCam就是代表攝像機和取樣點之間的透射率,初始為一。當我們穿過雲層的時候,散射的級會變得越來越大,而透射率會慢慢變小。

在這個For迴圈裡面每一個取樣點在這個For迴圈中,我們會計算每個取樣點的雲層的密度和散射的能量,而散射的能量就是剛才提到的在For迴圈裡面。在這個For迴圈中,我們會計算每個取樣點的雲的密度以及散射的能量。而散射的能量則是剛才提到的多次散射,還有再加上這個暗邊效果的一個得出的一個結果,再乘以目前的透射率就可以得到相機實際上接收到的散射能量,再以雲層的密度去更新透射率。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

注意一下,散射量和透射率更新的順序是不可以交換的,不然的話算出來的結果是會不對的。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

從剛才體積雲的建模以及著色的分享中我們可以知道,要算演出逼真的體積雲效果是有一個非常巨大的計算量。所以接下來我會分享是如何把效能的開消最佳化到手機上可以接受的程度。根據我們的經驗,光線行進要進行64個取樣才可以得到一個比較好的效果。但是在手機上,暴力地跑這樣一個光線行進大概需要10個毫秒左右吧。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

在《荒野大鏢客》中,提出一個螢幕空間分幀的方法,雖然可以有效地改善效能,但是當相機快速旋轉,或者是幀率不穩的時候,天空很容易出現像這個圖中裡面一格一格的情況。而相機快速旋轉其實是在第一人稱遊戲裡經常出現的情況,因此我們最終想到了使用半八面體投影來投影整個天空並且將光線行進的結果快取在一張512乘512的2D紋理裡面,再透過分幀更新。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

這樣做的優點是什麼呢?首先快取是獨立於檢視的位置方向以及相機的FOV。我們可以把快取應用在任何的動態反射中重複使用, 這樣不但解決了相機快速旋轉的問題,在渲染天空在水中的倒影的時候,我們也不需要重新再做一遍的光線行進。

另一個好處是,雲在半八面體空間中的運動是相對比較慢的,可以好好地與重投影技術結合起來。我們用了以下幾個技術來進行那個更新的最佳化。第一個是棋盤渲染技術,這個方法幫我們節省了50%的光線行進的計算量。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

首先我們有一個名為R的全尺寸的一個rt,它就包含了一個resolve之後的結果。我們有一張名為R的全尺寸的Render Target,它包含了最終的快取結果。針對手機硬體的特性,我們就把R當中的畫素分為兩張只有一半大小的Render Target稱為E和O。它們儲存的R每一行偶數或者是奇數畫素,因此我們最終會有三張Render Target,而光線行進只會在E或者是O中裡面計算。

每一幀我們只會更新其中一張,然後就把算好的結果resolve到R裡面用來繪製天空。把畫素拆分到兩張Render target的好處就是我們可以100%保證GPU不會有多餘的執行緒在等待,或者是寫入頻寬的佔用。

我們是用這一段程式碼把Seat裡面的SvPosition轉成光線行進所對應的方向。至於我們是怎麼把結果resolve到R裡面,我們只進行了一個簡單的複製操作,並且把無關的畫素Discard來節省了一半的貼圖讀取的頻寬。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們是利用這段程式碼來判斷resolve當前的畫素是否需要被discard。原理就是把當前的SvPosition先轉成checker的座標,然後再利用奇數或者偶數的ID轉回SvPosition。假如轉換前後的SvPosition對不上的話,就代表這個畫素需要給discard掉。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

之後我們會將Render Target再切分成4到16片來進行一個更大力度的分幀更新,這個想法也很簡單。我們透過裁減矩形來限制算目標的哪個部分需要給更新。正如右邊截圖中看到綠色的矩形。我展示一下這個具體上是如何工作。比如說我們希望把Render Target分成4幀去更新,所以呢從一開始,每幀僅計算一行的畫素,到這裡E的更新就完成了,所以呢我們就把它馬上Resolve到R裡面,因此就讓它的內容可以顯示到螢幕上。

然後我們繼續在O上進行更新,一旦O的更新也完成了,我們也會把它resolve到R裡面。然後我們就從E重新開始一個迴圈。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

然而這個最佳化也有一定的代價,就是它會導致像定格動畫一樣的情況。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

為了解決這個問題,當繪製天空的時候,我們可以插值用來取樣快取的一個方向。比如說雲層是比如說雲是分四幀從A點移動到B點。假設我們距離上一次resolve已經過了一幀,同時再看到的是天空的B點,由於雲的移動量是已知的因此我們可以往後回溯出並且找到C點。再利用相機到C點的方向,我們快取來取樣就OK了,我們看看插值後的效果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們剛才提到在光線行進單個方向的時候至少需要用到64步才可以有一個比較好的效果。因此我們也借鑑了基於TAA的技術,來進一步最佳化整體的效能,在每一幀裡面我們會對每條光線起的開始點套用了一個全域性的偏移,並且將結果和歷史幀的結果做一個吻合。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

比如說在第一幀的時候我們會計算藍色的取樣點,然後在下一幀就計算橙色的,可以看到所有的取樣點都有一個偏移,最後是紅色的。這個偏移是基於Halton序列來生成。我們其實是隨著時間的推移在射線上計算很多很多的樣本取樣,結果一般會在幾個幀裡面收斂到。在我們的遊戲中,加上這個最佳化之後,每幀只需要算16步即可以達到很不錯的效果了。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

同樣的世界上沒有免費的午餐,這個最佳化會帶來鬼影的問題。所以呢我們再一次使用了重投影來緩解這個情況。在光線行進的過程中,我們會根據雲的折射率,來評估出每一條射線的中心點,然後我們會把中心點減去雲的移動量得到P點,再利用相機望向到P點的向量,從快取來取樣歷史幀的數值來跟目前新的數值進行混合。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

這是應用了重投影之後的結果,可以看到鬼影的問題已經大大減少了。除了如何降低這個光線行進的計算量,我們還有一個最佳化。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

在一般的情況下我們會用半精度的浮點數來儲存散射的結果。假設說一張512乘512的Render Target便會佔用大概是2M的記憶體及寫入的頻寬,在主流的手機上這個是可以接受的。但是半精度的Render Target,在一些比較老的裝置上不太友好,所以呢我們也必須要考慮使用8位RGBA的格式,然後我們也會面臨以下的挑戰。首先我們所有的單位是基於物理的,所有輸入和輸出都是處於一個高動態範圍裡面。

其次是在太陽的方向,有一個非常非常強的一個相位的峰值,這樣讓這個情況變得更糟糕。同時我們也需要考慮剛才提到時間超取樣的一個數值的穩定性。所以呢我們使用了這個歸一化的技巧來得到這個數值壓縮的結果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們先看看這個表示式,首先我們將散射除以一個相位項,這樣的話就可以降低整體的峰值。要注意的是,我們不是直接除每一個方向的原始的相函式,而是跟均向性的版本做一個吻合來避免過度壓縮在陰影部分的一些畫素。

之後我們會將散射除以一個預曝光的值,大概的的思路就是把陽光的亮度環境光等等的相關的數字相加在一起,保證散射的結果不會超出歸一化的範圍。最後我們做了一個伽馬2。2的編碼來提高數值的精度。這個就是我們歸一化之後的所儲存的結果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

這裡是在Iphone11上一部分畫質測出來的效能資料。作為與端遊方案的對比,我們還使用了同一個場景,在GTX 1070顯示卡上進行了測試。在沒有任何最佳化的情況下,光線行進在移動裝置上,需要大概10個毫秒來更新。在最高畫質我們會將快取分為8幀更新,在手機上就只需要0。6個毫秒,如果在桌面上6幀只需要0。09的毫秒。在中等畫質,我們會把分幀的數量增加一倍,在比較老的裝置上,我們會使用最低的畫質,我們會開啟剛剛提到的HDR壓縮並且將快取減少到只有256乘256的解析度。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

最後我再分享兩個跟體積雲有關的動態天氣效果。第一個是雲在地面上的投影,因為我們將整個體積雲的透光度儲存在快取裡面,所以呢我們可以透過一個簡單的計算就可以把結果投影到地上,做出雲裡的效果。首先我們是從著色的點朝太陽的方向發出一條射線,之後再計算出射線與雲層底部的交點,最後地球中心與交點的方向去取樣得出透光度,這個透光度就可以當成是雲的投影來使用。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們看看在引擎中的效果。雲的投影可以跟隨著太陽還有天氣的變化所影響,令場景更為逼真的光效效果。為了有更好的效能,我們會建議把這個相交點的計算以及取樣的方向放到頂點著色器去預先算好。

下一個效果是閃電為了製作出更為逼真的閃光效果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們參考了Youtube上一個打雷慢動作的影片。在現實生活中閃電有三個階段,Lightning Leader這是一條像蜘蛛網一樣的路徑,從雲端延伸到地面上。實際上肉眼是幾乎看不到這個現象的,因為它來得太快。但有了它,它的效果是截然不同的,所以我們確定要保留這一個(效果)。

當Lightning Leader到達地面的時候,就會產生一個閃電的通道,電流就會從裡面透過,把空氣加熱到一個非常非常高的溫度就出現閃電和雷聲,這個階段叫Return Stroke。在Return Stroke之後,又有若干次Re-Strike。Re-Strike會在同樣的通道里面去發生的,但一般都會比Return Stroke比較少,平均發生3到4遍,然後會產生一個,閃爍的一個效果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們是利用分形演算法來產生Lightning Leader的網格。首先從一條直線開始,我們把直線的中心垂直的方向偏移一點點,最後把直線分為兩截,在新生成的兩截重複再做同樣的中心偏移,直到每一節的線段夠短為止。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

線上段細分的過程裡面,我們需要隨機生成一些分支,這樣才可以得到剛才說像蜘蛛網一樣的效果。假設我們是剛剛生成橙色的線段,我們可以把橙色的中心與藍色的中心點相連在一起產生一個紅色的分支,我們再把分支隨機縮短和旋轉,之後在新的分支裡面再進行剛才提到的細分的一個操作。

然後我們會把線段轉回一個四邊形的網格,R的通道就用來標記目前的頂點是否屬於主幹,G通道就儲存了與閃電起點,G通道就儲存了與起點歸一化的距離就原來模擬閃電從雲層到達地面的一個生長的動畫。這是我們最終渲染出來的一個結果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們減慢Lightning Leader的速度就讓我們可以更清晰地在這裡展示,這是最終在遊戲中能看到的效果。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

可以看到場景和體積雲會被閃電所照亮。場景方面,我們只是簡單地增強了主光源的亮度,並且用相機和閃電之間的距離基於平方來進行一個衰減,當中的影子可能是不正確的,但因為它發生得太快了,所以很難被注意到。

雲的方面,我們在渲染天空盒的時候,會考慮到目前閃電的位置基於一個指數的衰減來調整上方的亮度。雲的位置是利用視線和雲層的相交點,因此結果也不一定是100%準確,但對於移動端來說已經是足夠了。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

這是我們參考過的一些文章。今天我給大家分享了《暗區突圍》裡的動態天氣渲染技術以及一些相關的天氣效果的實現方法。

玩手遊也能體驗風霜雪雨?天氣渲染技術帶你領略雲端魅力

我們並沒有止步於此,我們正在推進風格化的天空支援以及正在研究如何以一些新的技術來最佳化體積雲的效能和效果。整套方法都是從錯誤中學習和打磨出來所以我也非常感謝我組內每一位參與了天氣系統開發的小夥伴,也感謝《暗區突圍》專案組的耐心和支援。最後也要感謝TGDC大會的邀請,讓我再一次有機會公開我的工作成果。

謝謝!