【GDC2017】Terrain Technology and Tools
育碧2017年的重磅分享。
先看一下效果視頻:
https://www.zhihu.com/video/953778110856957952E3 2015:《幽靈行動:荒野(Ghost Recon:Wildlands)》擁有一個非常大的世界:
有11種生物群體,有140種材質:
有16平方千米的水面(湖、大江、小河)覆蓋:
有著數以百萬記的樹木、石頭、灌木:
有超過600km長的道路:
並且有超過90km的鐵路:
有58個村莊,和大量的建築:
整個介紹分為五個部分:
- 原型介紹
- 地表工具
- 地表渲染
- Procedural 工具
- 結論
Houdini
https://www.zhihu.com/video/954842069030703104
首先,我們使用真實世界的數據優化了world machine生成的DEM(Digital Elevation Model)文件。然後,使用Houdini創建了一些工具用於:
- 自動生成帶有LOD的地表Mesh
- 根據坡度、海拔、粗糙信息、沖刷圖等生成地表materials分布信息
- 自動生成地表上的各種物件
Terrain Tools
Terrain Tools的目標是用Heightmap作為輸入:
然後得到一個豐富、真實的地表:
地表的效果需要達到這樣的目標:
- 有著大量細節的近景、震撼的遠景以及無縫過渡的中景
- 最高有著10texels/cm、1triangle/2cm的精度
- 玩家可以到達世界的任何一個角度,需要任何地方都有著一致、連續的效果
在Editor中,首先添加的一個功能是,刷地形工具:
工具基於GPU運算、可以實現在比較高的幀率下編輯大塊(2km*2km)地表。
製作一款遊戲的過程中,反覆迭代是在所難免的,地表編輯人員需要能夠快速的構建地表驗證想法、並且能夠快速的回退修改。
所以,我們提出了一個Layers的概念,Layers的幾種主要組成依次是:
- Base Layer :world machine的原始輸出
- Macro Layer :用地形筆刷做的修改(大的feature)
https://www.zhihu.com/video/954856571239464960
3. DCC層- Houdini生成的修改( 會被後面講到的Benoit cover掉)
4. Manual Level (包含所有手動的修改,這一步沒有Houdini的參與)
Material Distribution
製作的目標是得到一個一致連續的、高質量的大世界。對於這麼大的一個世界,如果純靠手刷material的話,幾乎是不可能的。所以,必須使用自動生成的方式來得到material分布信息。
舉個例子,生成material一個常用的rule,根據法線的z方向(有的引擎是y)可以得到一個比如雪的覆蓋信息:
更進一步的rules基於以下數據:
- 坡度
- 海拔
- 曲率
- Noise
- more...
基於這些信息,可以創建很多的rules,rules用棧的形式組織成為一個settings,棧中最後一條被滿足的rule會被採用並用於顯示。
效果:
https://www.zhihu.com/video/955212972574851072除了自動生成的material之外,有些區域還需要一定程度的手刷操作。比如不同區域(有著不同的settings)之間的過渡區域需要手刷。手刷地表的視頻:
https://www.zhihu.com/video/955217206435426304編輯之後的material分布結果會存成2個texture:
(1)Material ID map:用於存放材質ID
(2)Albedo map :用於遠距離顯示(遠距離直接顯示顏色圖)
地表會被切成tiles,以四叉樹的形式組織,利用這種組織結構,可以比較方便對地表做相關優化:
- LOD
- Culling
- Steaming
Terrain Rendering
每個地表的material(比如石頭material)會使用了以下幾種貼圖:
- Roughness
- Albedo
- Specular Occlusion
- Normal
- Displacement
基於Displacement和Tesselation技術得到非常次時代的效果:
在整個遊戲的大世界中,有著140+種地表material。這裡,使用Texture2DArray,可以同時載入32個material:
接著,我們看一下具體的渲染過程。比如來渲染這樣一個地表:
第一步是根據material ID,取對應的textures:
再取3次,進行線性插值的結果(一共4次):
為了解決斜坡的拉伸問題,沿著x方向、y方向分別採樣,做線性插值:
初版的效果雖然比較好,但是過多的貼圖採樣讓性能非常差(4次插值採樣、x軸和y軸:*2;一共採樣8種material):
優化思路,不需要所有的地表區域都要考慮斜坡拉伸問題,所以將地表分為以下幾塊區域:
這樣,大部分地表(80%)上,只需要採樣4種material:
這個分割的過程是runtime做的。
另外一個比較大的挑戰是繪製道路。這裡的做法是,直接使用地表渲染來渲染道路(不用單獨的mesh表示道路):
這樣做有幾個缺點:
- 道路的邊緣過渡不好處理
- 道路細節較少
這裡採用基於screen space的decal來提升細節:
但是,過多的decal導致overdraw很高,性能開銷比較大。
Virtual Texture
virtual texture是一個比較重要的優化方案。
它對material的blend進行pre-compute,然後存在一個集合里,在渲染的時候再進行查找使用。缺點是:
- 需要一個Feedback Pass
- 需要存海量的數據
我們需要對這些缺點進行優化,首先,考慮一下如何做Feedback Pass:
最簡單的方法是直接在CPU中進行計算,得到Tile identifier、Mip 信息(用於取Virtual Texture)。但是,CPU計算這種數據相對於GPU是很慢的(尤其是要支持4K屏幕)。如果要在一個小RT上做運算,又會丟失太多的細節。
最後採樣的方法是在G-Buffer Pass做這個事情:
使用一個3D Texture作為RT,3D Texture用UV、Mip作為坐標存儲Tile identifier。這一步之後,需要使用compute shader提取出missing parts。
用Virtual texture存儲Content的另外一個問題就是,數據量巨大。比如在高效果下,需要10texels/cm的貼圖精度。對整個大世界來說需要2P(1P = 1024T;1TB = 1024 G)的存儲空間。換而言之,就是不可能所有的blend都pre-computed。
最後採用實時生成Content的方案,分為以下幾步:
- 渲染materials和decals的blend結果到一個surface上
- 使用非同步的compute shader進行壓縮
要注意的一點是,所有的以上計算會被動態的分配到每一幀去計算,以保證幀率的穩定性。在1080P下,大概使用了218MB的內存:
通過Virtual texture的使用,大大降低了shader的開銷。
一些相關的計算性能的開銷數據:
Procedural Tools
Tools的幾個使用要點:
- Scale
- Tools必須同時支持不同的scale編輯
- 要同時控制好石塊和山峰不是一件容易的事
- 合作
- 在一個巨大的世界編輯中合作
- 跨兩個團隊合作
- 迭代
- 能夠比較方便的改變想法
- 能夠比較方便的實驗想法
- Tool也是數據
- 保持地圖是playable的
Tools的幾個特點:
- 可調參;用戶可以在開發的過程中調整參數
- 確定性;對於同樣的輸入,可獲得同樣的輸出
- Offline;數據需要烘焙
- Houdini;基於Houdini
- CPU;Houdini是基於CPU的,所以Tools也是主要使用CPU來計算
Houdini的使用是基於節點的,比如我們首先使用一個Displace節點讀取基本的高度圖:
然後,依次應用多個節點:
Houdini另外一個非常重要的功能就是生成大世界中的物件分布(Object):
https://www.zhihu.com/video/955574788715016192整個大世界中有80%的物件是Houdini自動生成的,這樣地編就可以專註於一些不能自動做的事:
- 關注整體畫面感-big picture
- 賦予世界意義-meaning
- 關注故事性-story
From The Ground Up - Terrain Drives Everything
地表只是整個世界的第一個Layer,我們需要在地表上構建其他的Layers(地表上擺放的物件)。在之前的討論中,我們只用到地表的height和splatting(material區分信息)。地表還可以有很多其他的信息(通過一定的規則提取):
我們可以基於這些信息,來影響Layers的生成,比如:
- 基於Roughness信息,來決定擺放石頭還是植物
- 基於Wetness,來影響植物的擺放和地表的高光
- 基於Sunlight,來影響植物的擺放和ambient
在進一步講述之前,先來用一個簡短的視頻說明一下自動化生成Layers的過程:
https://www.zhihu.com/video/955578110574288896Road Layer
首先,具體說一下Road的生成實現。對於Road,我們定義一些Waypoints,然後通過path finder來生成Road:
初始得到的路線是不太符合真實的,通過Anisotropic grid(http:://http://arches.liris.cnrs.fr/publications//articles//EG2010_ProceduralGenerationOfRoads.pdf)的方式進行了優化:
得到的Road線具有一定的多樣性。一個真實的例子,基礎地表:
生成Road後(有不同大小級別的Road):
對於Road Layer,總結下來,它的輸入是:Way Points;輸出是:
- Road Trajectories(Road的具體的線路)
- Terraforming(高度修改信息)
- Splatting(材質信息)
- Bridges(生成的橋)
通過path finder生成路線的過程視頻:
https://www.zhihu.com/video/955588194415239168Road Propsing Layer
跟Road相關的一些信息的生成:
- Decals
- 圍欄
- 電線杆
Railways Layers
Railways(鐵路)的生成跟Road的生成有一定的區別,比如:
- 需要更小的坡度
- 轉彎很小
- 橋和隧道更多
視頻:
https://www.zhihu.com/video/955590647411953664River Layers
在這個大世界中,有16平方千米的地圖面積是被水覆蓋的。所有的水幾乎都是相連的,然後按tile分成獨立的mesh(每平方千米一個mesh)。Rivers(河)和Lakes(湖)是地表的主要屬性,可以用地表工具生成出來。對於無數的Streams(小溪流),通過path finder生成,並匯聚到River里,River又匯聚到Lake。在生成這些Streams和Rivers時,會得到一個Flowmap(存在Vertex color上),用於渲染水的流動。
Settlements Layer
村落生成工具是最複雜的工具之一。給定一個中心點、一組建築、和一些參數來生成一個完整的村落。展示視頻:
https://www.zhihu.com/video/955595002479468544Fields Layers
農田生成工具可以獨立生成農田區域、也可以根據村落生成農田區域。
Rock Layer
生成Rock Layer,我們使用了常用的手法,美術在編輯器中定義分布規則:
- 密度
- 模型
- 大小
- 坡度分布係數
基於以上數據得到Rock分布信息,以及附加的信息:
- materials
- 流向圖(flowmap)
- 粗糙信息(roughtness)
- 遮擋信息
- 曲率
Rock分布信息也會受到之前生成的一些Layers的影響,比如村落、道路的Layers。
Rock Layer最終輸出的結果包括:
- Rock Points(位置點)
- Rock Volume(VDB)
Vegetation Layer
Vegetation(植被)生成工具和Rock生成工具非常類似,只是在參數上有些不同。
Work Flow
Subtractive workflow:
結合自動化生成和手工編輯的方式是,任何rules都可以設置排除區域,在排除區域可以自由的進行手工編輯。
Asynchronous updates:
在編輯的過程中,不需要保持整個大世界都是完整正確的,所以編輯的過程中,整個大世界是定期完整計算一次的。
LOD
植被和石頭的LOD的生成也會在自動化生成的過程中進行考慮。
Sound Layer
我們還會自動化生成音效。
網易遊戲招聘(應屆生、實習、社招)
求賢若渴招: 1.技術美術(TA) 2. 引擎程序 3. 邏輯開發感興趣直接加本人微信:warmsuning 或發送簡歷: hzliyangyang@corp.netease.com
推薦閱讀:
※Procedure Cloud
※走樣與反走樣(Aliasing/Anti-Aliasing):Graphics Cases
※關於雜訊...
※計算機圖形學常用術語整理
※【GDC2013】Sand Rendering in Journey
TAG:計算機圖形學 |