Authored by TraceYang
前言
傳統的制作做比較真實大世界3D關卡地形時,通常的采用的方式是把HeightMap和SplatMap(Layer Mask)導入到引擎的地形系統里,生成Terrain LandScape的地形信息和地表材質的圖層信息。再由美術在引擎編輯器做進一步的細化工作。而這些Map的生成,是使用WorldMachine(簡稱WM)軟件來制作的。
圖為Ghost Recon Wildlands前期使用WolrdMachine制作的地圖
圖 除了HeightMap之外,SplatMap也是要從World Machine中生成的
從WorldMachine中Bake出Map后,導入到UE4引擎里,這個教程wiki上比較多,就不多做描述了。
圖 把Map導入到UE生成的Landscape
但是傳統的WM機制通常會有以下幾個問題
- WM里預覽的地形生成效果跟DCC軟件或游戲引擎相比並不美觀,也不能像其他工具里直接由美術參與修改
- WM導入到引擎需要通過導出Heightmap再導入引擎,當地形比較大時,map生成和寫入到硬盤的時間會超過10分鍾,對美術迭代修改的成本非常大
- WM生成后到引擎后,關卡設計還需要在地形上進行二次開發,從而影響到地形和地表的Map,這時如果需要WM生成部分地形時,整個流程會變的非常混亂。
像Ubisoft在近年來的大世界項目,Ghost Recon Wildlands和FarCry5如里引入了Houdini Pipeline技術,GDCVault上都有介紹,具體的Heightfield替換WorldMachine的制作,會在地形篇提到,管線章節里就不多做敘述了。這里假設你已經用Houdini的HeightField制作了地形,接下來看下怎么能夠快速的通過Houdini Engine快速的導入到游戲編輯器里。
Houdini HeightFiled 到UE4 Landscape的無縫生成
下圖是Houdini HieghtFiled到UE4 Landscape的無縫生成的結果示例,不需要導入貼圖,只需把HDA文件拖入到編輯器的Viewport,賦予預制作好的Landscape材質,就可以自動把HDA Cook成UE的landscape資源。 這里假定假定讀者已經掌握
Landscape Material和Landscape Layer的創建方法,就不多做敘述了。
從Houdini Engine的機制圖可以看到。我們就是通過HDA文件 Houdini HeightFiled的每一個volume的信息轉入到UE4里,這里UE4 Houdini Engine Plugin已經實現了功能幫我們做轉換
首先這里要要讓HeightField的Size的設置和最終在UE4里Bake的Landscape Sizes一致。下圖是UE官方建議的
Landscape的配置。
HDA文件導入到場景后,這里可以看到Landscape 的
Component的情況。
管線介紹部分不會對Heighfiled的制作做太多介紹,用Houdini生成地形信息,通常是用兩種途徑:
方法一:
使用HeightField File節點加載一張已有的高度圖來生成
在
HeightField File 節點里可以配置生成到UE4的Landscape的Size
而具體的對應的UE Landscape的
Overall Resultion,可以使用Heightfiled Resample節點
而GridSpacing則對應的是他實際在UE4里的Overall Resultion
當
Heighfiled的
Grid Spacing比較大時,說明同樣大小的地形,對應的更少的頂點,換算到UE里,就是比較小的Landscape Overall Resultion。 Overall Resultion越小,UE里Landscape生成后的頂點數也會更少一些。這樣適合在移動終端用較少的資源做出相對比較大的場景。
下面我做幾組Height Field Size與UE Landscape Componment的對比,他們最終在UE里的Landscape szie都是8129x8129。只是細節有所不同。
。
業余學習中我們能把Houdini Engine作為一個黑盒,根據需求來做Size和
Grid Spacing的組合來達到想要的目標配置,而真正項目工程里,還是建議由引擎程序根據項目來定制Hengine Engine的Cook Landscape的配置。這個我們在后續的定制更新和修改時也會提到。
方法二:使用Heightfiled節點從0開始生成:
創建這個節點時,就可以選擇整個地圖的尺寸,其中Size就是為導入到UE4后對應的大小,
和方法一一樣Grid Spacing來決定
Overall Resultion。
其他的就跟方法一是一樣的了。
這樣,就可以根據機器性能,在場景用較低的幾何體生成出相對較大的場景。
Heightmap的導入解決了,然后就是HeightField Layer Mask與UE4 Landscape Material Layer的對應設置。
上圖中HDA里
HeightFiled的volume信息,height對應的就是HeightMap信息,這個Houdini Engine已經自動支持了,而其他的Layer Mask與UE的Landscape Material Layer,則可以通過命名來一一對應。

這里我們讓HeightField的Layer Name與UE的Landscape Layer Name保持一直。
左側的Heithfiled Layer名稱和右邊UE的Landscape移植,就可以通過Houdini Engine,不導出中間的Map資源,這個過程相比WM的10幾分鍾要快很多,通常HDA的Cook只要10幾秒。
具體的制作過程可以看附件的HDA事例,這里只介紹幾個Houdini關鍵節點的使用。
HeightField Copy Layer的功能就是把你在Houdini里生成的Layer Mask重命名為你想在UE引擎里對應的Landscape Layer的名字。
這樣,我們可以從HDA文件直接生成出帶地形高度和地表圖層信息的場景了。
Houdini HeightFiled 對World Composition的支持
無縫大世界游戲場景開發中,一個Landscape不管是在多人協作開發,迭代,還是在Streaming的優化以及打包等,諸多方面都會有很多的不便,所以需要我們把一個大世界的Landscape‘Tile化’。比如一個8x8km的Landscpe可能會切成4x4或8x8的Tile。UE也提供了World Composition的功能。
傳統WorldMachine里可以通過Tiled build生成出無縫的Tiled Heightmap和Mask,然后import到UE的Landscape里,這樣其實也會增加bake時間,另外把UE4 Landscape的Mask導回給Houdini也是很痛苦的事情(很慢,需要非常大的系統內存)。
好在Houdini 16.5版本后,其實對這部分的支持也加強了,Houdini提供了一個heightfield tilesplit節點就可以做Tile化了,這里我切成了4x4個tile。
再次把HDA加入場景Cook。就可以生成4x4=16個tile的Landscape了。
但是這個用heightfield tilesplit的方法有他的缺陷,一個是會在tile上產生邊緣產生接縫露空。
而且這種多個
Landscape的方式,和UE4的World Composition機制也有沖突。也不能跨Tile來做地形編輯,其實並不是做無縫大世界地圖的正確方法。
其實World Composition還是一個整體Landscape,通過把
LandscapeStreamingProxy分配到每個子關卡的方式,來進行的Tile分割。
這里提供一個不修改Houdini Engine也能快速的使用World Composition的比較笨的人力辦法來解決。
首先,我們不使用splite節點,直接導入一整張地圖進來,這樣肯定是沒有接縫的。
然后類似創建出對應個子關卡,這里假定我們生成2x2的。
接下來,我們選擇對應的sublevel,用Move to level工具,就可以把對應的Landscape Component移動到指定的Level里,生成一個LandscapeStreamingProxy
最后給每個Level生成對應的
LandscapeStreamingProxy。進行保存。
然后刪除掉原始的Landscape,刪除之前創建的SubLevel,
勾選Enable
World Composition。
UE4就會自動的幫你加載之前的sublevel,生成
World Composition。
這樣就和UE4默認的Import tiled map生成的
World Composition是一樣的了。
和前面的地形尺寸對應一樣,這里正確的方法其實是要修改Houdini Engine里面的Bake機制,參考
Import tiled map里代碼的方法,自動的創建關卡和分配Landscape Component,實現整個流程的自動化。否則將來的迭代也會成為問題。
后續問題
雖然這里看似Houdini HeightFiled to UE4 Landscape的流程已經打通,但是在實際項目開發中還是會有以下幾個問題
- 目前流程中Heightfiled還是整體的修改和導入,無法支持Landscape Component和Section的更小級別的增量更新
- 還要考慮World Composition的支持,可以自動的從Landscape的某個單元更新到LandscapeStreamingProxy
- 后續的基於地形的植被自動生成,山體自動建模等等的生成功能,也是要支持Landscape的最小單元。
- 對應手游的硬件的考慮,還需要要能生成不同細節的資源等。
- 最重要的,要把這流程做成引擎內的閉環,讓開發人員不需要了解Houdini就能UE4里執行和調用功能。
另外Unity雖然沒有提及,但相對實現應該跟UE4類似,而且也可以將Heightfile轉換為Terrain Mesh來適配移動設備,這里就不多做介紹了。而上面描述的問題,會在今后的分享中有所解答。關於本文的事例資源會在近期提供一個分享專用的git地址。
