B站制作过程展示: Houdini To UE4 程序化地形生成制作过程与效果展示
Github Houdini与HDA源文件:Houdini-PCG-Environment-Generator
目录
一、简单介绍
二、制作步骤
2.1 Houdini制作步骤
2.1.1 地形创建
2.1.2 层级划分
2.1.3 点云生成
2.2 UE4制作步骤
2.2.1 地形材质
2.2.2 点云模型替换
2.2.3 光源调整
2.2.4 内置的程序化植物生成器测试
一直以来对于开放世界的程序化生成比较感兴趣,各种原因选择了程序化野外山谷作为第一个研究目标。
实现的效果还算达到预期,但是性能还是不满意,修改参数后需要计算一些时间,可能是因为用了Erode计算侵蚀的原因吧。
后续仍需要不少优化,也希望大佬能指导指导,暂想通过分Tile,重构Houdini与UE4的基础管线方式提升,具体参考自该技术大佬分享。
这里仅将最终的制作思路作讲解,期间零碎的测试不再赘述。
通过学习与研究,我决定采用擅长制作程序化地形的Height Field节点,在该领域花费了较多的时间,首先创建一个默认大小的Height Field高度图区域,大小刚好是题目要求的1k x 1k。Grid Spacing网格上两点之间的距离,相当于这块高度图的分辨率大小,设置为2。
使用Height Field Noise节点对高度值添加噪声模拟地形,我将噪声振幅、大小与模式参数暴露在了HAD中,使得在UE4中能够进行进一步调整。
为了使地形形状能够更加真实,我使用了Height Field Erode节点模拟自然中的雨水、风力侵蚀,这里需要通过时间轴模拟侵蚀随时间的变化,时间越久越耗费性能,我将帧数锁在了20帧左右,这样即使不小心移动了时间轴也不会对已经调整的效果产生影响,也避免了耗时的计算;紧接着通过Height Field Distort对地形进行扭曲,添加更多的细节,得到了不错的山地与平原轮廓;最后通过Transform节点对地形整体进行了适度的抬升,方便后续的高度蒙版值设置。
虽然创建好了地形,但我们需要让程序能够知道树木、草地或是石块应该放置在哪,或是地表的材质会根据地区的不同而有所变化。Houdini提供了一个强大的节点Height Field Mask By Feature,它能够根据一些参数的设置对当前地形进行分区。比如我通过坡度筛选,将20-80度的山地标记出来用于生成树木。
使用Height Field Blur模糊上方的蒙版,让过渡区域别那么锐化明显。
通过Height Field Copy Layer对当前创建的Mask区域进行重命名,这可以让我们在UE4地形材质中能够更容易的对各地形进行区分与关联。
我们将山地与平原区分开来,为之后UE4中设置不同的地形材质做准备。通过Mask By Height得到山脉部分,同时我也将该参数暴露了出去,当您高度超过上限时也可以自行调整。
这时我们通过Height Field Layer,将以上两种不同的蒙版选择Add模式进行叠加。同时你也可以根据情况,选择其他的合成方式。
通过类似的方式,我又制作了坡度较为平缓的地形蒙版,为一些石块的生成做准备。
叠加目前三种蒙版区域。
下面通过一个很特殊的节点Height Field Remap,将输出最大、最小值倒置的方法,我们得到了与之前蒙版相反的区域,以此来代表平原生成草地。
Height Field Scatter节点让我能够通过设置Mask Layer针对特定的蒙版区域进行随机撒点,通过覆盖率等参数的调整达到了我期望的效果,将Tag Name命名为tree,这样能够在Geometry Spreadsheet中看到这些参数的各种属性数据。
同时需要注意的是,对于树这种竖直生长的植物,我们需要去掉勾选Match Normals with Terrain是,这样才能够让树不沿着地形表面的法线生长。
与此同时,我想创建两种不同类型的树木,并能通过权重控制其生成是数量。因而通过attribcreate创建class与weight两个属性来标记,记得将Class修改为Primitive否则无效。
如果Box默认设置你会发现一半模型会在地底下,这是因为轴心位于Box中心,因而复制Size的Y值引用,在Center的Y值中粘贴引用并除以2,能够让Box 的轴心始终位于底部。
类似的方法,在Big Rock Layer蒙版下为石块进行撒点,使用一个球模型进行标记,最后在UE4中替换石块模型。
最后创建unreal_material属性用于关联UE4中的地形材质,这样导入HAD后会根据String中的路径自动对地形材质赋值。
该String通过如下方式获取,并在复制后删除掉/Game以前,LandscapeMaster以后的内容。
最后将所有节点封装成一个subnet用于导出HDA,通过菜单列表可管理该HAD文件。
通过拖拽节点中的变量到参数栏,即可绑定变量到HAD文件中,实现在UE4中实时对部分参数实时调整。这里通过文件夹进行了分类。
这是最后暴露出来的所有可修改的参数。
首先学习了官网的开放世界场景工具入门,了解了一些小技巧与开发的方法。
首先我选择制作已经关联好的地形材质,通过Quixel Bridge可以获取高逼真的地形扫描材质,并能直接导入UE4创建好材质,这里我选择了三种不同的地形材质,用于平原、山地以及石块蒙版区域,用来营造不同的地貌来增加真实度。将这三种地形材质创建为材质函数,然后新建LandscapeLayerBlend节点,将Houdini中的Layer名称与之对应,这样才能起到作用。
LandscapeGrassOutput结合LandscapeLayerSample可以为我们生成一些地表植被,这里必须保证LandscapeLayerSample中的名称与你想要在哪个Layer上生成的同名,否则草地生成不会生效。
然后通过Landscape Grass Type工具在它其中添加静态网格体,可以是草、花、灌木丛或是碎石,最后添加在上图中的LandscapeGrassOutput参数中。由于距离较远的地方草地会被剔除来优化性能,但为了美观我暂时修改了End Cull Distance来使平原能够显得富有生机一些。
效果如图(灯光后期后的效果),尝试了好多草模型,这个还是很满意的。
对于导入的树、石块的点云,之前在Houdini中是通过Box与Sphere模型代表的。现在我们可以在HDA中的Houdini Instanced Inputs中对其进行替换,并且你可以通过+号添加更多的插槽,供我们添加多种不同样式的静态网格体资源,这样能够更真实的模拟自然环境,石块添加也是如此。
通过HAD中的参数权重值Weight我可以对两种类型的树木进行撒点比例调节,比如我的场景中有松树和桦树两种树木,我想让松树多一点,于是将Weight Tree 1设置为0.7,Tree2设置为0.3。你也可以对一些覆盖率与大小随机区间进行调节。
添加了指数级高度雾,并开启了体积雾,让远处能够产生一些模糊感不至于那么的鲜艳。
添加大气雾前添加大气雾后
调整直射光、天空光源为可移动,实时预览光源调整结果,并对光的颜色、强度进行了微调(结合后期盒子)。同时也对天空球的云朵进行了调整。
后期盒子中禁用了自动曝光,调整到了合适的曝光强度。
对屏幕镜头饱和度与对比度适度的加强。
在开发过程中,我发现了UE4正在试验性的一个功能,也能够实现程序化搭建森林树木植被,同时支持很多参数的设置,比如是否对其表面法线、生成在多少坡度或高度区域、树木最大年龄、树木大小、碰撞半径等。也非常适合开放世界的创建,但题目要求使用Houdini生成模型点云,而且试验性功能不稳定,因而未使用该方法,下面是一开始我使用该工具简单的用本地资源创建的森林。
具体使用通过偏好器设置勾选Procerual Foliage即可开启,结合程序化植物生成器与植被类型即可快速模拟,生成森林。
下面是植被类型设置,我简单的调整了法线不对齐表面与撒点的程度。
这是程序化植物生成器的设置,草地使用的是Grass节点。
最后附上一张UE4可实时调节各参数的截图。