GDC -《幽靈行動:荒野》地形技術和工具

GDC -《幽靈行動:荒野》地形技術和工具

來自專欄 GT的虛幻引擎筆記及技術文檔4 人贊了文章

文檔翻譯自GDC 2017的技術演講文檔:《Ghost Recon Wildlands Terrain Technology and tools》;網上也有類似的譯文,但沒有看見完整翻譯的;本人在學習這篇文檔的時候順便完整翻譯一遍,自己的收穫也頗多;

文檔其中穿插了若干視頻演示,此文中以鏈接的形式給出;一些技術術語保留了原文以便於理解;

以下為原文檔的翻譯:

主講人為育碧的Guillaume Werlé和Benoit Martinez;

Guillaume Werlé是負責《幽靈行動:荒野》(以下簡稱《荒野》)地形系統技術相關的圖形程序員,同時也是Demoscene社區的活躍成員;

Benoit Martinez是項目主美和技術美術總監,負責管理關卡美術和Houdini內容團隊;早在2011年就加入了育碧的《幽靈行動:未來戰士》項目,並且是《荒野》項目的早期核心人員;4年忙碌的過程中除了負責項目還要照顧兩個項目期間出生的孩子。。。

《荒野》是育碧製作的有史以來最大型的開放世界動作冒險類遊戲,使用了4層32k*32k的Heightmap;

遊戲背景設定在玻利維亞,遊戲場景有著很高的多樣性,包括了11種完全不同的生物群落;

包括了湖泊、河流小溪的16平方公里的大地形,其頂點數將近9百萬;

自然環境主要是由大量的森林組成,包含成千上萬的樹木、灌木和岩石等;

還擁有長達600多公里的公路和更多的小路;

以及貫穿了整張地圖的鐵路系統;

一共有200處左右的營地、地標性建築、前哨基地,還有58個完全程序化構建的村莊;

程序化開發工具及技術 - 摘要:

  • 第一個原型 - 2012年開始製作
  • 地形工具 - Guillaume將要談到他創建的工具,以及地形渲染的一些細節問題
  • 程序化工具 - Benoit將要談到場景的創建工具和流程

https://vimeo.com/207479227 原型展示視頻;

在《幽靈行動:未來戰士》完成後開始嘗試製作更大的地形;

配合world machine使用現實世界的數據獲得相關DEM文件;

然後結合Houdini開發了一些工具如:

  • 自動生成自帶LOD的Tiled Mesh;
  • 根據基於斜坡、高度、粗糙度和來自World Machine的其它蒙板如flowmap制定的一些規則,來定義材質分配的splatting mask;
  • 通過坡度,高度,材質,密度,樹木之間的距離等一系列規則來獲得植物的散布點;

原型只由4個美術和1個圖形程序員花了若干個月做出來;

製作這個原型,先使用了《幽靈行動:未來戰士》遺留下來的引擎:Yeti;雖然我們用Yeti取得了一些不錯的成果,但其還是不能滿足我們的需求和野心,我們決定更換引擎:Anvil,刺客信條的分支引擎;

這個原型讓我們認識到了兩點:

  • 我們必須改進自己的地形製作流程;如處理模型需要在編輯器和各種DCC軟體中來來回回,很不方便;因此需要新的地形製作技術:方便美術的編輯和滿足運行時很好的性能;
  • Houdini被證明是一個非常靈活和高效的工具:技術美術可以在沒有專門開發人員的情況下創建工具;

4年前加入育碧公司《幽靈行動:未來戰士》團隊的Guillaume Werlé,在原型開發的幾個月後,就開始投入到了地形編輯器的研發工作;

在這幾個月中,美術團隊開發出了一套基於WorldMachine生成Heightmap的流程管線;

地形編輯器的主要目標則是使用這張高精度的而且不帶任何材質信息的Heightmap,轉化成一個逼真且多樣化的世界:

上面的截圖即來自於開發提交前幾個星期,描繪了我們所想達到的目標;我們需要近距離觀看時的海量細節和令人驚嘆的遠景,且兩者完美融合;當調高圖形選項時,像素比可以達到10 texels/cm 和1 triangle/2 cm;玩家在遊戲中可以到達任何位置,意味著整個世界都要達到以上的質量標準;

我們開發的第一個功能就是Heightmap雕刻工具;基於GPU開發有幾個原因,首先當然是快,我們需要能編輯巨大地圖中的區域,一個簡單的點擊就能刷出一整座山;還有就是在編輯地形時這是最好的能提供準確視覺化反饋的方法;Heighmap和筆刷混合在一個浮點渲染目標中(floating point render target),並且能被遊戲Shader直接使用;

製作遊戲是一個迭代過程;

我們需要在遊戲中嘗試各種新的創意並且不想在還原的時候花費太多時間;

所以我們想到了層的概念;

World machine的輸出被保存在我們稱為<base>的層,編輯器中的每次修改結果放在<macro>層;當不滿意修改結果時,<macro>層中的內容可以被輕易抹掉還原成原始的heightmap;

以下是這個雕刻工具的展示視頻:

https://vimeo.com/207479248

我們還建立了一個Houdini生成修改的專用層(「DCC」層),這是個非常重要的功能,之後會由Benoit在第二部分詳細說明;簡而言之,利用Houdini,技術美術獲得了對地形完全的讀寫控制權;

最後一個層(「micro」層)包含了不能使用Houdini的關卡設計相關的修改;

現在開始說明材質分配流程;

剛才已經說到,我們需要一個看起來很真實、質量標準統一的世界;考量到地圖的尺寸很快能得出結論:全手工去刷地形材質的話,就太慘了;我們需要一個半自動的流程,因此決定用程序化的方式來生成材質;

地形編輯工具中依靠法線方向給heightmap著色的方法就是一個很好的辦法,根據這個簡單的規則,已經能生成大效果不錯的山頂了,我們決定擴展這個概念;

取而代之的是,在滿足規則的條件後,顯示的是有全特性的材質而不是純色;我們設計了若干個判斷條件,它們基於拓撲結構、噪點和能在pixel shader中實時求值的簡單核函數(Simple kernels);

上圖是我們的編輯器設置界面截圖;可以看到其中的每一個設置都由若干個堆疊在一起的規則然後由尾部至頂部進行計算;最後一個計算規則成功的材質才被顯示出來;

https://vimeo.com/207479253

現在一個簡單的點擊就可以刷出設置好的材質,但是材質間的漸變還是要花很多功夫去讓其看起來自然;我們決定擴展依靠「規則」的思路,來智能判斷筆刷的透明度;

https://vimeo.com/207479279

材質分布的結果之後被存儲在2張貼圖中;第一張我們稱為<splatting>,其包含了heightmap每個元素(entry)對應的材質索引;

第二張稱為<Vista>貼圖,看上去像是谷歌地圖的截圖;作用為渲染遠景時作為albedo map;

所有東西都被切割為塊(tiles),並被壓縮成四叉樹(quadtree);這個簡單的框架非常便於LOD的生成和patch的剔除;根據剔除的結果和攝像機的距離,四叉樹的每個節點都有個小的荷載由載入的進程流入或流出;

在開始講渲染之前,簡單的描述一下我們的材質相關;

遊戲中的每個材質中的高精度貼圖都使用Zbrush和Substance工具按PBR標準製作;

每個材質都含有置換貼圖(displacement map);基於曲面細分的置換幫我們在製作原型的時候達到了所期望的「次世代」效果;這種非常好的結果讓我們願意投入更多的時間在GPU相關的工作上;

假如設定簡單,大部分的地形同時使用4個材質就綽綽有餘了;但我們的地形太多樣化,最後使用了143個不同的材質在地形上;在一開始就全部載入它們顯然不可能;

我們把離玩家最近的32個材質緩存在一個貼圖數組(texture array)中;然後使用一個indirection table把全局splatting索引轉換為本地緩存索引;渲染近景的時候,我們直接從緩存中採樣紋理;

了解了以上之後,開始講我們的渲染流程;

這是近景shader的最終效果;為了讓大家更好的了解到其過程,我做一個步驟拆分展示;

在一開始我們獲得splatting的索引;把其轉化為本地緩存索引;然後我們從緩存中採樣所有的PBR紋理;

為了獲得所有材質間的良好過渡效果,我們再做了3次雙線性插值(bilinear interpolation );

為了避免拉伸問題我們為斜坡使用了雙平面投射(biplanar projection );每個軸一遍,那麼就意味著我們要把這些都做2遍;

第一個版本的shader取得了很好的視覺效果但性能消耗卻很大;太多貼圖需要在pixel shader和domain shader中獲取並混合在一起;複雜shader產生非常低的波前佔有率(wavefront occupancy)導致了寄存器的高壓力(register pressure);我們急需簡化一些東西;

在做優化時,我們發現完全平坦或完全傾斜的地方不需要混合太多不同的材質;因此可以為以上的特例做特定的shader;

這是我們對4個相鄰材質做了雙線性插值;

對斜坡做了雙平面投射;

最後,在過渡區域我們仍然需要獲取所有材質;

把地形分割成各個單獨小塊(patches)將會非常耗費磁碟空間;我們的解決方法是使用compute shader在運行時儘快生成進入Viewport的部分;對性能的提升顯而易見,現在大約80%的地形獲取的是4個材質而不是之前的12個;

這時我們開始關注到另外一個挑戰:道路網!運行時生成的話簡直是技術上的噩夢,我們很怕假如要存儲在藍光碟上空間會不夠用;我們決定直接把道路嵌入到地形,而不是用傳統的模型製作;但是這會產生一些問題,比如粗糙的材質過渡和明顯缺少細節;

屏幕空間的貼花(screen space decals)看起來是個不錯的解決方法;

但它們產生了過多的overdraw而很快被停用;還有就是它們不能影響置換拓撲;

在我們的案例中,Virtual texturing技術似乎會是一個很好的優化方案;

這將大大減少材質混合的預計算和所有貼圖集中decals的映射所需要獲取的貼圖數量;Virtual texturing技術已經在一些其它著名遊戲中成功使用過,我想GDC在座的大多數人已經很熟悉其概念,所以我就不講相關細節了;

每種渲染技術都有其缺點,virtual texturing也不例外;我們嘗試在以下幾點改進這個傳統技術;

最簡單決定哪一部分需要virtual texture的方法就是在離屏面(offscreen surface)中光柵化場景,然後在CPU中讀取內容;但這樣非常耗費性能,特別是遊戲在4k級別顯示的情況下;當我們的地形渲染使用曲面細分並且用較低的解析度渲染目標顯示細小的三角面時,會損失太多細節;

我們在Gbuffer通道綁定了一個額外的3D紋理作為渲染目標而不是使用專用的通道;當我們渲染地形時,使用UV和miplevel作為輸出的坐標系來直接指定virtual texture的顯示部分;

然後compute shader分析紋理內容和記錄缺失的部分;之後結果信息(大小只有幾個位元組)會在CPU上讀取;

當用最高的圖形質量運行遊戲時,virtual texture顯示達10 texels/cm 的像素比;假如預處理並壓縮,這些需要大約2Pb的容量;

所以我們決定在運行時生成這些內容,材質和decals在離屏面混合然後使用Async Compute管線實時壓縮;但駕車飛馳時需要地圖塊的大量更新,很快就會幀率狂降這樣的幀間低一致性(low frame-to-frame coherency)的情況處理起來很棘手;

多幀間的Virtual texture更新不得不做時間切分,以及還要做很多讓高幀率和低潛伏期(latency)達到平衡的調整工作;

我們嘗試成功的去把很費的近景shader替換成virtual texturing;

幸運的是我們在開發前期就做出了這個決定,結果調整了內存的預算;

如大家所看到的,遊戲在1080p的情況下運行時,存儲atlas圖大概需要200MB多一點;原生4k的情況下,會達到1GB左右;

譯者註:把所有要混合的貼圖做成一張貼圖,這張圖稱為Atlas;

我展示一些xbox one上運行的性能數據來結束我的演講;如上圖;

(演講人換為Benoit Martinez )Guillaume已經給大家講了地形相關的方方面面,我來講講我們的程序化工具:它們是什麼,如何工作以及其背後的理念;

規模

  • 工具適合從大到小的各種規模的場景;
  • 編輯範圍從最小的岩石到最大的山巒是製作這個工具的準則;

協作性

  • 一整個巨大的關卡;
  • 兩個在不同地點的製作團隊:巴黎和布加勒斯特;

迭代性

  • 我們需要能修改需求;
  • 試驗新的想法;
  • 工具即為數據:工具的創建和存儲與世界上任何其它實體完全一樣;工具是生成自身實體的元實體;

當然最重要的是:每天都必須能保持其可遊玩性;

  • 基於規則的工具:使用者編輯參數和調整規則就能產生相關內容;
  • 確定性:相同的輸入產生相同的結果;
  • 離線性:沒有任何東西是在運行時生成;所有的都是在製作時烘焙的;
  • Houdini:世界創建流程管線和所有的製作的工具使用Houdini;
  • CPU:自從我們開始使用Houdini大部分工具都基於CPU(Houdini的最新版本能更好的支持GPU,但我們製作時並非如此);依賴CPU並不是問題:CPU很便宜,但我們需要更多內存,一些工具非常佔用內存!

什麼是Houdini:

  • SideFX公司的DCC(Digital Content Creation,數字內容創作)軟體;
  • 在特效領域大量使用(但不關我們的事);
  • 我們用來進行場景創作;

我們用Houdini來做什麼?

  • 原型:很好的能快速實現想法的工具集;
  • 工具創建:創作相關內容;
  • 視覺預覽數據/獲取統計數據/處理數據/優化數據;

為什麼使用Houdini而不是C++/GPU工具?

  • 快速迭代;
  • 沒有編譯時間:工具是HDA(Houdini digital assets)- 在HDA中做修改或修復Bug -> 發布給團隊 -> 每個人可以馬上使用;
  • 性能問題?專用的工具當然會更快一些,但Houdini有無可取代的靈活性;

Houdini團隊:

  • 一個技術美術總監(Benoit Martinez)和三個技術美術創建了所有的工具並設置了流程管線;
  • 30個場景構建人員(由關卡美術和關卡策劃組成)在開發過程中使用了這些工具;

我們所使用的SideFX產品?

  • Houdini(DCC軟體)-> 創建HDA/工具
  • Houdini engine -> Houdini的核心API整合到了我們的遊戲編輯器;在編輯器中使用HDA/工具;
  • Houdini Batch(渲染農場) -> 渲染農場中的計算工作;

地形的確就是其它一切的基礎;我們所做的第一件事就是創建了自定義節點來讀取地形數據;這裡用一個應用到Houdini網格的地形塊作為例子;如上圖,可以看到若干個選項,現在獲取的是地形基礎層;

然後是選擇了所有層;手動修改的層(macro層和micro層)和生成的其它層如道路層等;

我們有很多在這個世界中填充大量物件的工具;

這些工具並不創建模型,而是幫助美術對已有的物件制定擺放的規則;

我們大部分的Houdini工具處理好擺放點然後返回引擎以下數據:

  • 矩陣;
  • 已有物件的ID;

https://vimeo.com/207489407 以上是展示工具創建以及為何快速和靈活的視頻鏈接;

我們估計有80%的數據是使用Houdini創建或操作的;由於它們是基於規則的工具,所以能很好地保持一致性;

這些工具修改迭代世界中的大量區域,為美術節省時間,讓他們能專註於更有價值且不能使用自動工具完成的任務:

  • 統一大局;
  • 賦予意義於這個遊戲世界;
  • 通過場景環境來講述故事;

地形只是最初始的一層,讓我們來看看構建在其上的其它層的細節;

地形不僅僅是高度以及貼圖混合;

我們推導出能夠在其它工具中復用的有用信息,比如:

  • 從海拔高度中我們可以獲得粗糙度、檢測出山頂,這些信息對擺放石頭或植被很有用;
  • 從河流、材質和一些特定的物件我們可以定義出潮濕度,然後可以使用在植被的規則中,或影響地形的高光;
  • 求陽光照射的平均值,我們可以得到一張有用的蒙版,用來驅動植被和環境音效;
  • 來自world machine的初始水流蒙版(waterflow mask)用來影響地形splatting;但是當地形被雕刻修改後我們想保持這張蒙版的更新;

我們在渲染農場中自動更新這些地形層:

每次當有用戶提交了地形的拓撲結構修改,會觸發Houdini渲染農場的重新計算;更新文件存儲在Houdini工具可以立刻讀取的伺服器上;成為中間數據後可以隨時更新,我們對此沒有任何版本控制;沒有版本控制和備份聽上去有點嚇人,但製作中我們也沒出什麼問題;

https://vimeo.com/207479343

在談到我們工具集的具體細節之前,用以上的視頻展示一下程序化生成的層;

  • 道路生成和程序輔助;
  • 野外的道路、植被、岩石;除了最後兩塊大石頭是手動擺放其它的都是程序化生成,包括河流的成形、水體模型和流向;
  • 甚至村莊也是生成的,從仿地成形到建築的擺放;
  • 帶有隧道和橋樑的鐵軌線路;
  • 在全局運作,連接所有的道路,計算flow map蒙版,擺放植被和村莊;

定義路點,通過尋路演算法(Pathfinding)自動連接成道路;

第一次尋路的測試結果還不錯,但還不夠好;

根據這篇論文:arches.liris.cnrs.fr/pu

我們開始試驗加權各向異性(weighted anisotropic)最短路線演算法;

其關鍵是搜尋多個方向和每個方向的多個距離,而不是之前的四個方向;

最後的結果正是我們想要的;

在地形上放置少量路點。。。。

我們獲得了有各種類型道路和小路的統一道路網;記住這都是離線過程;其計算時間並不是問題(2km*2km的地塊計算起來只要10分鐘);

道路層輸出的信息有:

道路軌跡:我們可以在很多情況下使用這些信息,如AI的交通系統;

地形塑造:一張heightfield貼圖塑造了地形;

Splatting:一張更新地形材質的貼圖蒙版;

橋樑:假如是最優路線,我們允許尋路演算法能跨過河流;

https://vimeo.com/207479385 展示尋路演算法形成地形主幹道的視頻鏈接;

我們有手動創建decal、電線、柵欄和防撞墩的工具,然後當我們試圖去構建一個完整、真實的公路網時,意識到我們只需要輸入路網的道路軌跡信息到工具,可以很方便的生成這些道路輔助設施,不用人工去擺放;

鐵路層同理,但其規則稍稍不同;更低的坡度,轉彎少且平緩,還有更多的橋樑和隧道;公路的道路軌跡信息為隱式輸入,因為鐵路需要考慮到公路情況,不能重疊(某些地方會平行)並且相交時要保持90度角來避免危險和潛在的交通問題;

https://vimeo.com/207479400

之前提到的一些工具,比如視頻所展示的橋樑工具,可以在獨立模式下手工創建橋樑或嵌入到更大的工具中去自動創建相關內容;

注意:橋樑或隧道是模塊化的,並沒有新的模型被創建,只是實例化而已;

遊戲中16平方公里的地方被水覆蓋;

這是一個被切分為塊(tile/平方公里)的單獨連續模型;

水關乎到湖、河流和小溪;

河流湖泊這些地形的主要特徵可以在地形工具中直接製作;

另一方面數量龐大的小溪使用道路的尋路做法把山頂的源頭和河流連接起來(然後河流連接到湖泊);

對於地形地貌我們定義了一些層順序,所以小溪會在道路下鋪設的管道中流動,但河流我們更傾向於讓其穿過橋樑來保持連續性;

我們生成小溪的軌跡信息後(還有某些河流)我們就能復用這些信息來定義flowmap的向量;然後flowmap被存儲在頂點色中;

定居點構建工具是我們最複雜的工具之一;輸入定居點中心、建築清單和一些參數來完整的生成遊戲中的村鎮;我們花費了不少時間去做成這樣一個穩定的、可用的工具,最後我們達到了所期望的目標;程序動態生成定居點後,我們會把其「鎖死」,讓美術去手動添加更多的細節和潤色;

https://vimeo.com/207479416 以上視頻鏈接是定居點工具的展示視頻;

農田生成工具可以單獨使用,創建獨立的農田;也可以把定居點作為輸入值來生成其周邊的農田;

我們用了比較傳統的方式來做岩石的分布:

定義一張分布蒙版 - 美術可以在編輯器中直接視覺預覽:

  • 分布規則應用在什麼地方
  • Material – Occlusion – Curvature – Flowmap – Roughness – postFilter

創建應用在蒙版內的分布規則:

  • 模型
  • 相對坡度調整
  • 比例參數
  • 密度/最小距離

假如需要的話,分布規則還可以考慮到其它工具的結果,來避免石塊與路面或建築等重疊;

基本來說,植被工具用起來和岩石工具差不多,不過當然還是有自己的一套參數;複雜的多功能工具維護起來也很複雜,並且效率也相對低下;各種情況下我們都更喜歡專用工具;

我們可以在開發過程中不斷的改進這些工具;

為了避免每一個可能的用戶都有特定的需求,我們決定每個工具都有一個擁有者;通常是一個美術與將創建相關工具的技術美術合作;為一個工具編寫相關文檔的也可以是工具的擁有者,來編寫更友好易於理解的幫助文檔而不是技術文檔;

我們還整合了預設支持,那麼工具擁有者就能夠創建一系列規則,其它的用戶可以直接使用這些預設值而不用去理解和使用所有的參數;

排除法工作流:

混合程序化內容和手工控制是非常複雜的;

假如想要好的手動控制那麼就應該純手工去做;所有的工具都支持輸入手工定義曲線來排除某個區域,或隱式輸入(比如:排除道路上的植被);

使用這個工作流,負責植被或岩石擺放的美術可以不用考慮村莊、道路等諸如此類的問題;他們只用任意定義生物群落的規則,必要的排除過程會在之後的整合過程中完成;

非同步更新:

我們需要保證一個始終可遊玩的世界,但並不意味著其要很準確;

假如地形的拓撲結構修改了,我們不必完全重算植被的擺放,大部分情況下我們只需要保證沒什麼東西擋住道路並且所有東西吸附到了地形;

記住這些工具是獨立使用的,不受其它物件擺放的約束,並且它們都應用在原始的基礎地形上;

我們還有「點緩存(point cache)」,所有point來自各個工具;

  • 首先編輯器針對地形檢查所有實例;
    • 把所有的東西吸附到地形(保持所有的地形相對偏移 - 想想陷入到泥土中的石塊)
    • 刪除程序地形化區域所不需要的物件
      • 從道路、河流和定居點等等地方移除植被;
  • 然後針對所有實例組間的相互關係
    • 橋樑和隧道則刪掉石頭
    • 石頭上則刪掉植被
    • 電線不能穿過樹木
    • 還有諸如此類的情況。。。。。

當我們能獲取Houdini上所有的數據的時候,我們能做的不止是物件的擺放了;這裡我們在檢查物件密度(植被和岩石)然後以此平衡每個物件的LOD;

除了視覺化方面的我們還可以用來做音效設計;我們有工具可以根據地形、物件的類型定義規則來生成一張音效圖(sound map);每個顏色可以作為一個特定環境音效的索引;

Worldbatch可以幫助自動處理這種任務,或者允許你在任何時候更新世界所使用的任何類型的數據 ;

Worldbatch基於Houdini python (hython) ,使用 "Hqueue" 任務分配系統(由SideFX開發)在渲染農場開始一個數據任務;

一個任務讀取一個Houdini asset資產文件(otl格式),假如需要的話設置好參數然後開始此otl文件的渲染進程;

用戶在UI模式下能夠從世界地圖中直接選擇想要重新計算的東西,它能自己運行,把任務發送到自己的電腦上或發送到渲染農場;

之前我提到過把Perforce也加入了進來,worldBatch會在用戶提交Anvil引擎的地形相關修改清單時自動運行,命令行腳本將會讓worldBatch發送基礎任務到渲染農場保證數據的更新;

4位技術美術創建了多達145個的各種工具和全自動化的管線流程,讓關卡美術能更專註於細節表達,甚至能幫助視覺方面以外的音效、遊戲玩法、邏輯等工作,推動了整個項目的效率;

這裡,演講結束;下面是總結和特別感謝名單;

<全文完>


推薦閱讀:

為什麼很少優秀的刺客信條cos?有沒有優秀的ACcos分享?如何cos還原AC?
為什麼刺客信條的遊戲模式越做越偏離刺客了?
在《刺客信條:起源》里你見到或拍到過哪些好看的照片?
有多少玩彩虹六號發生的趣事?
如何評價《刺客信條:起源》DLC「法老的詛咒」(The Curse Of The Pharaohs)?

TAG:遊戲開發 | Ubisoft育碧 | GDC |