虚幻引擎程序化资源生成框架PCG 之Gather(收集)、Merge(合并)、Union(并集)

news2024/11/17 16:14:56

有朋友询问:Gather(收集)、Merge(合并)、Union(并集)这三个运算节点,看名字有些相似,究竟区别是什么?目前还没有详细的官方文档,所以今天老王结合源代码,尝试分析一下。

文章目录

  • Gather(收集)
    • Gather的作用:
  • Merge(合并)
    • Merge的作用:
  • Union(并集)
    • Union的作用:
  • 小结

Gather(收集)

在这里插入图片描述

bool FPCGGatherElement::ExecuteInternal(FPCGContext* Context) const
{
	TRACE_CPUPROFILER_EVENT_SCOPE(FPCGGatherElement::Execute);

	Context->OutputData = Context->InputData;

	return true;

}

Gather的作用:

  • FPCGDataCollection:输入端所有FPCGDataCollection合并成一个FPCGDataCollection,对数据不做任何处理,所以最终输出端的FPCGDataCollection数量为1。
  • FPCGTaggedData:最终输出端的FPCGTaggedData数量为输入端所有FPCGDataCollection中包含的FPCGTaggedData数量总和。
  • PCGPoint:最终输出端的PCGPoint数量为输入端所有FPCGDataCollection中包含的PCGPoint数量总和。

小结: Gather就是对FPCGDataCollection简单汇总操作。

Merge(合并)

在这里插入图片描述

bool FPCGMergeElement::ExecuteInternal(FPCGContext* Context) const
{
	TRACE_CPUPROFILER_EVENT_SCOPE(FPCGMergeElement::Execute);
	check(Context);

	const UPCGMergeSettings* Settings = Context->GetInputSettings<UPCGMergeSettings>();
	check(Settings);

	const bool bMergeMetadata = Settings->bMergeMetadata;

	TArray<FPCGTaggedData> Sources = Context->InputData.GetInputs();
	TArray<FPCGTaggedData>& Outputs = Context->OutputData.TaggedData;

	if (Sources.IsEmpty())
	{
		return true;
	}

	UPCGPointData* TargetPointData = nullptr;
	FPCGTaggedData* TargetTaggedData = nullptr;

	// Prepare data & metadata
	// Done in two passes for futureproofing - expecting changes in the metadata attribute creation vs. usage in points
	for (const FPCGTaggedData& Source : Sources)
	{
		const UPCGPointData* SourcePointData = Cast<const UPCGPointData>(Source.Data);

		if (!SourcePointData)
		{
			PCGE_LOG(Error, GraphAndLog, LOCTEXT("UnsupportedDataType", "Unsupported data type in merge"));
			continue;
		}

		if (!TargetPointData)
		{
			TargetPointData = NewObject<UPCGPointData>();
			TargetPointData->InitializeFromData(SourcePointData, nullptr, bMergeMetadata);

			TargetTaggedData = &(Outputs.Emplace_GetRef(Source));
			TargetTaggedData->Data = TargetPointData;
		}
		else
		{
			if (bMergeMetadata)
			{
				TargetPointData->Metadata->AddAttributes(SourcePointData->Metadata);
			}
			
			check(TargetTaggedData);
			TargetTaggedData->Tags.Append(Source.Tags); // TODO: only unique? if yes, fix union too
		}
	}

	// No valid input types
	if (!TargetPointData)
	{
		return true;
	}

	TArray<FPCGPoint>& TargetPoints = TargetPointData->GetMutablePoints();
	
	for(int32 SourceIndex = 0; SourceIndex < Sources.Num(); ++SourceIndex)
	{
		const UPCGPointData* SourcePointData = Cast<const UPCGPointData>(Sources[SourceIndex].Data);

		if (!SourcePointData)
		{
			continue;
		}

		int32 PointOffset = TargetPoints.Num();
		TargetPoints.Append(SourcePointData->GetPoints());

		if ((!bMergeMetadata || SourceIndex != 0) && !SourcePointData->GetPoints().IsEmpty())
		{
			TArrayView<FPCGPoint> TargetPointsSubset = MakeArrayView(&TargetPoints[PointOffset], SourcePointData->GetPoints().Num());
			for (FPCGPoint& Point : TargetPointsSubset)
			{
				Point.MetadataEntry = PCGInvalidEntryKey;
			}

			if (bMergeMetadata && TargetPointData->Metadata && SourcePointData->Metadata && SourcePointData->Metadata->GetAttributeCount() > 0)
			{
				TargetPointData->Metadata->SetPointAttributes(MakeArrayView(SourcePointData->GetPoints()), SourcePointData->Metadata, TargetPointsSubset);
			}
		}
	}
	
	return true;
}

Merge的作用:

  • FPCGDataCollection:最终输出端的FPCGDataCollection数量为1。
  • FPCGTaggedData:最终输出端的FPCGTaggedData数量也为1。输入端所有Tag的并集和Attribute的并集作为输出端FPCGTaggedDataTagAttribute。如果两条FPCGTaggedData中有同名Attribute且类型不一致以第一个为准。
  • PCGPoint:最终输出端的PCGPoint数量为输入端所有FPCGDataCollection中包含的PCGPoint数量总和。

小结:MergeFPCGTaggedData层级的合并。

Union(并集)

在这里插入图片描述

bool FPCGUnionElement::ExecuteInternal(FPCGContext* Context) const
{
	TRACE_CPUPROFILER_EVENT_SCOPE(FPCGUnionElement::Execute);

	const UPCGUnionSettings* Settings = Context->GetInputSettings<UPCGUnionSettings>();
	check(Settings);

	TArray<FPCGTaggedData> Inputs = Context->InputData.GetInputs();

	const EPCGUnionType Type = Settings->Type;
	const EPCGUnionDensityFunction DensityFunction = Settings->DensityFunction;

	TArray<FPCGTaggedData>& Outputs = Context->OutputData.TaggedData;

	const UPCGSpatialData* FirstSpatialData = nullptr;
	UPCGUnionData* UnionData = nullptr;
	int32 UnionTaggedDataIndex = -1;

	for (FPCGTaggedData& Input : Inputs)
	{
		const UPCGSpatialData* SpatialData = Cast<UPCGSpatialData>(Input.Data);

		// Non-spatial data we're not going to touch
		if (!SpatialData)
		{
			Outputs.Add(Input);
			continue;
		}

		if (!FirstSpatialData)
		{
			FirstSpatialData = SpatialData;
			UnionTaggedDataIndex = Outputs.Num();
			Outputs.Add(Input);
			continue;
		}

		FPCGTaggedData& UnionTaggedData = Outputs[UnionTaggedDataIndex];

		// Create union or add to it
		if (!UnionData)
		{
			UnionData = FirstSpatialData->UnionWith(SpatialData);
			UnionData->SetType(Type);
			UnionData->SetDensityFunction(DensityFunction);

			UnionTaggedData.Data = UnionData;
		}
		else
		{
			UnionData->AddData(SpatialData);
			UnionTaggedData.Tags.Append(Input.Tags);
		}
		
		UnionTaggedData.Data = UnionData;
	}

	return true;
}
UnionData = FirstSpatialData->UnionWith(SpatialData);

Union的关键是对FPCGSpatialData进行并集运算。符合条件的FPCGSpatialData会合并成1个。

Union的作用:

  • FPCGDataCollection:最终输出端的FPCGDataCollection数量为1。
  • FPCGTaggedData:最终输出端的FPCGTaggedData数量也为1。
  • PCGPoint:最终输出端的PCGPoint数量输入端所有FPCGDataCollection中包含的PCGPoint数量总和。

小结

简单地说:Gather(收集)、Merge(合并)、Union(并集)依次是从FPCGDataCollection层级、FPCGTaggedData层级、PCGPoint(FPCGSpatialData)层级和“合并”运算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/756922.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑城逐渐衰退甚至消失,究竟是好是坏呢?

在过去很长一段时间里&#xff0c;想要购买电子设备都逃不开一个叫“电脑城”的地方&#xff0c;那里鱼龙混杂良莠不齐&#xff0c;是令许多人记忆深刻分外难忘之处。但是随着时代发展电商兴起&#xff0c;采用传统线下销售的电脑城却逐渐衰退甚至面临消失。 电脑城曾经是很多…

【2】Spring手写模拟-依赖注入、初始化、AOP

首先回顾一下我们之前的流程ApplicationContext 构造方法 获取Spring配置类ComponetScan 注解&#xff0c;扫描包&#xff0c;获取其路径及其对应的字节码文件逐个扫描字节码文件 利用字节码文件获取类&#xff0c;查看是否包含Componet 注解&#xff0c;并获取或者生成BeanNa…

vv、vt 埋点上报自动化文档

vv、vt 埋点自动化文档 文章目录 vv、vt 埋点自动化文档一、项目简介二、环境搭建Airtest官方参考文档AirtestIDE下载Python环境安装Airtest安装安卓环境IOS 环境iOS-Tagent 编译 设置代理 三、框架介绍四、实现原理4.1 框架流程图4.2 初始化配置4.2.1 读取mock server配置&…

sqli-labs

目录 Less1 首先来爆字段 联合注入 判断注入点 爆数据库名 爆破表名 information_schema information_schmea.tables group_concat() 爆破列名 information_schema.columns 爆值 SQLMAP 主要对sqli-labs 的深入学习 Less1 我们先看看源代码 <?php //includ…

山西电力市场日前价格预测【2023-07-16】

日前价格预测 预测明日&#xff08;2023-07-16&#xff09;山西电力市场全天平均日前电价为395.36元/MWh。其中&#xff0c;最高日前电价为510.19元/MWh&#xff0c;预计出现在20: 00。最低日前电价为309.52元/MWh&#xff0c;预计出现在13: 15。 价差方向预测 1&#xff1a;实…

如何从零开始搭建公司自动化测试框架?

搭建的自动化测试框架要包括API测试&#xff0c;UI测试&#xff0c;APP测试三类。以上三类其实可以简化为两类&#xff0c;那就是&#xff1a; 1&#xff09;接口自动化测试框架搭建 2&#xff09;UI自动化测试框架搭建。 没问题&#xff0c;安排&#xff0c;且是手把手教你如何…

Next.js框架入门笔记

内置组件 ‘pages/_document.js’ 文件&#xff0c;自定义document DOC&#xff1a; https://www.nextjs.cn/docs/advanced-features/custom-document <Head>组件 <Head>是一个内置在 Next.js 中的 React 组件。它允许您修改页面的<head>。 Docs: https:/…

JVM理论(四)运行时数据区--堆/方法区

堆(heap) 堆内存逻辑上分为三部分 一个JVM实例只存在一个堆内存,JVM启动时创建堆区&#xff0c;通常情况下也是最大的内存空间&#xff0c;几乎所有的对象实例都要在堆中分配内存&#xff0c;所以堆也是垃圾回收的重点区域堆是被所有线程共享的,在堆里面也可以划分线程私有的缓…

肝!熬夜到天明,阿里顶配级 Spring Security 笔记

Spring Security Spring Security 是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是 Spring 生态系统中的一员&#xff0c;因此它伴随着整个 Spring 生态系统不断修正、升级&#xff0c;在 spring boot 项目中加入 springsecurit…

Ubuntu下安装Miniconda

下载 到根据自己本地python版本到官网下载 https://docs.conda.io/en/latest/miniconda.html#linux-installers 我本地是python3.8 然后上传到Ubuntu服务器上&#xff0c;或者直接使用wget下载&#xff1a; wget https://repo.anaconda.com/miniconda/Miniconda3-py38_23.5…

WebSocket理论和实战

一 WebSocket理论 1.1 什么是http请求 http链接分为短链接、长链接&#xff0c;短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。长链接是在一定的期限内保持链接&#xff08;但是是单向的&#xff0c;只能从客户端向服务端发消息&#x…

单例模式、指令重排序、锁、有序性

今天在回顾单例模式时&#xff0c;我们都知道懒汉式单例中有一种叫做双重检查锁的单例模式。 我们来看下下面的代码有没有问题&#xff1a; 这段代码我们可以看到&#xff0c;即优化了性能&#xff0c;在多线程情况下&#xff0c;如果实例不为空了&#xff0c;则直接返回了。…

1766_perl实现readlines功能

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 近段时间写一个Perl程序&#xff0c;中间反反复复用到了文件的读写。虽说是用Perl的基本功能实现读写非常简单&#xff0c;但是写的过程中我不止一次在想Python以及MATLAB的功能…

华为OD机试真题 Java 实现【评论转换输出】【2023 B卷 100分】,附详细解题思路

目录 专栏导读一、题目描述在这里插入图片描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A…

什么是元学习?外循环和内循环?支持集和查询集?

一、前言 元学习近几年也算是一个比较热门的研究方向&#xff0c;大部分被用来解决低资源少样本零样本学习的任务场景中。 那么为什么元学习可以提升低资源少样本的学习效果呢&#xff1f;活着说元学习到底是一个什么阳的算法呢&#xff1f; 这里做一个简单的概念阐述。元学…

echart之map地图图表使用教程

本文以echarts展示成都地图为例子。 echarts map &#xff08;echarts地图&#xff09;使用教程 效果展示准备阶段获取地图geojson数据安装echarts 开始绘制容器准备js代码 补充事项vue3.0 用ref定义echarts报错toRaw、markRaw 扩展 地图隐藏南海诸岛地图显示提示框地图实现下钻…

Vue项目的启动

前言&#xff1a; 由于最近开始实习&#xff0c;负责人上来就给我丢一个前端vue项目和后端文件&#xff0c;让我在本机完成部署&#xff0c;由于之前学的基本上都是后端相关知识&#xff0c;很少有了解到前端的东西&#xff0c;因此在这里将自己部署Vue项目时遇到的问题和解决过…

编译libtiff库给IOS平台用

打开libtiff官方网 : libtiff / libtiff GitLab 克隆: git clone --recursive https://gitlab.com/libtiff/libtiff.git 克隆成功并打开libtiff目录,发现有autogen.sh 与CMakeLists.txt所以可生成Configure程序来配置并编译,也可直接使用CMake-GUI来配置编译,选择其中一种 …

远程会诊如何实现?

比如&#xff1a;医生遇到复杂病情需要求助院外专家远程会诊过程中&#xff0c;需要将电脑中的病人资料给院外专家看&#xff0c;同时确保医院电脑和网络系统绝对安全&#xff0c;电脑不允许安装任何外部软件&#xff0c;不能被外人控制和操作&#xff0c;外部设备不能接入医院…

【Java技术专题】「攻破技术盲区」带你攻破你很可能存在的Java技术盲点之技术功底指南(鲜为人知的技术)

带你攻破你很可能存在的Java技术盲点之技术功底指南 基本类型的包装类技术盲点&#xff1a;基本类型的比较技术盲点&#xff1a;字符串内部化&#xff08;string interning&#xff09;字符串内部化的示例 技术盲点&#xff1a;类型缓存机制&#xff08;空间换时间&#xff09;…