大世界技術整理之一 GDC Ghost Recon Wildlands Terrain Tools and Technology
1 GDC 連結:Ghost Recon Wildlands Terrain Tools and Technology
2 規模:
32k x 32k heightmap x 4 layers
11 Biomes
140 materials(Terrain meterials)
Rivers and lake area: 16 km2
Vertices: 8,912,520
Trees: 839,862
Bushes: 3,449,638
Rocks: 775,288
Roads: 656km
Footpaths: 2150km
Crash Barriers: 10,712 modules
Traffic Signs: 781
Decals: 4,874,935
Railways: 90km
Sleepers(枕軌): 61,435
Villages: 58
Building modules: 217,715
Village props: 234,697
整個世界大小約:20km x 20km
3 從原型開始:
猜測是1個TD+4個TA 和圖程的專家團隊,從12年開始做原型
地形
容易編輯
執行快
Houdini 是專案的核心
用一個叫Anvil 自研的遊戲編輯器去做
質量:
真實的觀感
從鵝暖石到山脈
10 texels per cm
1 triangle every 2cm
3。1 分層:
可互動且非破壞性的過程
分層設定
Base - World Machine output(World Machine 中匯出的高度圖)
Macro - Large features(用來做地形的二次修改):編輯器下的修改都儲存在這裡。可以用筆刷還原到Base Layer 狀態,可以在這一層細化高度圖和其他細節
DCC - Houdini generated modifications
Micro - Level design adjustment
我的理解:Base 層和Macro 層是地形,DCC 層是Houdini 生成的過程化物件,Micro 用來手擺。DCC 中去Fetch 各種資訊,如地形高度圖、Splat 貼圖、地形的其他貼圖,再按照一個Flow 去過程化生成所有的Object,因為有些Object 的生成規則的輸入,依賴某些前置流程的輸出。在生成各個DCC Layer 的過程中,有些步驟也會影響原始的地形高度圖,因為可能會涉及到地形的二次雕刻。
3。2 材質分佈:
手刷是不可能的!過程化!
在遠景雪山上:最基本的原則是根據法線的z 做灰和白的線性插值
基於每一級的規則設定和規則的疊加順序,在材質編輯時自下而上逐級取樣坡度、高度、噪聲、曲率資訊,決定所需要的使用的材質,再在畫素階段去取樣這些紋理生成最終的PBR引數
所有的符合的規則都會被寫入紋理中,很多時候不止一種材質
同時支援手刷修改材質,與過程化的生成結果做合併
最終儲存了兩張紋理用來存材質分佈的結果,一張存材質Id,另一張存用於遠景的Albedo
這兩張紋理的解析度都和高度圖一樣,並且用Quadtree(Mipmap)做了處理,方便做Lod、Culling和Streaming
3。3 地形材質:
PBR 紋理集,用ZBrush 和Substance(Painter)
Albedo
Roughness
Specular occlusion
Normal
同時用了Displacement(實在聽不懂這裡說的是啥,好像是用了Displacement mapping 在什麼原型期,所以決定多分配點GPU 時間在上面)
(每個地形塊)大部分用4種材質,用頂點色或者權重圖去混合每一個Terrain Renderer
總共有140+ 種地形材質
不能一次性全部載入(會做流送)
(接下來是猜測)因為一個地形使用的材質數量最多32種,主要是4種,那麼我就把每一組地形所於Splatting 的Albedo 紋理放到一個Texture2DArray,然後先從Splatting 中取出Splatting Index 再轉換成Local Index(cacheIndex),再用UV 和這個Local Index 去取樣得到Albedo(和其他PBR 引數)
3。4 前景渲染拆解:
這裡為了混合效果好,就需要多次取樣Splatting(不懂)
然後處理斜坡處的Bi-Planar Mapping(沿著水平的X 軸和Y 軸分別做世界空間取樣)
為了避免在材質中去做4+8次取樣混合(也就是常用的Tri-Planar Mapping),會把每個Patch 分成3個部分
不那麼陡的用4層材質做混合,不做Tri(Bi)-Planar Mapping
非常陡的就只沿著X軸和Y軸做Bi-Planar Mapping,不用再取樣Z軸(豎直方向)上的4層材質
坡度介於中間的才做Tri-Planar Mapping
(這裡我估計跟RVT 有關)當Patch 在Viewport 中時,執行時動態切分並且做快取,用Compute Shader
可以減少大量的紋理取樣,因為80%的紋理都只需要取樣4次了,而不是Tri-Planar 的12次
3。5 道路網路:
因為某種原因(實在聽不清),決定把路網直接雕刻在地形上,然後要解決兩個問題:糟糕的過渡和缺少細節
為了增加細節,加上很多延遲貼花,但效能又不行了,而且還不能影響Displacement
所以就開始用Virtual Texturing(手動狗頭)
3。6 虛擬紋理:
虛擬紋理技術的上下文就不詳細說了,感興趣的可以參考我的這個分享
主要的流程是:
Feedback pass 用來計算tile id 和mip level,然後透過一個頁表的結構去管理Texture tile,最終顯示出來
但是也有一些問題要處理,主要是Feedback pass 和Amount of content(特指SVT)
在CPU 上去算哪個tile 被請求就很慢,因為要遍歷整個framebuffer,尤其是在4K 解析度下。降低精度也不是個辦法,會缺少細節(迷。好像說的是用了Tesselation 和大量的Triangle)
所以就換了一種做法:
在GBuffer pass 中去輸出到一個三維紋理中:xy 是tile 的index,mip 是tile 的mip,然後標記這個tile 為VT_USED
跑一個compute shader 去把這個資料轉成CPU 友好的結構,存一個UsedCount 和Used 資料
在這個紋素比的情況下,資料實在太大,所以我們需要RVT
在請求tile 時動態去畫一遍然後快取起來,並透過非同步的compute shader 去壓縮成BC 格式
需要小心地調教效能,避免卡頓或者載入緩慢(翻譯是口吃)
結果就是香!一堆8K圖,總佔用才218MB
總體來說效能還可以接受
4 過程化工具:
能大能小
能區域性編輯,也能整體編輯
易於協作
支援多個使用者在同一個區域同時編輯
互動式易於驗證
工具和內容的變化都要能比較及時地反饋出效果
工具就是資料
這個過程化的工具,是:
基於規則的相互依賴的一套工具
是確定性的,同樣的輸入會有同樣的輸出,沒有隨機
是離線的,不是執行時的
基於Houdini,CPU Based,內容生成工具
各種好(如上)。TD 很熟悉,用Houdini 可以做很多原型和工具,並且能快速迭代,一個小團隊就可能用起來,在Houdini 編輯器下做完之後可以透過Houdini Engine 在自己的編輯器App(比如UE4)與Houdini 互動對接,有一個大概15臺機器的渲染農場(用於Houdini 的整圖解算)
在Houdini 中可以透過這個工具去讀取預先做好的Base Layer
其他Layer 也能取到
4。1 Instancing 方面:
用Houdini 撒點
傳送Matrix(位置朝向縮放)+ Object ID 給遊戲編輯器(如UE4)
在引擎中例項化這些物件
右邊圖上每一個點就是一個Object,都是基於規則的,透過Houdini 中的各個工具去生成。可以看到道路和道路上的Decals、村莊等等
接下來這段超燃,建議自己看,演示了用Houdini 做一個帶坡度等引數的撒點工具的製作和引擎匯出:
生成一些景觀Decals:
先弄個封閉的區域
然後撒點
讀高度圖
計算法線
根據坡度做剔除(加上Slope 引數)
加上一些隨機的旋轉
繫結模型
把曲線做成Input
把撒點的數量做成Input
把Slope 做成Input
把要繫結的Models 做成Input
最後把工具打包傳送給遊戲編輯器
這段太燃了,一定要自己看!
(發現Anvil 的UI 上有一個時間的條,做完之後調調時間看看效果,感覺就很棒!)
美術就可以爽快地用起來了,然後如果美術說,能不能幫我改一下,讓這些樹只生成在路邊?很容易,因為Houdini 裡面我們有這些資料(能讀到Roads 的資訊,改一下撒點邏輯即可)
4。2 最後的效果:
用Houdini 生成了80% 的世界(但剩下的20% 卻消耗了80% 的資源)
然後是一些總結回顧:
高度圖和紋理
32k x 32k 的高度圖
32bits 的材質紋理
100GB 的Terrain Layers(這裡沒搞懂)
Instancing
大概1200萬的Instances
Meshs
不是很多,但Houdini 也會幫忙生成一些Mesh
5 深入細節:
地形資料除了高度圖和Splatting 之外,還有Roughness、Wetness(根據河流的位置)、Sunlight(用來做植被生長的評估)、WaterFlow(每次修改地形都需要重新生成) 等紋理
又有一段很燃的影片,請自己看吧
道路:
道路
路邊的灌木
Decals
電線杆、護欄等Props
其他的植被
前景背景,都可以走過去,都是一樣的
Footpath:
Footpath 邊上灌木
植被
石頭(地形上的包邊石)
Props
還有兩個手擺的石頭
還有:河流、小路等
村落:
地形
河流
包邊石
灌木
植被
房屋
其他裝飾物
鐵路:
橋樑
鐵軌
枕軌
等等
道路:
因為人力受限,不能完全靠手擺道路,而道路又是遊戲的關鍵,所以做了套工具,過程化生成道路:
先定義路點(或者定居點)
透過尋路演算法去做Settlement 之間的連線
要保證規則的一致性
用各向異性的網格去生成路網
參考論文:Space Colonisation for Procedural Road Generation
5。1 接下來是每個模組生成的輸入和輸出:
這裡除了靜態的場景部分,還會加入一些NPC,用來表達Activities
石頭會輸出Volume 用來遮擋植被
5。2 散點快取和互斥的工作流:
如果美術或者關卡策劃想要修改特定的場景部分,那就標記那塊區域(沒怎麼聽懂,好像是圈一塊地),然後在Houdini 中就不去生成這塊內容,這樣就可以手擺了
另外這些散點如果每次重新計算的話開銷會很大很大,所以就弄了個非同步的工作流:按月重新重算所有散點資訊,並且儲存成points cache,日常工作就是把points cache 取下來,合併結果(我猜這裡是做特殊修改時可以臨時刪除某些散點,手調某些特定的區域,然後透過Subtractive Area 去遮蔽防止Houdini 覆蓋這塊區域)。同時需要透過一些自動貼地的方式,保證總是Playable,防止在地形變化了的情況下東西浮空,影響日常的迭代
這裡好像是說可以透過LOD Multiplier 做全域性的LOD 調教(沒太聽懂),自動去平衡LOD distance
並且有CI 流程每天去檢查每個區域的三角形密度,如右圖
6 合併工具:
7 過程化工具:
145 個工具 & 全自動的流水線:4個管線TA
被強化的LA:可以專注在細節上
除了視覺部分還可以生成聲音、Gameplay、Logic
透過一個特別的團隊去完成,大家目標是一致的
有圖形程式和TD、TA:大家一起做工具(但不僅限於此)
8 Q&A:
1、怎麼辦到Houdini 裡面這麼多東西遊戲中效能OK的:
A:我們會做流送,只是在工具裡面會比較吃記憶體。我們還有Instancing 系統,比如樹就是,大概渲染5km,再遠就是Billboard 了
2、怎麼測試這麼大的場景的:
A:我們就是跑圖,用載具什麼的。然後我們還有機器人,Nightly Build 之後會去跑圖,去檢查幀率、記憶體、丟失的資源等等,然後生成一個報告。總體來說我們把一切都控制在自己手上,比如距離、間隔等等,並且流程也維護得很好,沒怎麼失敗過,雖然有但不多。
3、你們是怎麼做到的這樣的流程和更新哲學的,是怎麼獲取主要使用者的,怎麼把東西做出來的(沒怎麼聽明白):
A:我們是從原型開始做實驗,逐漸發現我們的能力邊界,並且有一個非常扁平非常高效的團隊密切合作,逐步迭代。隨著團隊規模變化,我們也做了很多調整。
4、你們的團隊最終有多大:
A:在巴黎TA、LA、Props Artist 大概有17人,其他地方還有(沒聽明白)