Blender 3.4 用几何节点程序化生成潘多拉地形

几何节点和Shader节点的不同
某个Shader 节点产生的数据可以自由地在不同节点间传递、组合、嵌套,这是因为shader节点中所有的数据本质上都是函数(对于任意的点M(x, y, z),都可以计算出任意数据在这一点的值 [ 在blender中,不存在的值 = 0 (如1/0 = ln 0 = 0) ] ,而这些函数都定义在整个三维实数域内。
但是,几何节点有明确的操作对象 -- 几何体,更确切地说,是几何体的每一个顶点。相信很多小伙伴都跟我一样,看到过这样的红色虚线。

警告出现的原因就是执行操作所引用的数据并不属于操作对象。就好比计算苹果下落轨迹,却引用了梨子的位置或香蕉的初速度。与shader对比,我们可以发现,几何节点的数据依托于几何体而存在:对于某个数据A,几何体的每个顶点都存储了一个A的值。如下:

Position属于attribute的一种。attribute节点提供了一个输入的端口。当某个attribute “B”被引用在Set Position节点末端时,Blender会逐一查看每个顶点存储的B值并以这个值为输入通过运算节点对这个顶点进行位置变换。
应用案例
在生成山峰时,可以计算山峰中心到被移动点A的距离作为自变量,接入一个减函数,将函数值作为点A在Z轴移动的值:

然后,对找到的函数值进行修饰,如加上随机函数值:

最后将组合后的函数值接入z轴偏移量:

在这个例子中,我们引用的几何体数据是点的位置信息(position input)。通过计算每个点到山峰中心的距离,我们获得了每个点在几何体变形成山峰后的基础高度;通过将点坐标接入噪波Noise和马氏分型Musgrave,我们获得了每个点在基础高度附近的随机偏移量。最后,将二者相加得到组合函数,并接入set position节点,目标几何体就真正变成了山峰的样子。
潘多拉地形构成

浮岛
浮岛的单体由棱角球icosphere经三步变形而来:

首先是下方倒置山峰:

其次是上方山峰:

最后是水平方向的噪波处理:

在得到单体浮岛后,在浮岛分布的区域生成随机点,并用instance on points节点将浮岛在这些点处生成:


山峰
山峰由网格grid变形而来。每个点的z轴坐标偏移如上文案例中所示。


藤蔓
藤蔓是比较复杂的部分,涉及到attribute的赋值和引用。
先在浮岛上取若干随机点作为藤蔓起点,再将每个点依法线Normal进行射线映射Raycast,终点即为藤蔓另一端点。将网格体直线Mesh Line作为Instance在每个点处生成,并根据Raycast结果校准长度。将随机点节点自带的rotation输出赋给instance的rotation,使网格线和Raycast的方向相同。网格线的细分程度越低,藤蔓曲线就越粗糙。

值得注意的是,此处的position输入最终在instance on point被应用。因此“Position”对应左下节点生成的随机点的坐标。
接下来使藤蔓弯曲:
定义两个新的Attribute“起点”和“终点”(注意要用Instance类型),分别存储每条藤蔓的起点和终点
Realize Instance将在不同点处生成的多个几何体合并成同一个几何体,但保留Instance类型的attribute并转为point类型
引用两个Attribute,用起点到藤蔓上一点的距离除以藤蔓长度作为自变量x(x在0到1之间),定义y = x * (x - 1) * k,将y作为该点z轴的偏移量,k即是下垂程度

最后,将藤蔓曲线变成真正具有粗细程度的网格体:

注意到存在部分竖直的藤蔓,这是为什么呢?
植被
在法线向量Z值大于0或小于0的区域分别生成随机点,并将不同植物作为instance分别应用在所有点处。

为了节省性能,我在此直接引用了简单建模的树木模型。我做过树木生成的节点组,但是仅仅单棵树木已经让blender有明显卡顿。倘若那个节点组进入这个场景成为树木的几何体,blender许是会崩溃,且我的电脑大抵是要陪葬的。

如果看的人多,我会再写一篇文章分享树和下垂藤蔓的全几何节点生成方式。背景的星球是我另外做的“菈妮群星”场景的资产,如果对此感兴趣的小伙伴多的话我也可以出一期相关的shader节点教程。
(本文中所有的 “值” 并不特指数字,而是包括blender所有能用的数据类型,如向量vector、值value、布尔bool、颜色Color等)
PS:发教程视频没人看,那就简单写个专栏分享一下自己的blender学习经验叭。