Houdini程序化道路生成嘗試

道路程序化生成,是我作為一個日常從事城市規(guī)劃(偶爾建筑設(shè)計)工作的社畜一直想在houdini上嘗試制作的PCG工具之一,最近也趁著業(yè)余研究了一下,將一些初步的成果跟大家分享。

學(xué)習(xí)與參考
知乎上關(guān)于油管houdini道路生成的文章,其實(shí)已經(jīng)有不少。在此先感謝?
楊超(https://www.zhihu.com/people/wantnon)和 大大凱(https://www.zhihu.com/people/Dkyle)兩位大佬的無私分享,是他們的文章給了我程序化工具制作的思路和靈感。
houdini路網(wǎng)
https://zhuanlan.zhihu.com/p/73570541
Houdini程序化道路系列
https://zhuanlan.zhihu.com/p/334788179
此外,SideFX官網(wǎng)上的教程,也提供過一些不錯的道路生成教程可供學(xué)習(xí):
https://www.sidefx.com/tutorials/complex-roads/
當(dāng)然還有去年很火的利用HoudiniEngine以及UE5高效配合制作的黑客帝國城市示例:
https://www.sidefx.com/community/unreal-engine-5/
????????上述的文章和教程都能夠快速高效地通過繪制的樣條線生成道路和相應(yīng)的交叉路口;或者通過指定封閉的區(qū)域作為城市的區(qū)域并且在內(nèi)部利用算法生成路網(wǎng),進(jìn)而生成大規(guī)模的城市道路系統(tǒng)。然而這些方法就結(jié)果而言,并不是特別的“正確”。具體而言,在道路交界口出對于地塊轉(zhuǎn)角的處理,多是通過Resample節(jié)點(diǎn)并且設(shè)置平滑或者類似的方法來形成道路交界段一側(cè)的曲線。這樣帶來的問題則是:
生成的道路交界口路面轉(zhuǎn)彎半徑會出現(xiàn)過小,實(shí)際上并不是一條合理的城市道路。
因此我希望自己在實(shí)踐的過程中能夠有一種既保證高效,同時也能注重城市道路規(guī)范的生成方法。

實(shí)現(xiàn)過程
1.準(zhǔn)備階段:輸入——路網(wǎng)繪制以及數(shù)據(jù)準(zhǔn)備
為了節(jié)省時間,這里沒有通過osm或者gis獲取真實(shí)道路數(shù)據(jù),而是在houdini種示意性地繪制了一套路網(wǎng)。路網(wǎng)設(shè)置了三個道路等級,每個道路等級通過attribute設(shè)置了相應(yīng)的目標(biāo)道路寬度。

同時,基于不同的道路等級可以去規(guī)定相應(yīng)的設(shè)計車速,進(jìn)而求出相應(yīng)的路緣石圓角半徑。
另外也可以通過查規(guī)范的方法,直接查表設(shè)置道路半徑。這里放出對應(yīng)的表格供參考。

2.處理階段:道路交界口判定
方法一:利用道路交界點(diǎn)匹配路網(wǎng)分段的方法
這個方法是我在閱讀黑客帝國城市示例的hip時候?qū)W到的,大致的思路是:先通過節(jié)點(diǎn)對整體的路網(wǎng)生成相交點(diǎn),通過對交點(diǎn)對所有路網(wǎng)段提取每個點(diǎn)所對應(yīng)的線段。

在一個比較規(guī)整的網(wǎng)格路網(wǎng)里,這個方法是比較有效的。通過這個方法能夠提取到每個交界點(diǎn)對應(yīng)的路段并對其進(jìn)行路面生成,最后生成合理的道路交界段。

但是,在更加復(fù)雜的路網(wǎng)系統(tǒng)里,這種方法有一定的缺陷,這種缺陷來自于匹配算法帶來的“短視性”,
簡單來說就是:上述方法不會知道除了拾取的道路段以外接下來的道路走向,在以下道路在交界處發(fā)生拐彎的情況下就會產(chǎn)生奇怪的結(jié)果:

方法二:大大凱大佬的方法
為了解決上述的“短視”,下面通過另一種算法來解決上述的問題。
利用巧妙的算法將相交路段提取出來,這個方法能夠無視每條路網(wǎng)樣條線中的頂點(diǎn),將一定范圍內(nèi)的線段拾取進(jìn)同一個“道路交界口”組中,方便后續(xù)的處理。

這樣也正好解決了上述方法一中的問題。(跪拜大佬!?。?/p>

將不同的道路交界口歸到不同的組之后,接下來就將他們拾取進(jìn)foreach loop中,進(jìn)行道路交界口網(wǎng)格生成的處理了。
3.生成階段1:道路交界口路面的生成
對每個成組的交界口路段,生成交界口路面的基本流程如下:
1.每條路網(wǎng)中心線依據(jù)設(shè)定好的道路寬度?width?生成基本的面,并且布爾成整體;
2.提取出道路的邊線,根據(jù)原來設(shè)定好的圓角半徑?rd_radius?進(jìn)行倒圓角,半徑值取兩條道路prim中所記錄的最大值;
3.提取圓角最末端的點(diǎn),分別對其求到道路中心線的垂足,并且比較其與道路交界中心點(diǎn)的距離,保留二者距離更遠(yuǎn)的點(diǎn);
4.根據(jù)步驟3中獲得的點(diǎn)繪制道路交界口的邊界線,與道路邊緣線一起進(jìn)行封面形成完整的道路交界口路面。




3.生成階段2:道路段生成
這一部分相對比較簡單,大致的思路是:
1.利用前面的道路網(wǎng)系統(tǒng)于前面生成的道路交界口網(wǎng)格,將道路網(wǎng)交界口以外的道路中心線提取出來。
2.對提取出來的道路端通過夾角的計算,找到需要進(jìn)行平滑處理的拐角。這里我會尋找交角大于15°的道路拐角進(jìn)行處理。
3.把這些拐角拎出來之后進(jìn)行一系列的平滑處理:通過resample減少頂點(diǎn)數(shù)量,生成nurbs曲線再重新轉(zhuǎn)化成細(xì)分的polyline。
接著依據(jù)不同道路等級的線以及對應(yīng)的道路寬度attribute,生成道路面。
并且通過固定的縮放系數(shù),設(shè)置道路面的UV。



最后將道路交界口和道路段一起輸出,路面的最基本的生成階段就完成了。

總結(jié)與后續(xù)計劃
目前只基本完成了道路網(wǎng)基本的路面生成,還有人行道、建筑地塊包括地塊內(nèi)部的路徑的生成還需要繼續(xù)制作。另外目前還有許多特殊的情況沒有考慮處理,在生成道路交界口面的時候還是會出現(xiàn)錯誤的結(jié)果。
接下來會對這個工具目前已知的bug進(jìn)行優(yōu)化,并且制作成HDA方便后續(xù)在UnrealEngine中使用。(應(yīng)該不會咕咕掉的吧...2333333)
謝謝大家看到這里,繼續(xù)研究去了:)
Houdini程序化道路生成嘗試的評論 (共 條)
