背景
通過之前的幾篇分析實踐,已經基本打通了UE4的Houdini植被管線部分,並對Far Cry5(簡稱FC5)的植被系統的需求做了整理,在接下來的幾節中,會關注於如何使用Houdini基於UE4來開發類似FC5的植被生成系統。這里按工具制作流程分為幾個部分來做闡述。
- 使用Houdini開發類似FC5里的Generate_Terrain_Entities的HDA節點
- 修改Houdini Engine,讓Generate_Terrain_Entities的Input和Output可以支持在UE4里生成植被
- 進一步優化Houdini Engine,可以讓關卡設計人員可以在UE4 Editor里更加靈活和方便的修改

本節的目標就是如何開發一個
Generate_Terrain_Entities的HDA節點,並在Houdini里實現類似上圖中FC5的效果,大致流程分為:
- 創建HDA面板,為內部的過程化實現創建參數關聯
- 根據Viability中選擇Terrain Data以其他的過程化生成的2D data,確定植被的生成范圍
- 根據Density,Sizes,Scale,Color,Rotation等面板參數,來生成Point Colud,以及Point對應的旋轉,顏色,縮放等信息。
- 多個HDA連接,每個HDA代表一種植被類型。並實現按照Viability范圍和優先級的選擇正確的Species。
- 根據最終的PointCloud,用Copy to Point節點做植被的Instance化
面板制作
首先要做的,是創建一個
Generate_Terrain_Entities的SOP節點,並且HDA的參數面板和Input/Ouput,這里先創建一個SOP節點,

參考FC5,創建一個類似的
Generate_Terrain_Entities的參數面板和Input,Output的輸出。

參數面板就和FC5文檔里介紹的一樣,具體做法就不多做敘述了,稍微有些Houdini經驗的美術都可以實現。

參考FC5把Input Laber 設置為2個,Output為3個,Input Output接續的數據在下圖有注釋。這樣把每個Speices鏈接鏈接在一起,具體如何起作用的在后文會有介紹。

復制完參數面板后,就是要實現根據參數來生成植被的Point Cloud信息的功能了,在之前管線里已經提到過,Point Cloud是使用Scatter節點,基於Heightfiled Mask的信息來生成的。接下來的目標就是如何根據植被系統的設置,正確的生成所對應的Mask。

確定生成區域
FC5的植被系統的生成區域來源主要是兩部分,一個是基於地形數據生成的各種Mask數據,例如AO,Flow,Slope,這些Mask通常確定植被會生長在哪些區域,

另外一種就是直接導入的2D數據,比如場景美術手繪的區域,以及一些在引擎里通過其他的過程化工具生成內容,比如街道,水塘的Mask,保證這些區域不會有植被放置。

把這不同Mask的組合根據規則和面板參數做數學組合,就得出最終的生成區域結果,這里簡單的介紹下如何使用VEX腳本結合Houdini的節點來實現功能。
首先是
AO,Flow,Slope,Direction(Sun or Wind)等Terrain Abiotic Data的生成,這些大部分可以用Houdini自帶的節點來生成

AO的生成,這里使用官方論壇上的一個OpenCL加速的heigtfiled AO節點,鏈接地址:
https://www.sidefx.com/forum/topic/54318/?page=1#post-243847

Altitude可以直接讀取height信息,但因為一些特殊的緣故,height的最低值並不一定為0,這里使用了一個Python節點,調用terraintoolutils.computeInputRange的函數來獲得height的范圍

這里增加一個altitude的Attribute的Ramp,用來獲取制定范圍內的高度信息

在
Generate_Terrain_Entities內部,在名為Mask的SubNetwork里主要做這些各種Mask的處理工作

這個示例Vex代碼里,迭代每一個Attribute的Ramp的Mask,然后合並到一起。為了簡化有些功能沒實現到Vex里,比如每個Attribute的Toggle開關和Power值的判斷,不同的Attirbute,例如Altitued還要做一些特殊處理等等。另外FC5可以支持多組Combined Data后的Data Group再做二次Combine。最終會是雙重循環的形式。

下圖的效果就是只有一個
Altitude(Height) Attribute的效果。

接着,在單獨加入一個Slope的Attribute的效果


最后得到兩個Attribute合並的效果。

這樣,houdini的生成區域的基本功能就完成了,后面就可以參考FC5,基於flow,direction等信息,制作出不同的植被生成區域的pattern

除此之外,FC5中還有一些用過程化工具生成mask要做為exclusion區域來使用,

比如這里把生成water的區域,作為
exclusion mask。

把exclusion mask作用到Alittude Attribute上,


就得到了
exclusion后的結果。

除此之外還有Noise,FC5的Noise的Size是受地形法線影響的,這根據Volume中height的位置,來取得height mesh里對應的Point的Normal,根據Normal的Y值來控制生成Noise的Size。

這樣,不同坡度的噪聲大小也不同。下圖就是water和altitude attribute以及noise共通作用的結果。

最后得到的Mask,就是對應的植被生成區域。接下來就要根據Mask,來生成植被的Scatter Point Cloud了。
生成Point Cloud
基於HeightFiled Mask來生成Point Cloud,通常使用HeightField Scatter就可以實現,

而FC5的植被系統里,還是要考慮植被的Size和Age參數,來確定最終的Point Cloud,這里使用下面兩個Attribute的Data Group來作為植被的生成信息

下圖就是得到的Viability的信息。

接下來,需要把V
iability Mask用SDF的方式轉為Age的mask

通過convertvolume和isooffset節點,用SDF方式重新生成Age Mask


接下來,通過Density面板,來配置密度,然后把Density寫入到HeightFiled的Mask里(也可以自己新建一個volume來保存)。而通過Density Ramp來控制不同Size植被的密度值,也就是Age(Mask)越小的外圍的小樹,密度越高,而Age(Mask)比較大的樹林中心的大樹,密度會比較小。

把Density值作為Density Attriube傳入到Scatter節點,同時輸出Point的Radius屬性。


這樣就得到了初步的Point Cloud,以及對應Point的Size,Pscale的信息。

然后,通過Size面板,設定不同等級的植被的具體大小。

以及對應的植被的顏色值。

就得到了帶有具體Color和Transform信息的Point Cloud.

再通過Copy to Point節點,用Debug Tree進行測試,這樣就得到了一種植被的Scatter結果。可以看到Age信息外圍顏色較淺的樹木密度相對較大,尺寸也較小,而Age信息內部的顏色較深的樹木則尺寸比較大,散布的也相對稀疏一些。

這樣,一種植被的生成功能已經初步完成,但生態系統里,還是要考慮多種植被的共通生長的競爭關系。以及同一種植被之間的競爭關系。這就需要實現FC5里通過對
Viability Radius的判斷來選擇Species的功能。
根據Viability選擇Species
FC5使用的方法,是根據
Viability Radius和Viability強度,來確定一個范圍內生成哪種植被。

這個實現也比較簡單,先獲取一個Point Radius范圍內的全部Point,把Viability相對較小的剔除掉就可以了。

這樣,在之前的演示的植被效果下面,再增加一個HDA節點。生成Species B

Species B的生成信息如下。


這里
Species B的Viability值比
Species A要高

這樣,
Species B和Species A混合在一起后,Species B會把Viability Radius里的Species A剔除掉

增加密度后,2種植被的布置效果。

最后像FC5這樣,把地貌的生態環境中的每種特定位置的植被用HDA文件一一描述再串聯起來,就可以構成區域復雜的植被體系了。

總結
這樣,就初步實現了FC5的
Generate Terrain Entities的基礎功能,但欠缺的地方還是很多的。
- Density,Size,Age等參數使用以及規則上,需要去對應最終的游戲世界的尺寸做修改。
- 如何更優雅的與UE4的FoliageSystem結合,需要再Houdini Engine里做進一步的擴展
- 算法上的調試,優化,也需要基於具體的制作示例來進行
- 像Rotation,TerrainData的輸出,在之前幾節有過介紹,在后文與UE4的整合里也會有進一步的改進。
在下一節里,在介紹如何使用
Generate Terrain Entitie在UE4里制作效果的同時,進一步的優化和改進
功能。