GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

王俊宏發表於2024-03-27
導語:在今年的遊戲開發者大會(GDC 2024)上,來自騰訊遊戲的專家持續帶來前沿分享,圍繞AI、渲染、跨端遊戲開發、動畫等遊戲技術應用及遊戲製作,引發同業關注。本文為“暗區突圍手遊:在移動端打造次世代射擊遊戲”分享的圖文版乾貨內容。

分享嘉賓:王俊宏 騰訊互娛魔方暗區突圍手遊專案圖形程式負責人

大家好,感謝大家參加本次會議。我叫王俊宏,是魔方工作室暗區突圍渲染組的主程。我在騰訊工作了12年,一直從事PC和移動遊戲開發。

我將從介紹《暗區突圍》手遊和移動光線追蹤的背景開始,然後介紹《暗區突圍》中的光線追蹤,包括光線追蹤場景管理、反射、軟陰影、環境遮擋和最佳化,最後是一些結論。

一、背景介紹

《暗區突圍》是一款面向Android和iOS裝置的下一代沉浸式第一人稱戰術射擊手遊。該遊戲於2022年7月正式釋出。製作人孫一鳴去年在GDC上介紹了遊戲玩法。遊戲使用的是Unreal Engine 4.26引擎。也是一款開放世界遊戲。例如,最新的關卡礦區, 大小約為4公里乘以4公里。場景中有超過10萬個網格例項和3000多個流式載入關卡。因此,場景管理將是一個挑戰。

我們遊戲中的一些重要渲染特性包括:首先,渲染管線採用的是前向渲染管線。其次,我們使用了基於物理的渲染,包括基於物理的材質、光照、相機和著色。例如,這個影片展示了遊戲中的自動曝光功能。

第三個重要特性是動態天氣系統,我的同事陳家銘在2022年的GDC上介紹過。在這個影片中,陽光、天空光和雲都會隨著時間變化。

最後,我們遊戲中的全域性光照基於預計算輻照度傳輸。因此,在這個影片中,當天氣系統變化時,間接光也會有所不同。

接下來,我將介紹移動光線追蹤的情況。現在最新的智慧手機已經支援硬體加速的Ray Query(也稱為Inline Ray Tracing)。Ray Query可以在任何著色器階段使用,例如頂點著色器、畫素著色器或計算著色器。然而,在移動裝置上除錯光線追蹤仍然具有挑戰性,因為大多數截幀工具和GPU效能分析工具都不支援移動端的Vulkan Ray Query。

在我們整合光線追蹤之前,有一些準備工作需要完成。首先,我們啟用了Android的Vulkan API。然後,更新了Shader交叉編譯工具到最新的Shader Conductor,以支援光線查詢的著色器指令。最後,我們擴充套件了UE4的Vulkan和Metal RHI。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

二、《暗區突圍》手遊中的光線追蹤

現在,我來介紹《暗區突圍》手遊中的光線追蹤。在中國,帶有光線追蹤功能的Android版本已於2023年釋出。而iOS版本的光線追蹤功能正在開發中。正如影片所示,我們已經整合了光線追蹤的反射、軟陰影和環境光遮蔽。接下來我將展示在智慧手機上拍攝的截圖。

這是在智慧手機上的截圖,如果禁用光線查詢,大理石地板上不會有反射效果。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

但是,如果啟用了光線查詢,我們將獲得令人印象深刻的光澤反射效果。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

這是另一張在室外拍攝的截圖,輪胎、箱子和地板上沒有環境遮擋效果。

當啟用光線追蹤的環境遮擋時,間接光效果更加逼真。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

當禁用光線查詢的軟陰影時,我們使用CSM陰影和硬體PCF。但是陰影貼圖的解析度不足以為金屬柵欄或其他一些細小物體渲染清晰的陰影。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

啟用光線追蹤軟陰影后,我們可以獲得幾乎完美的軟陰影效果。所有這些可以為玩家創造更加真實和具有沉浸感的體驗。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

正如我之前提到的,對於我們來說,管理光線追蹤場景是一個挑戰。稍後我將介紹我們所面臨的挑戰以及應用的最佳化方法。

以下是三個主要挑戰:第一個挑戰是底層加速結構(BLAS)的記憶體佔用。第二個挑戰是在移動GPU上構建BLAS的計算成本較高。第三個挑戰是在具有太多例項的頂層加速結構(TLAS)中Trace非常耗時。這是在PC上使用NVIDIA Nsight Graphics捕獲的截圖,顯示了我們遊戲中部分TLAS例項的情況。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

首先,我將介紹目前場景管理的基本情況。我們的關卡是由關卡流式載入系統管理的。當載入包時,會加模型的底級LOD。更高階的模型LOD則由模型流式載入系統載入。而一些帶有遮罩、世界座標偏移或透明材質的模型不會建立BLAS。那麼,我們能否在載入模型LOD時建立BLAS呢?答案是否定的。因為當載入地圖時,會建立超過4700個BLAS,視訊記憶體佔用高達4.4GB,然後遊戲會因為記憶體不足而崩潰。

我們使用了一個簡單的演算法來管理BLAS。在這個圖中,P是相機的位置,r1是BLAS建立半徑,r2是BLAS銷燬半徑,d是相機到物體邊界球的距離。如果d小於r1,將標記為待建立;如果d大於r1且小於r2,將標記為待保留。然後,我會立即處理待建立請求。但對於沒有待建立或保留標記的BLAS,將會被延遲銷燬。這樣可以避免物體靠近邊緣時頻繁建立和銷燬。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

這裡所有引數都是可調的。經過最佳化,BLAS的數量從4700個減少到約700個。影片記憶體從4.4GB減少到了1.1GB。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

對於TLAS,我們每幀更新一次,並在構建時啟用Fast Trace標記。我們還使用距離剔除和投影角度剔除來最佳化例項數量。應用這些最佳化後,圖中TLAS例項數量降為600個左右。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

這是在名為Vivo X90的智慧手機上的效能資料。構建BLAS的成本小於0.5毫秒。構建TLAS的成本約為1毫秒。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

接下來,我將介紹光線追蹤的反射,重點介紹渲染管線部分。

使用Ray Query實現反射面臨幾個挑戰。第一個挑戰是如何對反射畫素進行著色。在Vulkan Ray Query中,沒有RTPSO。而且我們的遊戲中沒有Bindless Texture。但是場景中有成千上萬種不同的材質。不可能使用一個通用著色器來對其進行著色;第二個挑戰是當前的渲染流程是正向渲染,我們需要為反射建立一個混合渲染管線;第三個挑戰是效能。例如,耗電和幀率。

這是《暗區突圍》手遊的Ray Query反射渲染管線。第一個渲染Pass是Base Pass,它會獲取所需的畫素資訊。第二個Pass是Query Scene Pass,我們發射光線以獲取螢幕空間中每個畫素的網格和三角形資訊。第三個Pass是可見性解析Pass,該Pass將為每個畫素計算反射顏色。接下來的兩次渲染使用聯合雙邊濾波來獲取光澤反射紋理。最後,將光澤反射紋理與場景顏色混合。稍後我將介紹關鍵步驟。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

以下是一些準備工作。在資源烘焙過程中會生成用於渲染反射顏色的著色器。在執行時,我們將收集用於對反射著色的繪製命令,並在每幀重新分配網格例項ID和命中組ID。

然後,我將介紹渲染流程中的關鍵渲染步驟。在Base Pass中,我們將渲染一個額外的Render Target。它儲存了法線、粗糙度和一個標誌位。我們稱之為Thin G Buffer。中間的影像是Thin G Buffer。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

下一個是Query Scene Pass。由於光線查詢中沒有光線追蹤管線狀態物件(RTPSO),所以我們使用Query Scene Pass和Visibility Resolve Pass代替。在Query Scene Pass中,我們重構世界位置和反射光線方向。然後發射一條光線,如果擊中任何例項,則儲存例項ID、三角形ID和擊中點的重心座標。左側的影像儲存了打包的三角形ID和重心座標。右側的影像儲存了模型繪製ID。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

對於Visibility Resolve Pass,我們提交可見性解析的Draw Call命令,並且使用Uniform Buffer提交繪製ID。每個Draw Call都是一個全屏四邊形。對於GPU而言,如果繪製ID不匹配,畫素將被丟棄。我們使用Manual Vertex Fetch和重心插值來計算畫素著色器中的PBR引數。然後發射一條陰影光線以獲取陰影值。最後計算反射顏色並寫入反射Render Target。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

這種演算法的優點是硬體相容性好,易於整合。但缺點是Draw Call以及Overdraw太高。因此,我們使用GPU遮擋查詢來刪除不可見的網格繪製命令,並使用深度測試來消除過度繪製。這張圖展示的是深度緩衝區,它儲存了網格繪製ID。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

最佳化之後,可見性解析繪製呼叫從600多個減少到約110個。並且完全消除了Overdraw。這張圖片展示了可見性解析的結果。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

之後的模糊處理Pass使用了聯合雙邊濾波器。輸入是Thin G Buffer、反射紋理和深度紋理。我們使用一個核偏移來根據粗糙度調整核大小。右側的紋理是光澤反射紋理。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

第二次模糊處理與第一次幾乎相同,但使用了更大的卷積核偏移。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

這是混合的結果。可以看到邊緣被保留了下來。對於光滑的地板,反射很清晰,而對於粗糙的牆壁,反射較模糊。對於完全粗糙的材質,在這裡不會發射任何光線。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

因此,最終我們獲得了良好的硬體相容性和高效能。對於Dimensity 9200,我們的幀率超過了60幀。這裡也有一些缺點。例如,處理透明或遮罩材質比較困難。

下面我將介紹光線追蹤的軟陰影和環境光遮蔽。

軟陰影和環境光遮蔽都需要發射大量的射線。這是使用1條陰影射線和1條環境光遮蔽射線的結果,影像充滿了噪聲。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

這是軟陰影和環境光遮蔽的渲染管線。我們使用完整的Pre Pass來獲取幾何法線和深度。然後Query Scene Pass發射光線,它將輸出帶噪聲的陰影和環境光遮蔽結果。接下來的渲染步驟是空間-時域降噪。最後,Base Pass將取樣去噪後的陰影和環境光遮蔽結果。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

對於Query Scene Pass,陰影和環境光遮擋效果會各發射一條射線。三角形背面不發射陰影射線。對於這個Render Target,R通道是陰影,G通道是環境光遮蔽。兩者都充滿噪點。為了提高效能,還可以使用較低的渲染解析度。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

左側是沒有降噪的影像,右側是經過時域降噪後的影像。這裡大部分噪聲都被去除了。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

這裡還應用了A-Trous濾波器進行去噪。經過兩次處理後,我們得到了右邊的結果。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

左側影像展示的是陰影,可以看到邊緣非常柔和。右側環境光遮蔽的質量也非常高。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

下面是遊戲裡最終的結果。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

對於Dimensity 9200系列晶片,我們實現了超過70的渲染幀率。

這裡也有一些缺點。例如,具有遮罩的材質需要使用其他陰影演算法。對於透明表面,陰影和環境光遮蔽會得到錯誤的結果。實際上,這裡的玻璃陰影是不正確的。而且過多的渲染Pass和紋理取樣會導致較高的功耗。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

我們還應用了其他一些最佳化。例如幀預測,我的同事齊越也在GDC會議介紹了它(在移動端實現144幀渲染:《暗區突圍》手遊中的幀預測)。

結果

最後,我將會展示一些結果。這是Ray Query的詳細效能資料。它可以平穩地執行在60幀每秒。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

平均功耗約為3000 mw。

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現

最後一部分是致謝。我們的專案成員包括鍾建斌、高鍇庚、齊越和崔世文。上述所有工作都離不開整個團隊的共同努力。還要感謝我們的合作伙伴MediaTek和Vivo。

這裡還有一些參考資料。最後感謝大家今天的到來!

GDC | 下一代的移動端圖形:《暗區突圍》手遊中的光線追蹤實現


來源:騰訊遊戲學堂

相關文章