All Houdini

Houdini PDG – Section 3

 
 

  1. 基础知识

 
 

目前主流的过程化生成工具都是两种思路,一种基于Node,另一种基于Layer。后者最大的好处在于可以快速上手,而且有一个所见即所得的编辑逻辑,例如PhotoshopSubstance Painter都是这样。而基于Node的工具则需要使用者具有很清晰的逻辑,知道自己用这个节点要干什么,但这同时也大大便利了后期的修改和简化,通过修改每个节点的参数即可达到不同的效果。目前的Substance DesignerHoudiniblender都是基于Node的思路。

 
 

举个例子,在这篇文章中我们制作一个地形demo按照这样的顺序:

 
 

 
 

每个部分都由Houdini的数个节点组成,这些节点都有具体的参数来负责具体的功能,可以很方便的修改得到最终效果。同时,PDG模块可以将这些HDA模块统一在一个HDA下管理,分别控制不同的步骤,非常方便。

 
 

但是这并不代表基于Node就是好的,例如上面的layout绘制,比起根据节点一个个去计算,直接创建Editable Node去在引擎中刷地形是最快最方便的。

 
 

另外推荐一下官网上的Houdini Masterclass(可能要科学上网),详细的讲了H17Terrian的制作步骤

https://vimeo.com/296028795

 
 

 
 

 
 

 
 

 
 

首先建两个几何节点:

然后包装一下,shift+c打组,对组合设置Create Digital Asset,同样的全部参数先默认隐藏,这些操作同前一个教程。

 
 

然后我们先来实现painting这个节点。

首先建立一个Grid节点,然后设置一下参数:

SizeY的值与SizeX完全一致。

然后将这个参数加入到对外展示的参数列表,并修改设置一下参数。

这时候Size这一栏会展现出这样:

同样的做法使用在Rows,Columns这两设置项,最后效果如下:

 
 

之后为我们的笔刷工具创建两个属性,densityscale,一个决定密度分布,一个决定绘制大小。并使用random节点对scale做一个小范围的随机(当然也可以直接用rand函数),笔刷则用edit节点实现

 
 

因此首先建立一个attributecreate节点,加两个参数。

 
 

然后加入edit节点,设定我们的编辑节点是这个节点:

 
 

另一侧,创建tube几何体作为我们的山体,并设定基本参数:

 
 

我们用copytopoint节点将这个tube替换掉上面scatter后的grid,制造出山体的layout分布:

 
 

调整一下tube和scatter的参数即可得到类似山体的效果。

 
 

然后设置一下对外的参数

 
 

最后合并一下输出网格,生成的山脉和原始的地形。

建立merge节点,然后创建object merge节点,object merge节点就是获取原来的地形grid用的,我们主要设置里面的object参数来获取地形grid。

 
 

还要设置一个数处节点:

 
 

这时候输出的山脉都是一样大的,我们来点随机使得山脉看上去更自然。

因此我们插入一个attribwrange节点,一个attribrandomize节点

attribrandomize要设定random哪个参数

attribwrangle用来传递scale参数,里面要设定传递,f代表的是float转换

 
 

最终效果:

 
 

然后我们在Unity里面来试用一下,直接拷贝到unity工程里面:(这边不要忘记了Editable Node设置为painter,前面开始的时候有讲到)

为能使用笔刷工具,需要点选Enable Editable Node Tools

然后就会有笔刷菜单出现

注意笔刷的意义是,刷权重。比如这边刷的是scale这个parameter的值是0的权重,如果我们全部刷红,这个时候点击fill来执行houdini的逻辑,你会发现产生的都是小scale的山峰。

反之我们将权重刷为1.

效果就是这样的,刷权重scale为1的地方,明显生成的比较大。

 
 

(吐槽一句这个笔刷超级反人类的,而且不!支!持!撤!回!)

 
 

这边还需要增加的一个功能就是导出生成好的这个mesh,因此要对原来的hda文件再做修改,添加些参数。

Exporter部分的做法:直接用了一个Object Merge取得几何体,然后用ROP节点输出到文件夹下。注意路径一定要用相对路径

然后参数添加到对外列表:

这样Unity参数列表里面就可以导出文件了。

 
 

 
 

 
 

上面绘制的只是一个大致的分布,这种效果肯定是无法放到游戏里的,而且纯粹的几何体也无法使用Houdini的各种heightfield工具,因此我们新建一个subnet来转换它为heightfiled文件,并对其初步处理。

 
 

这里首先创建top节点集合。和前面的作法类似,创建topnet,null两个节点后,shift+c打组,然后对组对象create digital asset创建对外窗口。

内部:

 
 

这边要注意的是,使用Topnet节点的时候,要设置正确的working directory,这个不对就没效果:

 
 

然后创建一个filepatten节点,这是输入网格文件的节点,我们需要暴露给unity来联动,因此做如下设置:篮筐里面表示的是默认值,这边要改置空,当然不改也没太大影响。

 
 

设定完,我们就可以用上面Unity导出的网格文件.bgeo来cook做测试。

里面就是导入文件,然后处理成高度图的逻辑:

 
 

 
 

 
 

 
 

 
 

我们来看HDA Processor节点的设置,top节点是建立在sop流程之上的,因此我们首先需要建立SOP空节点如下,并且这是这个subset node为create digital asset:

在参数方面我们需要做如下调整:

也就是说这个节点需要一个输入,不需要输出。因此我们需要为这个文件准备输入如下:增加一个文件节点,注意给文件节点的值。

 
 

Ip_project_terrain节点里面就可以用来实现高度图的处理;
建立一个heightfield节点,然后设置一些参数:

 
 

加入heightfield_project节点,得到的就是高度图了:

然后加入blur,distort,使用下面这个节点,效果就出来了,参数自己调整:

 
 

进一步优化和加节点如下:

 
 

至此SOP流程做完了,我们回头再来处理TOPnet。

Topnet流程里面直接导入sop那边的制作过程:

然后还需要设置一下HAD Processor的输入输出参数:

 
 

这样就可以Cook这个Topnet节点了。

这边还需要再强调一下,Topnet节点可以看作是houdini内部的并行解决方案,不影响原来的节点制作流。因此一般的做法就是先按照原来的SOP完成内容的实现,然后使用Topnet节点包装。

 
 

然后是地形侵蚀效果

 
 

如果是初次接触Houdini,可能对erode节点不熟悉,Houdini的侵蚀效果是根据下方的time line来推进模拟的,这里我们拉动下方的动画条来看看模拟之后的效果

 
 

节点图:

 
 

Time-Shift节点来控制侵蚀效果,使用maskclear清除掉mask,这里为了显得不那么程序化,利用distort by noise做一些变形,最后还是用一个NULL节点标记输出

 
 

效果:

 
 

然后将上面的过程shift+c打组成subset,命名再create digital asset,然后再释放出下列的参数:(这一步做法如同上面的讲过很多次的做法一样,不再赘述),最后得到这个ip_erode_terrain这个节点组。

然后对于输入输出的参数也要做修改:

 
 

然后就是在topnet里面来使用上面的这个处理过程,这边的设置也都是一样的,创建一个hdaprocessor节点,然后启用前面的这段设置。

 
 

这边要重要的一步,这一步保证Topnet执行可以在Unity里面成功:HDA作用路径要改成如下

 
 

下面我们将上面的生成结果到unity里面试用一下,这时候我们需要修改一下ip_level_creation_top这个节点暴露的参数,首先是地形projection相关的:

然后是侵蚀相关的:

 
 

最后保存这个节点生成的hda,再将生成的结果导入到unity里面,效果如下,注意右边的layout里面需要导入的就是第一步生成的terrain_layout存储的几何位置。

 
 

然后启用topnet功能开始生成实例:

 
 

这边还需要注意的是地形的尺寸貌似只能是2的n次方+1,其他尺寸会有问题。

同时这个尺寸最好是和前面的terrain_layout的结果一致,不一致就会有各种各样的问题。

 
 

Unity内效果展示:(尺寸1025)

Unity内效果展示:(尺寸2049)【尺寸不对应,外部无数据导致的】

【如果不是2的n次方+1大小,直接生成一张白的。】

 
 

 
 

 
 

 
 

 
 

下一步就是处理纹理:

 
 

 
 

 
 

选中View窗口按D,会出现如下菜单,你可以调整一下houdini展示窗口的一些渲染参数:

 
 

三层maskbyfeature,具体参数可以自己设,有些关键的差异见下面图示:

 
 

最终的几点关系图,这里包含三层copylayer,每一层我们可以在destination里面标记一下这一层表示的类型,比如这里可以写上base, cliffs, grass

 
 

下一步就是创建unity里面可以设置的贴图参数类型,

参数的命名和类型需要严格按照Houdini Heightfields to Unity Terrain中的标准

https://www.sidefx.com/docs/unity/_attributes.html#AttributesInput_Heightfields

 
 

比如我们这边想要的设置是diffuse,用到的是红框里的那条

那么houdini里面的设置就如下,要一一对应。

 
 

用上面的方式创建三个节点,其名字分别为base, cliff, grass,然后每个节点都包含两个参数,设置如下:

 
 

最终的节点流程:

 
 

然后shift+c打组输出,然后建立Digital Asset如下,注意暴露的参数:

 
 

 
 

 
 

下面就是修改topnet节点到Unity里面使用:

 
 

改完通过Cook,保存节点然后就可以在Unity里面使用了。

Unity中更新我们的top hda,可以看到多了texturing属性,Path就是我们贴图的相对路径

 
 

关于这个路径实在是挺坑的,我这里解决方案就是把贴图放在和Scenes同一级的Resources文件夹下,然后把这个文件夹下的参数作为相对路径传入,注意图片文件的后缀名也要去掉。例如这样:

 
 

但是即使这样还是显示不出来贴图,我们需要在原来的流程里面去屏蔽掉一些参数设置:

如下位置加入这个节点,然后Group里面选择除了我们需要设置路径的三个变量,以及height,四个值以外的所有都选上,表示屏蔽这些参数。

 
 

这边还需要注意的问题就是上面的取 `@pda_output` 这个值的问题,我没有搜到相关的内容,但是貌似这个指的是缓存里面的模型数据。这个非常奇怪的是,当你重新开启houdini的时候,获取这个值一般都是不对的,因此我这里推荐不是用这个值,上面涉及到的流程其实是可以串联的,我这边使用了如下的Sop流程,没有问题:

 
 

 
 

下面就是在Unity里面使用,这边我即使是重新从头到尾做了一遍,还是没有解决贴图贴不上去的问题,因此暂时搁置。

Unity里面我做的效果如下:

 
 

这边就尝试不用PDG的情况下怎么来使用,首先尝试在Unity里面,一个一个节点拖入,结果还是不对的,错就错在贴图这一步。

这边挂起!!!

 
 

然后我们来看地形分块

 
 

同样的首先建立 SOP 节点,并 create digital asset。

设置的参数如图所示

 
 

然后在top节点内部同样的增加一个hdaprocessor节点来处理切分这个事情。

对应的设置如下,首先关联到对应的SOP节点,然后设置整个top节点的对外参数,然后比较重要的一步就是,设置这个hdaprocessor执行次数,因为是对原来的一块切成很多块,因此这个hdaprocessor要切多少块就要执行多少次。

注意下面的迭代次数,copy的参数是上面的图里面的红色框表示的是暴露参数。

另一个选项卡:

这样你会发现这个节点要执行16次,任意两效果如右图所示。

 
 

Unity里面的输出效果: