先後立項三次,「逼瘋」郭煒煒的科幻機甲遊戲經歷了什麼?

2023-12-20     遊戲葡萄

原標題:先後立項三次,「逼瘋」郭煒煒的科幻機甲遊戲經歷了什麼?

西山居攻下的一座大山。

前不久,西山居在TGA上爆料了科幻機甲新作《解限機》(《Mecha BREAK》)

看過葡萄君文章的讀者可能知道,這款遊戲是西山居在2019年就掏出的「機甲大作」《Code B.R.E.A.K.》,前段時間郭煒煒跟葡萄君聊到這款遊戲時,還表示「目前已經是第三次重新立項了……我真的快瘋掉了。

巧的是,在TGA過去沒幾天西山居引擎平台技術總監黃錦壽參與了今年的Unity Open Day廣州站,並講述了這款遊戲的研發經歷和渲染相關的技術攻堅情況。

以下為現場分享原文:

大家好,我是黃錦壽,來給大家介紹一下我們項目《解限機》(《Mecha BREAK》)裡面的 Virtual Geometry(以下簡稱「VG」),分享一下我們在項目裡面利用這個技術做了哪些東西,以及實現了哪些效果。

我們的遊戲今年 12 月份在 TGA 亮相,《解限機》是一款以機甲為題材的多人對戰 TPS 客戶端遊戲。遊戲中有 3V3、6V6、大世界戰場的對戰玩法。其中大地圖是一個 256 平方公里的龐大地圖,可以容納幾十人一起對戰。

我們為什麼要給項目開發虛擬幾何體?因為項目的需求是大世界地圖,在實現龐大面積地圖的同時,場景複雜度又非常高,而且我們的模型細節也非常豐富,精度也非常高。在視頻中可以看到我們製作的戰鬥伺服器很複雜,特效非常多,子彈的彈道都是實時計算、碰撞也都是精準碰撞檢測。正因為模型精度高,所以製作需要多級的 LOD,美術資源製作工作量大,周期比較長。

用虛擬幾何體,我們就可以解決以上的幾個問題。用了這個技術以後,我們只需要製作高精度模型就好了,美術不需要再為製作 LOD 模型浪費工作量,因為 LOD 模型通過程序生成會比人力手工做更快、更好一點。因為我們的戰鬥非常複雜,GPU 的計算非常耗費,所以我們的想法是儘量把渲染相關的東西交給 GPU 來做,例如模型的裁剪。所以我們還開發一套 GPU 的渲染管線,把原本由 CPU 來做的裁剪、LOD 計算、排序等操作交給 GPU 來負責計算。

因為我們不用 MESH,而是模型的數據直接存在顯存里,所以可以減少一定內存的使用。而且這樣我們對於三角面的數量限制,就可以實現幾何級數的突破,不再受到三角面數量的影響成為渲染效率的瓶頸。虛擬幾何技術就有點像虛擬貼圖一樣,把 MESH 切分成很多 Cluster 等不同的部位,根據不同的距離來實時流式加載,只有需要級別的 Cluster 才會被載入到系統中去。

上面是一個支持骨骼模型動畫,傳統的 GPU 其實不同的 MESH 是沒辦法做到合批渲染的,我們用了虛擬幾何體,也對骨骼動畫做了特殊的支持。並且我們這一套渲染管線也支持 HDRP、URP,還有多平台的 PC、安卓、iOS,主機平台的 XBOX、PS5 在上面都是可以正常運行的。

這是我們遊戲機甲裡面使用到的 VG 演示效果,機甲支持塗裝系統,每個玩家可以有獨立的材質,可以高自由度定製每台機甲的效果,這是我們虛擬幾何體三角面片的模式。可以比較直觀的看出,在機甲模型距離鏡頭遠近的時候,會有 LOD 的切換,但是在實際的遊戲來看是看不太出來有 LOD 明顯跳變的。

遊戲的植被系統是為項目專門定製化開發,讓項目的植被項目系統支持 VG,我們遊戲里所有的樹和草都是通過 VG 渲染,並且還支持交互。

這是剛才說的植被系統在遠處是使用了 IMPOSTER,近處可以看到是實體模型的樹,遠處是變成一個 IMPOSTER,這些植被也支持可破壞、交互,這些碰撞檢測都是用 GPU 來支持的。

遊戲里子彈打的每一棵樹都是交給 GPU 來實時做碰撞檢測,現在展示的是單人在打,其實我們遊戲裡面,是有多名玩家可以同時打,有很多數量的子彈。子彈的計算量是非常高的,所以我們把它利用 GPU 的並行計算來做碰撞檢測,提高它的檢測效率。可以支持大量的子彈同時並發做高效精準的碰撞檢測。

這是我們遊戲裡面的一些機甲,每台機甲都是不一樣的,不管是 MESH 還是材質、表現,種類是完全不一樣的,但是在這個場景下,可以看到這些角色全都是一次繪製完的。不像傳統的 Instance 是一個機甲類型繪製一次,現在是不同的類型都全部一次畫完,而且拉遠拉近會有自動的 LOD 切換。

我簡單介紹一下這個是怎麼做的,以及大概的原理。以前是用傳統的 GPU SKINNING,要把動作烘培到貼圖上,但是這樣的話,動作融合、IK、RIG動作融合,都沒有辦法使用。因為我們的遊戲對動作要求比較高,所以必須要使用這些功能。為了解決這問題,我們決定在這些動作系統計算完骨骼動畫後,再把數據上傳到 GPU 顯存中,在 GPU 裡面做蒙皮動畫計算。最後在這一個 Drawcall 裡面通過 VG 渲染,單個 DrawCall 全部繪製上去。就算同一個機甲,玩家可以有不同的塗裝,有不同的紋理,不同的顏色,這些都是可以支持的。

這個就是我們剛才放的 40-50 個不同的機甲,單個 Drawcall 就可以一次畫完了,要滿足這個條件,這些機甲必須要用同一個 Shader,材質可以不一樣,但是這個 Shader 必須要一樣。骨骼數據、材質參數,用 Buffer 傳到 GPU 進去,其實跟 GPU Skinning 一樣也是在 VS 裡面做蒙皮計算。骨骼動畫的運算,和 Unity 原生的動畫更新流程差不多,也是多線程裡面計算完了之後,上傳到 GPU 裡面。

這是我們之前做的一個測試,大概放了 200 個模型,如果直接放這樣的模型,不同 MESH 沒有做合批渲染的時候,大概只有 40 幀左右;轉化為 VG 之後,單次 DrawCallp 完成所有 Mesh 的繪製可以有 1 倍的性能提升。右邊的圖,其實是單 Drawcall 就把 200 個機甲全部繪製完了。

這裡是可以看一下演示的,這個場景的面數非常高,可以看到這裡的每一片葉子都是用的幾十個面做的建模,我只是為了演示虛擬幾何體的渲染性能,所以使用一個精度非常高(超出遊戲資源規範)的樹模型放到場景里。

這個場景是一個非常複雜的場景,上面植被加上建築已經超過上萬個,樹是超高精度的、超過 375 萬面的模型。這個樹是自動化生成的,可能放了幾百上千的植被的樹,單場景裡面應該是超過 10 億面,如果算這個統計,估計可以上幾十億的三角面片都有的。但是由於有虛擬幾何體的技術,我們就可以在面數上稍微放鬆一點,美術可以有更大的發揮空間。

這個是我們做 VG 的調試模式,因為我們左邊第一個的是 Triangle 模式,是每個模型的三角面片的情況;中間是 cluster(等一下可能會講到 cluster 的概念,它會把模型每一個切分成多個部分);第三個是 material id 可以看用了多少 Drawcall,不同的 Material 是不同的顏色。下面比較特別的是 Miplevel,當前顯示的 LOD 級別,全紅是 D0 最高級別的;下面中間的是 Max Miplevel,代表這個模型生成了多少級 LOD,取決於模型精度。我們在生成 VG 數據的時候,就已經生成完了,這就相當於你的面數非常高,可能生成的級別比較多一點,15、16 級都有可能;最後一個是測距模式,可以滑鼠點在中間,看到當前這個物件距離鏡頭的距離是多少,我們是用來做調試,這個物件在什麼距離會顯示什麼級別才合適,輔助我們做調試用的。

我演示一下這個場景 VG 的效果,現在畫面裡面看到的模型,都是虛擬幾何體(Virtual Geometry)

我們簡單說一下這個虛擬幾何體的渲染管線的實現原理。主要分兩部分:第一部分是模型的切分和 LOD 的生成,另外一部分是搭建完整的 GPU 場景(即 GPU 渲染管線),要包括數據上傳、裁剪剔除、LOD 計算,排序、渲染,其實和 CPU 渲染管線是一樣的,就是全部都交由 GPU 來做完。不過它比傳統 CPU 管線的裁剪部分多了一個步驟,除了 Instance 級別裁剪,還有 Cluster 級別的裁剪,在裁剪過程中要計算每個可見的 Cluster 當前的 LOD 值是多少,以此來決定該 Cluster 在螢幕中顯示的時候,需要顯示哪個級別的 Cluster,才加載那個級別的 Cluster 數據,再上傳到 GPU 裡面去。然後我們要對所有可見的 Cluster 按材質進行排序,再根據材質來進行渲染。

這裡說一下剛才說的 Cluster,我們說的 Cluster 其實就是把一個整個 MESH 切分成了 N*N 個小模型,每個小模型就是一個 Cluster。切分完之後再分組,對每一組進行鎖邊,來做減面,減面後再切分 Cluster,再分組減面,循環以上步驟,一直生成完最低級別的 LOD 數據。鎖邊的作用是為了保證在 LOD 切換的時候,不會出現兩個級別之間的接縫連接不上,出現對應不上的情況,能夠保證它的邊界是無縫銜接出來的。這樣才能做到一個模型裡面,可以同時顯示多個級別的 Cluster LOD,比如一個模型裡面,我身體可以是 LOD 0,頭可以是 LOD 2。取決於你看到是哪個位置。

這幅圖會直觀一點,切分 Cluster 之後會有不同顏色。右邊不同顏色的就是一個大塊的,就相當於把包含裡面的 Cluster 分在一組,分好組之後就把這個組裡面的 Cluster 減面,可以看到右面的模型面數是非常高的,進行減面後,就只剩原來的一半面數,然後組內重新切分 Cluster,切分後新的 Cluster 再重新分組,如此循環,直到生成最低精度的模型。

總結就是根據第一步生成的 Cluster,進行分組減面生成下一級 LOD 的 Cluster,每級面數減少一半。原則是切出來的 Cluster 保持的面積儘可能接近。

這是一個 Cluster 切分的演示,這就是一個整模通過我們的算法對它做 Cluster 的切分,每一個不同的色塊都切分成子的 MESH,就是我們說的 Cluster,裡面有包圍盒數據,這些數據就是為我們 GPU 管線做裁剪使用的。

這裡是演示了普通的 MESH 和 VG 的 MESH 的區別,拉遠的時候模型會消失,是因為它超過了我們鏡頭裁剪距離,可以不渲染了,所以 VG 模型就直接不渲染了。我們支持遮蔽裁剪,被物件擋住也是不會渲染的,還有視錐裁剪,模型的一部分離開了鏡頭之外,那一部分就不渲染了。如果是傳統的 LOD,或者是傳統的裁剪,這個模型是整模,看到一個手指都會整個模型渲染。我們使用 VG 之後,就可以做到「看啥渲啥」,只渲染我看到的頭部或者手的一部分,看不到的部位可以不渲染,這大大節省了渲染的三角面數,提高渲染性能。

這個就是我們在用普通模型,以剛才的模型為例,大概是 25 萬面,原始內存是 14.5M,本地磁碟是 10M 左右。我們轉成 VG 之後,我們存成自己單獨的格式,文件大小是 6.1M,而且是包含 14 級 LOD,這個模型可以一直 LOD 到第 14 級,即便這樣也只有 6M,壓縮率是原來大概的 65%。如果加上 LOD 數據的 MESH 來比較,壓縮率會超過 50%,可能會更高一點。因為原來的只有 LOD0 並沒有 LOD1、2、3。而 VG 的模型是包含了 LOD14 級,而且 VG 不占用內存,數據只存在顯存當中,對於內存的壓力來說,可以大大釋放了。

這個是我們 GPU 場景大概的渲染流程。

思路是這樣的,上面的 GPUScene 線程就是有點類似 Unity 的渲染線程,下面的主線程是發起 GPU 相關的指令,如添加、刪除 VG 對象、位置更新、裁剪回讀、數據上傳等操作指令 ,這些指令發起後,實際是交給 GPUScene 線程做處理,所有具體的操作,數據處理,上傳數據,跟 GPU 相關的操作都在此線程中完成。最下面的 GPU 才是我們真正的 GPU 單元的處理任務,俗稱顯卡的計算。GPU 需要處理數據解壓、裁剪、排序、渲染,這裡相當於一條完整的渲染管線流程都是在 GPU 裡面完成。CPU 只需要把模型的數據上傳到 GPU 裡面去,其他的事情都交給了 GPU。這裡使用 GPUScene 線程來做數據處理,目的是部分渲染相關的處理需要等 GPU 計算結果,放到子線程里做,可以跟主線程中的一些邏輯計算並行處理。充分利用 GPU 和 CPU 時間。減少相互等待的而造成的算力浪費。

這是我們的顯存的使用量,從圖中可以算出整個 VG 的系統所需的顯存大小,圖中你看到最大的 Buffer 是 134M,我們稱它為 Page Buffer,它就是整個 VG 系統模型數據的總 Buffer,它要把整個系統,場景裡面所看到的模型的 MESH 數據都是放在裡面。除了 Page Buffer 還有一些裁剪的列表的 Buffer,各種不同的 Buffer 的數據加起來,不超過 300M。而且這樣的話,我們是不需要再加載以前的 MESH 數據,即 CPU 里我們不需要存儲任何模型數據。

這是我們的一個場景,因為我們的資源量非常大,以前還沒有使用 VG 的時候,MESH 數據占用內存 1100M,改成 VG 之後,因為 MESH 已經不需要了,都把實時的數據壓縮到 GPU 的 Page Buffer 里。我們模型數量很多,並且都很大,加載單個 MESH 10M 內存就被占用了。現在只有鏡頭渲染到需要顯示級別的數據,才能上傳到顯存裡面,而且顯存 Buffer 是一個共享池,是可以循環使用的。從數據上來看,比之前節約了 900M 的內存。

這是一個場景的性能的對比,我們剛才視頻里演示的,以前普通模型的場景在 3080 可以跑到 110 多幀,960 顯卡可以跑 51 幀,我們換成 VG(即場景中所有模型都不使用 MESH,而是虛擬幾何體),FPS的提升分別是 43% 和 31%。因為所有的裁剪、LOD 計算都從 CPU 放到了 GPU,所以 GPU 負載都是有上漲的,從 70% 上升到 97%。但是比較可觀的是 CPU 的耗時,都有明顯的降低,3060 的機器上降低了 2.66 毫秒,在 2060 的機器上甚至降了 5.49 毫秒,960 的機器也降低了 4.57 毫秒。對 CPU 有很大的釋放,普遍有 20% - 30% 的 CPU 性能提升。我們就可以把 CPU 的計算能力用於遊戲邏輯等其他地方上,不再由渲染占用這一部分的 CPU 性能。

這裡是我們的手機版本的視頻,虛擬幾何體已經把它支持到 iOS 和安卓上,其實 XBOX 和 PS5 都可以使用,但這次沒有錄製這個視頻。用到的數據和 PC 上一樣的,一套流程處理的數據就可以在 PC 版和手機版上使用,模型只做一套資源,也不需要專門為手機做優化製作不同精度的模型資源,我們只要調一下參數,讓它顯示的精度級別不一樣。

今天我要介紹的就是這麼多了,這裡是我們最開始一個想法的視頻演示,是一個 VGBOX 的模型,無限細分,每一個級別就是遞減一半的面。而且是支持鏡頭裁剪的,還有遮蔽裁剪,實現鏡頭看到的才會渲染出來,鏡頭看不到的就不渲染,根據不同距離來決定顯示精度,一開始是抱著這樣的想法來做的。這個 Demo 主要是為了快速驗證 Virtual Geometry 這樣的 GPU Driven 渲染管線能不能在 Unity 里實現。

今天的分享就到這裡,謝謝大家!

推薦閱讀

騰訊遠征| 國產遊戲信任危機 | 站著掙錢

元夢之星 | 二次元騙局 | 黑神話:悟空

對話黃一孟 | 行業價格戰 | 對話郭煒煒

遊戲行業書籍推薦:葡萄書房

(星標可第一時間收到推送和完整封面)

文章來源: https://twgreatdaily.com/df498431c030ca7f75b35f3abccd6535.html