【blender从雕刻到摆烂】初见几何节点程序化生成(Procedural Content Generation)-城市场景

上次写的照片摆烂系列推送量和阅读量的比例还挺吓人,没想到大伙学建模的热情这么高涨。
后续也会继续做人柱力建模系列,但是靠人力来建模终究是有极限的。
“我不雕刻啦jojo——”

这次主要跟着julin佬的教程学习程序化生成城市场景。
但是我个人是计科科班,在逻辑上可能会相对有经验一些,如果是美术出身的朋友做pcg可能会相对难上手一些,但其实逻辑上来说难度也不是很大,重点在于想通。

第一次写这么长的文章,做了一半的复现learn-opengl的pbr环节要后推了。。。。

1.最终效果演示

首先是先放做好的效果。
最后来说参数其实不太多,我也没有百分百按着教程完全实现,就是到各取所需的完成度吧。
在这里插入图片描述
当时刚刚入门学习完全初见做的初版demo,简单的随机建筑生成
在这里插入图片描述
以下是完成版
拉动对应参数实现地块/建筑随机生成
在这里插入图片描述
实现地块尺寸变化的随机生成,我的老本子带不动太多地块带来的高面数,就最多拉到4*4意思下。(40系卡和13900hx在路上了!!)
在这里插入图片描述
实现楼高的随机变化,随机拉高/降低
在这里插入图片描述
实现建筑密度变化
在这里插入图片描述

2.需要小注意的两点

2.1.分割线不显示问题

看到这里的时候我还以为我的blender3.4都是盗版的,直接切到编辑模式发现居然还是只显示原本的立方体。
在这里插入图片描述
但我一看面数上是对的,感觉应该还是渲染的设置上出了问题。
在这里插入图片描述

在这里插入图片描述
直接到渲染设置里找,留意这一项。
在这里插入图片描述
打开即可正常看到分割线。
在这里插入图片描述

2.2.跨工程的资源导入

俺们长期玩unity的朋友可能对unity project那种文件式管理比较熟悉,但是blender这边的工程全部都打包成了.blend文件。
一开始想导入下教程里做好的材质球,百度了半天也没能找到解法,还得是谷歌。
跨工程的资源导入主要是在“文件”-“追加”栏内
在这里插入图片描述
选择对应的工程文件,文档管理的方式跟unity也比较接近,进入对应的文件夹内导入需要的资源即可。
在这里插入图片描述

3.思路整理

思路如下(误)
在这里插入图片描述
不开玩笑不开玩笑,像这种图形化编程往往都会变成一大坨难以进行整理和维护的屎山(这个只是主干代码,不包括我自己造的轮子节点等),所以还是需要多梳理一下大概的实现思路。

4.主干思路

就主干思路来说,还是比较简单的,整体来说就是通过相关参数划分好地块后,通过概率再划分出建筑集合和绿地集合,再各自进行重划分,生成对应的建筑/绿地模型。当然我们pcg为了节省工程量,往往是做好了组件来拼东西,后续也会提到怎么使用组件来拼建筑的流程。
第一步我们首先根据输入参数来做整体地块的划分,我们会根据地块大小,划分出x*y的基本地块数。
第二步中我们主要做了相关的随机切分的轮子,实现不同等级和次数的随机切分,并再次把地块随机分成两部分(两个面的集合)。一部分用于做建筑,另一部分用于做绿地。

在这里插入图片描述

4.1地块划分

那么首先我们通过给出x,y两个方向的地块尺寸和顶点数,通过栅格节点创建对应的地块方格。然后通过拆分边节点实现边拆分,把整个面根据边拆分成一系列独立的面。通过随机选择一系列的面并进行二次分割,最终输出分割好的地块。
在这里插入图片描述

在这里插入图片描述
第一次拆分面的效果(未作中间分割)
在这里插入图片描述
划分好的地面效果(完全划分好)
在这里插入图片描述

4.1.1 特定地块的随机划分功能实现

做程序化生成基本上无可避免地会出现需要自己做轮子的情况,在人工建模中很简单的一些操作,都需要相对复杂一些的逻辑才能够实现。这里的地块划分就是这样,原本一手ctrl r就能完成的居中划分,这里硬是折腾了一轮,非常的让人畅快。这里简单讲一下大概的流程:
这里主要是需要实现一个基于x,y方向上的最长边来做划分的功能。所以需要对x,y方向上的顶点进行相减并投影,从而获得对应的长度。由于pcg里面没办法直接通过节点来做ctrl r来做任意指定方向的中间切割,所以这里得自己造轮子。
在这里插入图片描述
该功能的节点连接的情况如下,左下最繁杂的部分其实是用来求解x,y轴的投影长度和比较的。由于节点展示实在是太不直观,而且连线连的也相对杂乱,重画流程图也相当于重新整理了思路,后续开始就不过多展示图形化编程的局部细节了。
在这里插入图片描述

几何数据输入(面)
在这里插入图片描述
因为这里主要都是正方形,所以是随机选择x,y轴进行切分,切分后进行缩放
在这里插入图片描述
对所有面复制后,进行反方向的变换。注意这边我们通过副本编号的选择,来选定特定批次的几何数据副本。
在这里插入图片描述
在这里插入图片描述
最终切分好的地块效果如下
在这里插入图片描述

4.2 分离建筑地块与绿化地块

在初步划分的基础上,我们主要是对地块先缩放然后再进行了二次三次的划分,并进行缩放。注意这里缩放是用到了一个类似于内插面的等距缩放的功能,跟直接进行缩放是有所区别的。
在这里插入图片描述
首先我们还是基于建筑密度的参数,随机分离建筑地块和绿化地块,并对两种地块都进行缩小和二次的划分。注意这里缩小后只是建筑和绿化类的地块,在这一类地块下还有马路路面的地块,马路地块也是基于4.1的方法输出的几何数据来做。
对于建筑地块,我们这里根据面积分离大中小地块,后续大中小地块会用于生成不同类型的建筑。
对于绿化地块,我们只分成大地块和次大地块,最大地块只用于生成操场和球场,次大地块则用于生成树木。
这里绿化地块和建筑地块在生成对应的建筑元素前都需要进行复制,一份用于赋予底座材质(草地,砖头地),另一份用于生成对应的元素。
在这里插入图片描述
节点情况总览
在这里插入图片描述

生成了树和地块之后的效果。
在这里插入图片描述

4.2.1 xy轴等距缩放的实现

等距缩放的原理很简单,主要是获取x,y边的长度,根据缩放的距离d求解对应轴的缩放系数,根据系数进行两次定向缩放即可。
常规缩放和等距缩放的效果对比(注意这里直接操作其实是走的内插面的流程)
在这里插入图片描述
获取x,y轴长度。注意这里没有输入,是因为几何节点在逻辑上与编程相似,但是一定程度上又有差别。我个人理解,这里通过边的顶点获取的是当前几何数据全部边的顶点数据,但是我们实际上操作的只是其中部分集合体数据。所以说一部分边的顶点数据虽然读到了,但是不会被使用,我们就当只有我们需要的几何数据的边顶点会被读取即可。
在这里插入图片描述
执行缩放的部分,主要是通过缩放距离d和xy的长度相减再相除获得缩放系数,然后通过两个缩放元素节点进行调整。逻辑比较简单。
在这里插入图片描述

4.3 生成建筑

生成建筑的主体思路比较简单,但是细节上需要调整的东西会比较多。主要是通过复制不同份数的楼面地块,然后根据层高进行变换,最后通过在每条边上平均布置相应的组件,实现每层楼的结构生成。在有些时候我们会做一楼结构和楼上结构的区分,以及楼顶结构的区分,大家可以通过副本编号的选择来处理相应的问题。
在这里插入图片描述
其实建筑的生成逻辑已经比较复杂了,而且不同建筑类型还需要定制化的调整,可读性和可维护性已经极其的拉跨。下图是节点效果展示。
在这里插入图片描述

复制生成楼面副本数据并实现变换
在这里插入图片描述
获取边数据
在这里插入图片描述
网格数据转换为曲线数据,实现重采样
在这里插入图片描述
重采样后数据转换为网格数据,再转化为点数据
在这里插入图片描述
实例化于点上(注意这里省略了麻烦和繁琐的缩放调整环节,只展示效果),暂时没有楼顶数据和其他装饰组件的几何数据
在这里插入图片描述
完成楼顶组件生成和全部装饰组件生成的样子
在这里插入图片描述

4.3.1 获取面法线

我们的建筑组件在建模好之后都是只朝着一个方向的,这里需要获取建筑四个面不同的法线,从而实现正确地旋转不同组件的朝向,获得正确的效果。
这里主要通过向z方向挤出网格,把处于xy平面的边挤出成四个面,通过编号采样获取各个面的法线数据,通过对其y方向生成对应的旋转向量,输出到实例化于点节点,实现组件的正确旋转。
在这里插入图片描述
挤出边的效果
在这里插入图片描述
预先做好的组件(y轴朝向)
在这里插入图片描述
针对不同的建筑,我们的生成逻辑会有所区别。
在这里插入图片描述
高层建筑生成
在这里插入图片描述

基本上大体的思路就这样,路面的生成思路实际上也差不多。由于在写文章的过程中,我的新电脑也到了,这次可以畅快展示更大地块尺寸的随机生成了!
在这里插入图片描述

5.后记

感觉blender的几何节点生成似乎比较偏向于底层原理的应用,偶尔也看过几眼houdini的pcg节点,好像看起来特别简洁的样子,后续希望能够继续学习blender几何节点的生成,也想跟进着多琢磨琢磨houdini的pcg流程。

猜你喜欢

转载自blog.csdn.net/misaka12807/article/details/129453275