欢迎光临散文网 会员登陆 & 注册

Houdini程序化道路生成尝试

2023-02-23 13:57 作者:小LABION  | 我要投稿

道路程序化生成,是我作为一个日常从事城市规划(偶尔建筑设计)工作的社畜一直想在houdini上尝试制作的PCG工具之一,最近也趁着业余研究了一下,将一些初步的成果跟大家分享。

学习与参考

知乎上关于油管houdini道路生成的文章,其实已经有不少。在此先感谢 

杨超(https://www.zhihu.com/people/wantnon)和 大大凯(https://www.zhihu.com/people/Dkyle)两位大佬的无私分享,是他们的文章给了我程序化工具制作的思路和灵感。

houdini路网

https://zhuanlan.zhihu.com/p/73570541

Houdini程序化道路系列

https://zhuanlan.zhihu.com/p/334788179

此外,SideFX官网上的教程,也提供过一些不错的道路生成教程可供学习:

https://www.sidefx.com/tutorials/complex-roads/

当然还有去年很火的利用HoudiniEngine以及UE5高效配合制作的黑客帝国城市示例

https://www.sidefx.com/community/unreal-engine-5/


        上述的文章和教程都能够快速高效地通过绘制的样条线生成道路和相应的交叉路口;或者通过指定封闭的区域作为城市的区域并且在内部利用算法生成路网,进而生成大规模的城市道路系统。然而这些方法就结果而言,并不是特别的“正确”。具体而言,在道路交界口出对于地块转角的处理,多是通过Resample节点并且设置平滑或者类似的方法来形成道路交界段一侧的曲线。这样带来的问题则是:

生成的道路交界口路面转弯半径会出现过小,实际上并不是一条合理的城市道路

因此我希望自己在实践的过程中能够有一种既保证高效,同时也能注重城市道路规范的生成方法。

道路生成效果预览


实现过程

1.准备阶段:输入——路网绘制以及数据准备

为了节省时间,这里没有通过osm或者gis获取真实道路数据,而是在houdini种示意性地绘制了一套路网。路网设置了三个道路等级,每个道路等级通过attribute设置了相应的目标道路宽度。

基本道路中心线网络,以及相对应的道路属性赋值

同时,基于不同的道路等级可以去规定相应的设计车速,进而求出相应的路缘石圆角半径。
另外也可以通过查规范的方法,直接查表设置道路半径。这里放出对应的表格供参考。


来源:《城市道路交叉口设计规程》-表4.3.2

2.处理阶段:道路交界口判定

方法一:利用道路交界点匹配路网分段的方法

这个方法是我在阅读黑客帝国城市示例的hip时候学到的,大致的思路是:先通过节点对整体的路网生成相交点,通过对交点对所有路网段提取每个点所对应的线段

在一个比较规整的网格路网里,这个方法是比较有效的。通过这个方法能够提取到每个交界点对应的路段并对其进行路面生成,最后生成合理的道路交界段。

但是,在更加复杂的路网系统里,这种方法有一定的缺陷,这种缺陷来自于匹配算法带来的“短视性”,
简单来说就是:上述方法不会知道除了拾取的道路段以外接下来的道路走向,在以下道路在交界处发生拐弯的情况下就会产生奇怪的结果:

实际正确的交界口应该是朝着红色箭头生成,而不是结果的灰色箭头方向

方法二:大大凯大佬的方法

为了解决上述的“短视”,下面通过另一种算法来解决上述的问题。

利用巧妙的算法将相交路段提取出来,这个方法能够无视每条路网样条线中的顶点,将一定范围内的线段拾取进同一个“道路交界口”组中,方便后续的处理。

这样也正好解决了上述方法一中的问题。(跪拜大佬!!)


将不同的道路交界口归到不同的组之后,接下来就将他们拾取进foreach loop中,进行道路交界口网格生成的处理了。

3.生成阶段1:道路交界口路面的生成

对每个成组的交界口路段,生成交界口路面的基本流程如下:

1.每条路网中心线依据设定好的道路宽度 width 生成基本的面,并且布尔成整体;

2.提取出道路的边线,根据原来设定好的圆角半径 rd_radius 进行倒圆角,半径值取两条道路prim中所记录的最大值;

3.提取圆角最末端的点,分别对其求到道路中心线的垂足,并且比较其与道路交界中心点的距离,保留二者距离更远的点;

4.根据步骤3中获得的点绘制道路交界口的边界线,与道路边缘线一起进行封面形成完整的道路交界口路面。

步骤1 绘制基本面
步骤2 圆角
步骤3 绘制边界
步骤4 成面

3.生成阶段2:道路段生成

这一部分相对比较简单,大致的思路是:

1.利用前面的道路网系统于前面生成的道路交界口网格,将道路网交界口以外的道路中心线提取出来。

2.对提取出来的道路端通过夹角的计算,找到需要进行平滑处理的拐角。这里我会寻找交角大于15°的道路拐角进行处理。

3.把这些拐角拎出来之后进行一系列的平滑处理:通过resample减少顶点数量,生成nurbs曲线再重新转化成细分的polyline。
接着依据不同道路等级的线以及对应的道路宽度attribute,生成道路面。
并且通过固定的缩放系数,设置道路面的UV。

获取路面段
转角平滑处理
成面

最后将道路交界口和道路段一起输出,路面的最基本的生成阶段就完成了。

总结与后续计划

目前只基本完成了道路网基本的路面生成,还有人行道、建筑地块包括地块内部的路径的生成还需要继续制作。另外目前还有许多特殊的情况没有考虑处理,在生成道路交界口面的时候还是会出现错误的结果。

接下来会对这个工具目前已知的bug进行优化,并且制作成HDA方便后续在UnrealEngine中使用。(应该不会咕咕掉的吧...2333333)

谢谢大家看到这里,继续研究去了:)


Houdini程序化道路生成尝试的评论 (共 条)

分享到微博请遵守国家法律