houdini engine for unity初探(一)
這陣子初步嘗試了一下houdini engine for unity。
感覺是:可用,但充滿了羈絆。
目前只做了 地形、道路、湖,而且遠不夠完善,僅以此例點滴經驗探討下houdini engine for unity的使用。
一,houdini engine的作用
houdini engine就是能讓使用者在遊戲引擎裡使用houdini的幾何計算功能。
若不用houdini engine,我們在houdini裡搭建場景,匯出模型、mask等資源,再匯入到遊戲引擎,這樣是可以的,但缺點是無法及時看到遊戲引擎中的效果。
若使用houdini engine,則是另一種流程:在houdini中製作hda,hda匯入遊戲引擎,在遊戲引擎中用hda搭建場景,並透過houdini engine呼叫houdini進行cook。這樣的好處是場景搭建過程直接在遊戲引擎中進行,所見即所得。提高迭代效率。
二,基本流程
1,在houdini中製作 地形hda, 道路hda, 湖hda。
2,將hda匯入unity,地形hda拖入場景。
3,將若干 道路hda 和 湖hda 掛接到 地形hda上(作為 地形hda 的輸入)。
然後就可以在unity裡調整curve或引數來改變 道路 和 湖 的形狀,同時對地形造成影響。
三,houdini engine存在的問題
1,功能不完善,資料較少,遇到問題只能自己去程式碼裡找,並亂改。
2,cook速度太慢,這是最大的問題。
例如調一下道路curve的控制點,要等五六秒鐘。而且,這還是隻有道路和湖且節點連得比較簡單的情況,可想而知,隨著功能/效果做細,速度只能越來越慢。
本來是想提高迭代效率的,這麼一搞反而慢了。
同一個功能,使用houdini/houdini engine cook和自己手寫編輯器相比,甚至會更慢。
怎麼會這樣,houdini不是有opencl加速嗎?
個人認為有如下兩方面原因:
1,houdini設計著重通用性,導致一些我們自己寫編輯器時很容易做到的最佳化,在houdini裡做不到。
比如說在地形上鋪路,讓道路將地形壓低(或抬高)這件事兒,由於道路通常只覆蓋一小部分地形,如果我們自己實現,肯定會對道路求包圍盒,然後只對包圍盒內的地形區域做處理。而houdini裡操作heightfield的節點,如heightfield project、heightfield mask by object、heightfield blur等,卻都是對整個heightfield進行處理。
2,遊戲引擎和houdini之間透過houdini engine交換資料的過程也比較耗時。
那乾脆不用houdini,直接手寫編輯器得了。
問題是有沒有那麼多時間和精力,而且有些複雜的計算幾何演算法,自己真的未必寫得出來,寫出來也未必夠魯棒。
四,解決辦法
1,基礎地形的生成過程不要放在地形hda裡
生成基礎地形,需要各種噪聲及erode,slump等操作,非常耗時,最快也要幾分鐘。這個過程如果直接放在地形hda裡,每cook一次就重新執行一遍根本不現實。考慮到基礎地形修改頻率較低,可單獨弄一個物件來生成基礎地形,將結果輸出為檔案,再用heightfield file節點引入到地形hda中。
houdini地形和匯出的高度圖(2048x2048)
2,houdini節點最佳化
用perfomance monitor可以檢視各節點的消耗,對高消耗的節點/subnet用其它方法代替。
3,編輯時降低地形解析度。
原始heightfield為2048x2048,在terrain hda中加一個heightfield resample節點控制解析度,編輯時將解析度降為1024x1024,減少cook時間,最終看效果時再調高。
4,廉價cook自動觸發,昂貴cook手動觸發
以鋪路為例,使用者拖動curve控制點,預設會觸發兩個cook,一個是道路cook,一個是地形cook(因為道路hda作為地形hda的輸入,houdini engine會正確處理這種依賴關係,當道路cook後自動觸發地形cook)。其中道路cook由於只是一些簡單幾何操作,速度很快。但地形cook由於涉及到一系列heightfield操作,比較耗時。那我們就讓它只進行道路cook,而不要進行地形cook。
這樣使用者可以實時看到路面變化,只是地形沒有跟著變,如果想看最終效果,手動點一下地形的cook。
其實只有影響到地形的操作才會比較慢,這樣的操作並不多,也就道路、河湖、地基這幾項,其餘如建築、植被等,都不會影響地形(建築放在地基上)。
至於如何實現“只cook道路,不cook地形”,本來我以為hda面板上的“cooking triggers downstream cooks”是幹這個的:
而且文件中也是這麼寫的(Houdini Engine for Unity: Houdini Assets):
但試了一下,貌似不起作用。
去論壇發了個帖子也沒人回覆:cooking triggers downstream cooks not working
最後只好去程式碼裡直接把地形的cook函式遮蔽了。dirty。
5,不用houdini/houdini engine。
一些難度不是很大的處理演算法,完全可以自己寫編輯器指令碼,反而效率更高。
補充:
有人可能會說用PDG提速,我沒細研究,但看了下indie pixel的影片,感覺一來比較複雜,不好維護,二來要想透過PDG加速,必須將任務拆分為可並行,對於地形處理而言,就是分塊(indie pixel的影片裡也這麼做的),但分塊會帶來很多限制,比方說heightfield blur、heightfield mask blur這類操作,在接縫處會產問題。如果我們要根據不同的操作,一會兒分塊,一會又合起來,分分合合之間,也是浪費不少效能。一個變通的方法是在設計上就避免在接縫處有東西,但這樣的話我即使不用PDG也可以透過每塊區域單獨一個hda來實現最佳化。。。
五,其它
1,一個比較有用的功能是在houdini中可以為hda指定 unity材質 和 c#指令碼(其實就是個detail屬性),到unity裡以後就自動掛上了。
2,heightfield到unity裡以後自動轉為unity terrain,heightfield的那些layer,其中height layer會作為terrain的高度資料,其餘layer則進入splatmap的通道,用於地形shader的紋理混合。