Houdini技术体系 基础管线(三) :UE4 Landscape Component的多选支持 下篇

背景

上篇中,我们介绍了如何修改Houdini Enigne来设置单个Landscape Compnent的Height和Layer的数据,但原生Houdini Engine并不支持多选Component的写回功能,下篇中,我们来解决这个问题。

Component多选支持的修改

Houdini Engine虽然支持多个Landscape Component的选择,但是并不支持写回到Landscape Component,需要自己来实现这个功能。单个Component的实现方法上文已经接受。

多选和单选区别只是在要把所选的Landscape Component按提交给Houdini的顺序来保存。

通过阅读Houdini Engine代码可以看到FHoudiniLandscapeUtils::CreateHeightfieldFromLandscapeComponentArray的参数LandscapeComponentArray里有所有提交的Landscape Component,不过LandscapeComponentArray中保存顺序并不是真正的提交顺序,而Houdini Engine Output出来的处理结果的顺序是Input的顺序的是一致的,如果直接用LandscapeComponentArray的结果,就会导致Component的不对应,所以这里我是在FHoudiniLandscapeUtils::CreateHeightfieldFromLandscapeComponent函数里把Input的Component保存起来,也保证了保存顺序。

然后在FHoudiniLandscapeUtils::CreateAllLandscapes函数中,就可以把每个FoundHeightfield和LandscapeComponent做对应,来调用LandscapeEdit.SetHeightData来更新这个Component的Height Data了。

  for ( TArray< const FHoudiniGeoPartObject* >::TConstIterator IterHeighfields
    ( FoundHeightfields ); IterHeighfields; ++IterHeighfields )
  {
      SelectLandscapeComponent =
      SelectLandscapeComponentArray[ComponentIndex];

而Layer Data的保存方式和Height Data,所有Landscape Component的Layer都保存在一个ImportLayerInfos,比如选了4个Component,每个Component有4个Layer,ImportLayerInfos里就有4x4 16个Layer Data的信息,这里也需要自己按Component和每个Component的Layer数量来提交。下面伪代码,LayerNum为每个Component的Layer的数量,ComponentIndex为处理的Component的编号,而实际开发情况下,可能每个Component的Layer的数量和命名都不一样,那就需要根据规则来定制这里的算法了。

 
// Set Current Component‘s Layer Data
for (int32 LayerIndex = LayerNum * ComponentIndex;
LayerIndex < LayerNum * (ComponentIndex + 1); LayerIndex++)
{
    LandscapeEdit.SetAlphaData
}
ComponentIndex++;

  

这样修改后,Houdini Engine就可以支持多选Landscape Component的Input和Output了。这里使用上节用到HDA文件,选中4个Component做HeightField Noise的生成

但结果跟我们预想的并不一样,而且只有第一个Component被做了Noise处理。。。

这是UE4原生的Houdini Engine的Input的数据和我们的HDA的处理算法不匹配导致的。

修改HDA对Input的支持

造成这个结果的原因,要从Houdini Engine生成Input的函数FHoudiniEngineUtils::HapiCreateInputNodeForLandscape入手:

// 1. Create the heightfield input node.
// We‘ll use its mergeId to connect all the landscape layers,
// while it‘s displayId will be our connected asset ID
FString LandscapeName = LandscapeProxy->GetName() + TEXT("_Merge");
HAPI_NodeId MergeId = -1;
if ( !FHoudiniLandscapeUtils::CreateHeightfieldInputNode( ConnectedAssetId, MergeId, LandscapeName ) )
    return false; 

  这里是通过Houdini Engine,直接创建了一个Houdini的Merge节点,然后把每个Component的Landscape Height Data和Layer Data转为HeightField的Height和Mask Volume,在Merge到一起,也就是用C++代码来生成HDA节点,这样就保证了所有Input的整体处理,而且也可以程序化的去对应不同的Input情况,在后面的章节里,很多Input项目也是要使用C++或Python来生成HDA节点来节省开发成本。下图就是程序生成HDA节点的效果示意:

再增加一个Heightfield noise 看下效果:和之前闭环测试效果一样,因为默认的Houdini HeightField节点并不支持这种多个Volume Merge的处理。

这里介绍三种解决方法:

方法一是直接修改或重写HeightField Noise节点来支持整个Merged Volume:

方法二:用Loop处理每个Height Volume

方法三:用tilesplice把Volume合并到一起做处理,然后再用split重新切开

如果不想自己修改或定制节点的话,方法二和三都可以,感觉方法三还更省事,但方法三有以下几个问题:

一个是Tile顺序的问题。UE4里的Tile和Houdini的Tile的行列是不同的,同样一个2x2的Compnent,他的Input和Output的顺序有所不同:

Input  Output

1 2      1 3

3 4      2 4

这个需要自己开发功能调整,另外,方法三所选的Component也必须是NxM这种连续的Volume,否则tilesplice节点会像下图这样帮你补齐。所以方法三也有不少的限制。

如果时间允许,还是自己开发一套Heightfield的节点来定制需要的功能,原生的HeightField系列节点在内存上也有些浪费,限制也比较多,而方法二和三可以作为临时应急方法。

边缘法线问题处理

再运行一次HDA处理,2x2的4个Component的节点确实都做了处理,但是在Component边缘有很明显的接缝问题,在World Normal视图下更明显。

造成法线接缝是Component之间是共享边缘造成的,单个Landscape Component的LandscapeEdit.SetHeightData即便选择计算法线,也会导致边缘因为采样不到旁边Component的顶点,而导致两个Component的不连续,这里我暂时使用了比较暴力的方法,所有的Landscape Comonent 在SetHeightData都不计算法线,而是在最后重新计算整个Landscape的Normal。

再看下修改后多选Component增加一个HeightField Noise的效果。

Height Data处理后,就是Layer Data的处理了,这里把HeightField Noise 改成 HeightField Mask Noise,对Landscpae的4个Layer的Mask做噪声处理,和之前Height Data导入时一样,也会有Component之间的接缝问题。

这种分割图接缝的问题,以前用WorldMachine做Tile Mask时也经常遇到,也就是Tile边缘之间共享顶点的问题。用WM可以少输出一圈边缘的Map的方法来解决,在UE4里也可以使用类似的方法。

在调用的LandscapeEdit.SetAlphaData参数上,把Stride比默认的宽度减少1(XSize - 1),就可以不传边缘的Mask Data进去了。

 
LandscapeEdit.SetAlphaData(ImportLayerInfos[LayerIndex].LayerInfo, SelectLandscapeComponent->GetSectionBase().X, SelectLandscapeComponent->GetSectionBase().Y, SelectLandscapeComponent->GetSectionBase().X + SelectLandscapeComponent->ComponentSizeQuads, SelectLandscapeComponent->GetSectionBase().Y + SelectLandscapeComponent->ComponentSizeQuads, (uint8*)ImportLayerInfos[LayerIndex].LayerData.GetData(), XSize - 1);

  

再看一下效果,接缝的问题基本上已经解决了。

总结

至此,Houdini技术体系的几个问题的基础解决方案已经完成,后面的文章会逐渐倾向Houdini的地形实际制作部分。

而这些技术案例,大多要基于这个闭环+可选组件的方式来实现,随着技术介绍流程,我也会在Github上定制一个类似Far Cry5的UE4 Houdini Engine版本,希望大家多提宝贵意见。

原文地址:https://www.cnblogs.com/TracePlus/p/9177146.html

时间: 2024-08-01 01:03:27

Houdini技术体系 基础管线(三) :UE4 Landscape Component的多选支持 下篇的相关文章

Houdini技术体系 基础管线(三) :UE4以选择区域的方式对地形做生成和更新 上篇

背景 前一节里,解决了Houdini地形无缝导入到UE4的流程问题.但这种方法也有它的局限性,在实际游戏项目里,LA和LD还是偏向在游戏引擎编辑器里工作,他们的一些设计也会影响到地形的信息,那么就需要Houdini对已经导入UE4中并Bake成Landscape的地形资源做二次修改.通常会选择两种方案: 方案一:把整个地形和建筑都导回到Houdini里,重新过程化和调整生成后,再全部导入回UE4做处理. 方案二:使用HDA节点的Input和Output,通过调用Houdini Engine AP

Houdini技术体系 基础管线(一) : Houdini与Houdini Engine的安装

Houdini 下载与安装 在官网 https://www.sidefx.com/download/ 下载最新的Production Build 版本,当前是16.5版本,需要注册帐号 PS:公司内网下载还是比较快的,如果是国内网络,下载可能会很慢和不稳定. 安装一路的默认选择就可以 后面我们需要使用的,让Houdini能够游戏引擎和DCC衔接的Houdini Engine Asset的选择安装,如果自己研究学习,又已经安装好引擎的话,可以勾选上.但正式项目会由程序员自己来维护Houdini E

Java 技术体系基础概念

Java 技术体系基础概念 =============================================================================== 概述: =============================================================================== 编程语言: [百度百科解释] 编程语言俗称"计算机语言",种类非常的多,总的来说可以分成机器语言.汇编语言.高级语言三大类.电脑每做的

java技术体系基础

编程语言分类: 1.系统级:C, C++, go, erlang 2.应用级:C#, Java, Python, Perl, Ruby, php 编程语言的类别: 指令+数据 1.面向过程:以指令为中心,围绕指令组织数据: 2.面向对象:以数据为中心,围绕数据组织指令: 虚拟机类型: 1.java虚拟机:jvm 2.Python虚拟机: pvm 开发动态网站的应用框架: 1.asp .net, jsp 思考与引申: 1.如果需要在不同的平台上都能使用开发好的java程序,需要在不同的平台上都安装

37 java技术体系基础、tomcat核心概念及使用初步、tomcat配置与应用

02 tomcat核心概念及使用初步 配置环境 node1: CentOS 6.7 192.168.1.121 CentOS 6 部署Tomcat [[email protected] ~]# rpm -ivh jdk-7u67-linux-x64.rpm  [[email protected] jdk1.7.0_67]# vim /etc/profile.d/java.sh export JAVA_HOME=/usr/java/latest export PATH=$JAVA_HOME/bin

《深入理解Java虚拟机》第一部分(Java技术体系,Java虚拟机,Java技术趋势)

第一部分 走进Java 1.Java技术体系 Sun官方定义的Java技术体系包括一下几个组成部分: Java程序设语言 各种硬件平台上的Java虚拟机 Class文件格式 Java API类库 第三方Java类库 JDK是用于支持Java程序开发的最小环境,Java程序设计语言.Java虚拟机.JavaAPI类库统称为JDKJRE是支持Java程序运行的标准环境,JavaAPI类库中的JavaSEAPI子集和Java虚拟机统称为JRE 按照Java技术关注的重点业务领域来分,Java技术体系可

浏览器端技术体系概览 -- 前端开发的七种武器

科普文一则,说说我对前端技术体系(也称浏览器端技术体系)的认识,希望能让更多人了解前端,也希望能借此丰富前端开发的大局观. 去年我写了网站性能优化系列文章,看过的朋友会知道,这类文章重点并非介绍各种具体的优化技巧,而是在关注发掘这些优化点的思路和方法.然后介绍给大家多种检测手段去发现问题,进而有目标的解决问题.所有这些需要我们对有网页整个生命周期有清晰的认识,对网页中各种技术极其相互结合的方式有明确的认知.这就回归到一个更本质的问题:浏览器端技术体系是怎样的. 想用三言两语说清前端技术不大可能,

.NET平台技术体系梳理

.NET平台应用领域众多(桌面开发,web开发,移动开发),不断有新的编程爱好者开始学习或从其他平台转移到.NET开发平台..NET开发平台由微软2000年提出,到今天已经进入到了第14个年头,新技术,新框架层出不穷,目不暇接.本文第一个目的是想揭示下.NET平台一路走来的发展脉络,以飨众多刚刚进入该领域的开发者. 我们总结的泛.NET平台技术圈的知识范畴如下图所示: 二 初学者学习路径建议 由上图可见,.NET平台技术繁多,从头学起需循序渐进.结合自己的学习经验,斗胆给出一份初学者的学习建议.

[个推 CTO、前MSN中国首席架构师 谈数据智能] 之本质及技术体系要求

安森,个推CTO毕业于浙江大学,现全面负责个推技术选型.研发创新.运维管理等工作,已带领团队开发出针对移动互联网.金融风控等行业的多项前沿数据智能解决方案. 曾任MSN中国首席架构师,拥有十余年资深技术开发与项目管理经验,在大数据处理系统.大规模并发平台.分布搜索系统.手机应用开发.无线通信领域和智慧金融系统等领域拥有丰富实践经验. 引言中国移动互联网的发展见证了中国大数据行业的蓬勃发展.数据智能作为移动互联网时代的自然产物,也是未来很长一段发展阶段的核心所在.个推(每日互动)和业界的共识不谋而