Houdini技术体系 基础管线(四) :Houdini驱动的UE4植被系统 上篇
2018-06-28 15:58
435 查看
背景
之前在《Houdini技术体系 过程化地形系统(一):Far Cry5的植被系统分析》一文中已经对AAA游戏中过程化植被的需求有了一定的定义,后续工作就是如何用Houdini开发功能需求定义的节点,以及对应UE4的Houdiin Engine来制定过程化管线。Houdini的HDA的开发放在过程化地形系统部分讲解,这里主要是讲解工作流程的制定。FC5的分析之前,也大致介绍了UE4的植被系统。这里再确定下植被系统工作流方面的需求:- Houdini Input:UE4 要输入什么给Houdini
- 所选择Landscape Component部分的地形信息
- 美术提供的选择区域,可以是绘制的Mask,也可以是Curve的选框
- 与HDA中对应的植被资源参数,简单的可以用Houdini Engine ,完善一些的话最好是一个json或xml的描述文件,或者UE4的DataTabel。
- 除了HeightMap外的Mask信息,还有峭壁,湖泊,电线杆,栅栏等不能摆放植被的区域Mask
- Houdini Ouptut:Houdini要输出什么给UE4
- Entity Point Cloud:每个点包含了对应的植被实体,以及实体的Positon,Rotation,Scale等Transform信息
- Terrain Data:例如树根对地形隆起的变化,树根部分对地表材质Mask的影响,地表的颜色等
- Mask Data:草体布局信息的Mask贴图
- UE4植被系统的支持
- Houdini Instance与UE4 Foliage Type的Instance的对应
- Houdini Biome Mask与UE4 Grass Type的对应
- Houdini闭环修改与UE4 Foliage System的对应。
Houdini的Input设置
在之前FC5的植被系统的需求分析中也可以得知,最新的AAA游戏中,一平方公里场景里就有60w左右的植被实体,而最近的一些UE4大世界游戏和手游,也通常在6x6~8x8km左右。在策划和美术的迭代开发中,每次都要生成整个场景的植被再看效果的话,会极大的影响开发效率,对大团队的多人协作开发也很不友好。所以这里也要像之前的地形管线一样,以FC5的过程化系统为原型,可以支持美术或策划来选择和绘制生成区域,让Houdini的过程化生成只影响这一部分选择区,这样不但可以利用UE4的WorldComposition的功能多人工作,也可以通过UE4自带的绘制Selection Region Tool,让美术更进一步的控制过程化的影响区域,减少生成时间,提升迭代效率。 如下图所示,FC5的植被系统,支持类似UE4的Component和Paint Region来作为Terrain Data, 在上文中,也总结到UE4里FC5植被系统的Input,有以下几项:- 所选择Landscape Component部分的地形信息
- 美术提供的选择区域,可以是绘制的Mask,也可以是Curve的选框
- 与HDA中对应的植被资源参数,简单的可以用Houdini Engine ,完善一些的话最好是一个json或xml的描述文件,或者UE4的DataTabel。
- 除了HeightMap外的Mask信息,还有峭壁,湖泊,电线杆,栅栏等不能摆放植被的区域Mask
TArray<float> SelectedRegionData; for (int32 X = MinX; X <= MaxX; X++) { for (int32 Y = MinY; Y <= MaxY; Y++) { float RegionSelect = LandscapeInfo->SelectedRegion.FindRef(FIntPoint(X, Y)); SelectedRegionData.Add(RegionSelect); } }
接下里,跟LayerMask同样的方式,通过C++代码创建一个名为SelectedRegion的Mask节点,并跟其他的Volume Merge到一起。
FString LayerName = "SelectedRegion"; HAPI_NodeId LayerVolumeNodeId = -1; if (!CreateVolumeInputNode(LayerVolumeNodeId, LayerName, ParentId)) return false; HAPI_PartId CurrentPartId = 0; if (!SetHeighfieldData(LayerVolumeNodeId, CurrentPartId, SelectedRegionData, SelectedRegionLayerVolumeInfo, LayerName, ComponentIndex)) return false; if (!CommitVolumeInputNode(LayerVolumeNodeId, InputMergeNodeId, MergeInputIndex)) return false; MergeInputIndex++;
另外,ULandscapeInfo提供了把绘制的SelectedRegion转为Selected Component的功能,这样绘制过过程化的影响区域后,就不用再选择一次Landscpe Component了。这个修改也很简单,在FHoudiniEngineUtils::HapiCreateInputNodeForLandscape函数里,当没有selected components时,就把绘制的区域转换成SelectedComponents。
if ( LandscapeInfo ) { // Get the currently selected components SelectedComponents = LandscapeInfo->GetSelectedComponents(); // 如果没有selected components,则从绘制区域获取selected components if (SelectedComponents.Num() == 0) SelectedComponents = LandscapeInfo->GetSelectedRegionComponents(); }把名为“SelectedRegion”的Mask作为Input输入到HDA后,需要在HDA里对应这个Mask Layer来识别。在HDA的Heightfield Noise节点里,把SelectedRegion作为Mask Layer来使用 这样HeightField只有在有Mask的部分会有Noise的效果,这个同样也可以用在植被的Entity Point Cloud的生成上。 下图的效果,就是在绘制的'X'的区域内,对9个Landscape Component产生噪声变化。 绘制选区通常是控制比较大的区域,而如果是要生成小范围的区域,建议像下图这样用Curve Input来控制区域了。 如何创建一个Curve Input的方法,在Houdini技术体系 基础管线(三) :UE4以选择区域的方式对地形做生成和更新 上篇 和官方文档 https://www.sidefx.com/docs/unreal/_curves.html里都有详细介绍,也是有创建SOP或添加Operate Path两种方法。这里就不多做叙述了。 除了HeightData选区外,Input还需要有摆放的UE4植被列表(Biomes List),植被列表通常是用xml,json,或者ue4的datatable来记录每种植被在HDA节点里属性以及在UE4中使用资源的对应关系。然后在HDA里通过Python脚本来加载读取,即便是比下图FC5用例更复杂的HDA节点串联和配置,也可以借助Python自动化,完全摆脱人力基于配置文件自动化的创建和连接。Houdini的Python脚本使用在后续的基础管线部分讲解,本节出于篇幅关系,使用Geometry Input作为简化版的Biome Input。 而类似各种像湖泊,峭壁,电线杆等的Mask过程化生成的Mask,这里假设你已经通过其他方式导出了Mask图,或者准备在Houdini里通过Mask By Feature或Mask By Object来生成。在管线部分也就不浪费篇幅了,会在之后具体的地形篇的植被制作部分再做详细介绍。
HDA的制作以及Ouput的对应
FC5的HDA的Output分为两大类- Entity Point Cloud
- Terrain Data
UInstancedStaticMeshComponent * InstancedStaticMeshComponent = nullptr; if ( StaticMesh->GetNumLODs() > 1 ) { // If the mesh has LODs, use Hierarchical ISMC InstancedStaticMeshComponent = NewObject< UHierarchicalInstancedStaticMeshComponent >( RootComp->GetOwner(), UHierarchicalInstancedStaticMeshComponent::StaticClass(), NAME_None, RF_Transactional); } else { // If the mesh doesnt have LOD, we can use a regular ISMC InstancedStaticMeshComponent = NewObject< UInstancedStaticMeshComponent >( RootComp->GetOwner(),UInstancedStaticMeshComponent::StaticClass(), NAME_None, RF_Transactional ); }
这里保证树的实体有LOD,并且在HDA Input 勾选Export LODs 再次Bake,可以看到是HierarchicalInstancedStaticMeshComponent,每个Instance也有之前的LOD信息了。 姑且算是支持了最基础的Entity Cloud Point的Output,但距离实际项目需求还很遥远,就像Input需要支持Biomes List配置表的读取一样,Output出于维护和调试的考虑,最好也是能支持Biomes List的输出,而且,虽然提供给场景美术绘制影响区域的功能,但BP的保存方式,对Houdini的闭环迭代也并不足够的友好,当美术需要对一些细小地区做频繁迭代时,新生成的植被如何去替换BP里已经生成植被也是个问题,解决方法只能整个BP对应区域重新生成一次。这需要美术在设计初期就对植被布局策略和种类考虑清楚。还有就是UE4除了Foliage Type外,还有Grass Type的植被的支持。这些会放在之后如何UE4植被系统整合的部分来讲解。 FC5的植被系统除了Entity Cloud Point之外,还有以下的Terrain Data的Output。 其中Terrain HeightMap和Forest Mask,都可以通过之前地形管线中介绍的方法传递给UE4,而Texture ID,因为FC5的地形渲染有TextureArray支持,而UE4则受限于每个Component4个Landscape Layer的限制,所以Layer与Texture的对应又是在Mateiral里绑定的,需要修改UE4引擎源码才能支持,但这就超出Houdini技术体系范畴了。这里介绍一个临时的折中办法,通过直接去修改约定好的对应的Layer的Mask权重的方式,来实现UE4里要根据输出的Houdini Output的去改变Layer的Texture ID的需求。 首先,用RegionTool绘制一块区域来生成植被 这里就只简单的根据绘制的Mask部分Scatter生成Point Cloud,效果如下 接下来实现一下Terrain Data的Output的功能,不论是Terrain Texture还是Terrain Deformation的输出原理上都是在植被一定范围内生成Mask,再把这个Mask转化为Layer Data或者Height Data,传递给UE4。 出于跑通管线的目的,这里在HDA里做一个简单的实现。在houdini里根据Scatter生成的Point Cloud,使用Sphere来生成出Mask,再根据这个Mask来提升地形高度,并把Mask输出位树根部所对应的Landscape Material Layer的值。 在测试场景上选择一个生成区域 有摆放植被的周围地形改为了另外一种Layer。 树根附近的地表高度也被提升了。和FC5那种按照树根形状来提升高度的效果相比还是有差距。
总结
上篇中,简单的介绍了如何在UE4里实现类似FC5植被系统的管线,但还有问题等待解决- 虽然植被实体可以被Bake为HierarchicalInstancedStaticMeshComponent或InstancedStaticMeshComponent来近似UE4Foliage Type的渲染方式,但并不支持GrassType的类型。
- Point Cloud生成的植被只能Bake为场景中的Actor或BP而不是Foliage Type,并不能与UE4的Foliage System融合,在迭代和修改中增加了额外的负担。
- 示例中的HDA只支持1种植被,生成策略也非常简单,而且也不支持BiomeList的读取,和FC5有相当大的差距。
相关文章推荐
- Houdini技术体系 基础管线(四) :Houdini驱动的UE4植被系统 下篇
- Houdini技术体系 基础管线(三) :UE4以选择区域的方式对地形做生成和更新 上篇
- Houdini技术体系 基础管线(二) :Heightfiled与UE4的无缝导入以及对World Composition的支持
- Houdini技术体系 基础管线(三) :UE4 Landscape Component的多选支持 下篇
- Houdini技术体系 过程化地形系统(一):Far Cry5的植被系统分析
- Houdini技术体系 基础管线(一) : Houdini与Houdini Engine的安装
- Houdini 过程化地形系统(二):基于UE4的FC5植被系统(1)
- 文件系统过滤驱动基础知识
- 开源社交系统ThinkSNS基础技术要点分享 让你少走弯路!
- 南大Mooc计算机体系基础--x32-86指令系统
- 系统架构师-基础到企业应用架构-系统建模[上篇]
- 权限学习--BlueDavy之技术Blog漫谈权限系统之结尾篇(开源产品、个人观点、知识体系)
- 数据仓库系统的技术体系架构设计
- linux基础2-11系统恢复技术
- 系统架构师-基础到企业应用架构-系统设计规范与原则[上篇]1
- 负载均衡--大型在线系统实现的关键(上篇)(再谈QQ游戏百万人在线的技术实现)
- 信息安全系统设计基础课外之: 网络攻防技术 20155202 张旭
- 文件系统驱动编程基础篇之五——注册表与Inf
- 零基础Android手机嵌入式开发实战课程(网吧计费系统、多功能播放器、驱动开发)
- java技术体系基础