Houdini技术体系 基础管线 :Heightfiled与UE4的无缝导入以及对World Composition的支持
Posted TraceYang的空间
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Houdini技术体系 基础管线 :Heightfiled与UE4的无缝导入以及对World Composition的支持相关的知识,希望对你有一定的参考价值。
Authored by TraceYang
前言
传统的制作做比较真实大世界3D关卡地形时,通常的采用的方式是把HeightMap和SplatMap(Layer Mask)导入到引擎的地形系统里,生成Terrain LandScape的地形信息和地表材质的图层信息。再由美术在引擎编辑器做进一步的细化工作。而这些Map的生成,是使用WorldMachine(简称WM)软件来制作的。
![](https://image.cha138.com/20210605/c49b2201d3524f73b0a1c2c983b3f418.jpg)
图为Ghost Recon Wildlands前期使用WolrdMachine制作的地图
![](https://image.cha138.com/20210605/f459b7e900774fc18db8c667e504bcc7.jpg)
图 除了HeightMap之外,SplatMap也是要从World Machine中生成的
从WorldMachine中Bake出Map后,导入到UE4引擎里,这个教程wiki上比较多,就不多做描述了。
![](https://image.cha138.com/20210605/e2959f5420f84d6ea199d8ca012a0b52.jpg)
图 把Map导入到UE生成的Landscape
但是传统的WM机制通常会有以下几个问题
- WM里预览的地形生成效果跟DCC软件或游戏引擎相比并不美观,也不能像其他工具里直接由美术参与修改
- WM导入到引擎需要通过导出Heightmap再导入引擎,当地形比较大时,map生成和写入到硬盘的时间会超过10分钟,对美术迭代修改的成本非常大
- WM生成后到引擎后,关卡设计还需要在地形上进行二次开发,从而影响到地形和地表的Map,这时如果需要WM生成部分地形时,整个流程会变的非常混乱。
像Ubisoft在近年来的大世界项目,Ghost Recon Wildlands和FarCry5如里引入了Houdini Pipeline技术,GDCVault上都有介绍,具体的Heightfield替换WorldMachine的制作,会在地形篇提到,管线章节里就不多做叙述了。这里假设你已经用Houdini的HeightField制作了地形,接下来看下怎么能够快速的通过Houdini Engine快速的导入到游戏编辑器里。
Houdini HeightFiled 到UE4 Landscape的无缝生成
下图是Houdini HieghtFiled到UE4 Landscape的无缝生成的结果示例,不需要导入贴图,只需把HDA文件拖入到编辑器的Viewport,赋予预制作好的Landscape材质,就可以自动把HDA Cook成UE的landscape资源。 这里假定假定读者已经掌握Landscape Material和Landscape Layer的创建方法,就不多做叙述了。
![](https://image.cha138.com/20210605/73f88c9863544240956b3347fd5e8801.jpg)
![](https://image.cha138.com/20210605/852df981a6aa43ab9aa865e00e3c90da.jpg)
从Houdini Engine的机制图可以看到。我们就是通过HDA文件 Houdini HeightFiled的每一个volume的信息转入到UE4里,这里UE4 Houdini Engine Plugin已经实现了功能帮我们做转换
首先这里要要让HeightField的Size的设置和最终在UE4里Bake的Landscape Sizes一致。下图是UE官方建议的Landscape的配置。
![](https://image.cha138.com/20210605/7123d6cd916a426bb066b4d1d2dec42e.jpg)
HDA文件导入到场景后,这里可以看到Landscape 的Component的情况。
![](https://image.cha138.com/20210605/d155b9797b1940c281f8f7081ebc882a.jpg)
管线介绍部分不会对Heighfiled的制作做太多介绍,用Houdini生成地形信息,通常是用两种途径:
方法一:使用HeightField File节点加载一张已有的高度图来生成
![](https://image.cha138.com/20210605/e961dba85a8044caaca2a02b5f5f3855.jpg)
在HeightField File 节点里可以配置生成到UE4的Landscape的Size
![](https://image.cha138.com/20210605/85bb8f0964044b9283ab2e8d15d437d5.jpg)
而具体的对应的UE Landscape的Overall Resultion,可以使用Heightfiled Resample节点
![](https://image.cha138.com/20210605/76b9e2ed31f64740b8f954fe5f0b84f6.jpg)
而GridSpacing则对应的是他实际在UE4里的Overall Resultion
![](https://image.cha138.com/20210605/a67d1f48fafe494098701f01c9356514.jpg)
当Heighfiled的Grid Spacing比较大时,说明同样大小的地形,对应的更少的顶点,换算到UE里,就是比较小的Landscape Overall Resultion。 Overall Resultion越小,UE里Landscape生成后的顶点数也会更少一些。这样适合在移动终端用较少的资源做出相对比较大的场景。
![](https://image.cha138.com/20210605/5ae16e855348469e9e040a443195182b.jpg)
下面我做几组Height Field Size与UE Landscape Componment的对比,他们最终在UE里的Landscape szie都是8129x8129。只是细节有所不同。
![](https://image.cha138.com/20210605/4a6c2c0c49244ad1967a1f0b17205ba0.jpg)
![](https://image.cha138.com/20210605/23682ffc8d1744a9ab0095732fb83427.jpg)
![](https://image.cha138.com/20210605/f0dfad8433f343e6abcdf7812cae4c63.jpg)
业余学习中我们能把Houdini Engine作为一个黑盒,根据需求来做Size和Grid Spacing的组合来达到想要的目标配置,而真正项目工程里,还是建议由引擎程序根据项目来定制Hengine Engine的Cook Landscape的配置。这个我们在后续的定制更新和修改时也会提到。
方法二:使用Heightfiled节点从0开始生成:
![](https://image.cha138.com/20210605/5e554c7425de444a9532712c8fe54fd2.jpg)
创建这个节点时,就可以选择整个地图的尺寸,其中Size就是为导入到UE4后对应的大小,和方法一一样Grid Spacing来决定Overall Resultion。
![](https://image.cha138.com/20210605/d912360982fb4e209c89b3bbf01efc89.jpg)
其他的就跟方法一是一样的了。这样,就可以根据机器性能,在场景用较低的几何体生成出相对较大的场景。
Heightmap的导入解决了,然后就是HeightField Layer Mask与UE4 Landscape Material Layer的对应设置。
![](https://image.cha138.com/20210605/c11429ba5bd444cab1c7df71f3ad2461.jpg)
上图中HDA里HeightFiled的volume信息,height对应的就是HeightMap信息,这个Houdini Engine已经自动支持了,而其他的Layer Mask与UE的Landscape Material Layer,则可以通过命名来一一对应。
![](https://image.cha138.com/20210605/95ce8fd0085741afa5ebd8c52bcaf3a7.jpg)
这里我们让HeightField的Layer Name与UE的Landscape Layer Name保持一直。
![](https://image.cha138.com/20210605/7fbb4ba90bb642e0a2ada030100248ee.jpg)
左侧的Heithfiled Layer名称和右边UE的Landscape移植,就可以通过Houdini Engine,不导出中间的Map资源,这个过程相比WM的10几分钟要快很多,通常HDA的Cook只要10几秒。
具体的制作过程可以看附件的HDA事例,这里只介绍几个Houdini关键节点的使用。
![](https://image.cha138.com/20210605/ffcedd2ad598413ea80d2af4117c91f0.jpg)
![](https://image.cha138.com/20210605/7b9918a05e58461db1c3f64c7d1062d0.jpg)
HeightField Copy Layer的功能就是把你在Houdini里生成的Layer Mask重命名为你想在UE引擎里对应的Landscape Layer的名字。
这样,我们可以从HDA文件直接生成出带地形高度和地表图层信息的场景了。
![](https://image.cha138.com/20210605/87e09c3dde2c4be999971b0bd530bb93.jpg)
Houdini HeightFiled 对World Composition的支持
无缝大世界游戏场景开发中,一个Landscape不管是在多人协作开发,迭代,还是在Streaming的优化以及打包等,诸多方面都会有很多的不便,所以需要我们把一个大世界的Landscape‘Tile化’。比如一个8x8km的Landscpe可能会切成4x4或8x8的Tile。UE也提供了World Composition的功能。
![](https://image.cha138.com/20210605/db2f3952d5354133b76401ba52e7ab65.jpg)
传统WorldMachine里可以通过Tiled build生成出无缝的Tiled Heightmap和Mask,然后import到UE的Landscape里,这样其实也会增加bake时间,另外把UE4 Landscape的Mask导回给Houdini也是很痛苦的事情(很慢,需要非常大的系统内存)。
![](https://image.cha138.com/20210605/0859cd7828a749fbaaf9058a7d2d3ff0.jpg)
好在Houdini 16.5版本后,其实对这部分的支持也加强了,Houdini提供了一个heightfield tilesplit节点就可以做Tile化了,这里我切成了4x4个tile。
![](https://image.cha138.com/20210605/f932c73c99ff4b5abfe5958908c4d100.jpg)
![](https://image.cha138.com/20210605/6486f0dc13c944fa9331892705f6bfae.jpg)
再次把HDA加入场景Cook。就可以生成4x4=16个tile的Landscape了。
![](https://image.cha138.com/20210605/143a9bb22f804b668ac509a587c1e2fc.jpg)
但是这个用heightfield tilesplit的方法有他的缺陷,一个是会在tile上产生边缘产生接缝露空。
![](https://image.cha138.com/20210605/f5215a2cafe64d2bb4b917c6f7942d4e.jpg)
而且这种多个Landscape的方式,和UE4的World Composition机制也有冲突。也不能跨Tile来做地形编辑,其实并不是做无缝大世界地图的正确方法。其实World Composition还是一个整体Landscape,通过把LandscapeStreamingProxy分配到每个子关卡的方式,来进行的Tile分割。
这里提供一个不修改Houdini Engine也能快速的使用World Composition的比较笨的人力办法来解决。
首先,我们不使用splite节点,直接导入一整张地图进来,这样肯定是没有接缝的。
![](https://image.cha138.com/20210605/1f7819b09a4d48a08ddc9e8dc9299c79.jpg)
然后类似创建出对应个子关卡,这里假定我们生成2x2的。
![](https://image.cha138.com/20210605/4679ef17375f47f08344ce04c2e4e91e.jpg)
接下来,我们选择对应的sublevel,用Move to level工具,就可以把对应的Landscape Component移动到指定的Level里,生成一个LandscapeStreamingProxy
![](https://image.cha138.com/20210605/54086728f4354dd7bc797b33a3f4e204.jpg)
![](https://image.cha138.com/20210605/0dc349b348214722836fa62d0fe3fb4e.jpg)
最后给每个Level生成对应的LandscapeStreamingProxy。进行保存。
![](https://image.cha138.com/20210605/119f558e09de45d5a2029ed48a9c69ff.jpg)
然后删除掉原始的Landscape,删除之前创建的SubLevel,
![](https://image.cha138.com/20210605/c472d4c5c292498590f8acb92220592c.jpg)
勾选Enable World Composition。
![](https://image.cha138.com/20210605/78a66d72e02848f6877aa7a03b9b3e8a.jpg)
UE4就会自动的帮你加载之前的sublevel,生成World Composition。
![](https://image.cha138.com/20210605/f45f3b7ec13e4ced9401b3101ba0c4f2.jpg)
这样就和UE4默认的Import tiled map生成的World Composition是一样的了。
和前面的地形尺寸对应一样,这里正确的方法其实是要修改Houdini Engine里面的Bake机制,参考Import tiled map里代码的方法,自动的创建关卡和分配Landscape Component,实现整个流程的自动化。否则将来的迭代也会成为问题。
后续问题
虽然这里看似Houdini HeightFiled to UE4 Landscape的流程已经打通,但是在实际项目开发中还是会有以下几个问题
- 目前流程中Heightfiled还是整体的修改和导入,无法支持Landscape Component和Section的更小级别的增量更新
- 还要考虑World Composition的支持,可以自动的从Landscape的某个单元更新到LandscapeStreamingProxy
- 后续的基于地形的植被自动生成,山体自动建模等等的生成功能,也是要支持Landscape的最小单元。
- 对应手游的硬件的考虑,还需要要能生成不同细节的资源等。
- 最重要的,要把这流程做成引擎内的闭环,让开发人员不需要了解Houdini就能UE4里执行和调用功能。
另外Unity虽然没有提及,但相对实现应该跟UE4类似,而且也可以将Heightfile转换为Terrain Mesh来适配移动设备,这里就不多做介绍了。而上面描述的问题,会在今后的分享中有所解答。关于本文的事例资源会在近期提供一个分享专用的git地址。
以上是关于Houdini技术体系 基础管线 :Heightfiled与UE4的无缝导入以及对World Composition的支持的主要内容,如果未能解决你的问题,请参考以下文章
Houdini技术体系 基础管线 :UE4 Landscape Component的多选支持 下篇
Houdini技术体系 基础管线 :Heightfiled与UE4的无缝导入以及对World Composition的支持