UE5《Electric Dreams》项目PCG技术解析 之 PCGCustomNodes详解(一)

2024-03-18 12:10

本文主要是介绍UE5《Electric Dreams》项目PCG技术解析 之 PCGCustomNodes详解(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Electric Dreams》项目中提供了一些自定义节点和子图(文件位置:“/Content/PCG/Assets/PCGCustomNodes”),这些节点和子图在《Electric Dreams》被广泛使用,对于理解《Electric Dreams》非常重要,而且它们可以直接移植到新的项目中使用。所以写个博客分析一下

文章目录

  • 前导文章
  • Passthrough节点
    • 作用
    • Execute with Context
  • PointNormalToColor节点
    • 作用
    • Point Loop Body
    • Execute with Context
  • PointFromPCGVolume节点
    • 作用
    • Execute with Context

在这里插入图片描述

前导文章

《虚幻引擎程序化资源生成框架PCG 之 UPCGBlueprintElement源码笔记(一)》
《虚幻引擎程序化资源生成框架PCG 之 UPCGBlueprintElement源码笔记(二)数据流》

Passthrough节点

作用

数据流的开关

Execute with Context

在这里插入图片描述

Enabled控制是否将从Input输入进来的从Output输出,当Enabledfalse的时候,输出的PCGDataCollection中的Tagged Data数组将会是一个空数组。

PointNormalToColor节点

作用

将Point法线存入Color属性

Point Loop Body

先看一下它的Point Loop Body
在这里插入图片描述
Point Loop Body的逻辑就是将每一个Point的Up Vector存储在Color属性中,然后把修改过的Point输出。

Execute with Context

在这里插入图片描述

注释见上图,在PointLoopBody后面有一个Initialize from Data节点,代码如下:

void UPCGSpatialData::InitializeFromData(const UPCGSpatialData* InSource, const UPCGMetadata* InMetadataParentOverride, bool bInheritMetadata, bool bInheritAttributes)
{if (InSource && TargetActor.IsExplicitlyNull()){TargetActor = InSource->TargetActor;}if (!Metadata){Metadata = NewObject<UPCGMetadata>(this);}if (!bInheritMetadata || InMetadataParentOverride || InSource){const UPCGMetadata* ParentMetadata = bInheritMetadata ? (InMetadataParentOverride ? InMetadataParentOverride : (InSource ? InSource->Metadata : nullptr)) : nullptr;Metadata->Initialize(ParentMetadata, bInheritAttributes);}else{UE_LOG(LogPCG, Warning, TEXT("InitializeFromData has both no source and no metadata override"));}
}

Initialize from Data做了两件事:

  • 将源Data中的TargetActor赋值给新PCGSpatialDataTargetActor
  • 用源Data的metadata初始化新PCGSpatialData的metadata

PointFromPCGVolume节点

作用

使用ContextSourceComponent或者Component的几何信息(TransformBound)构造1个PCGPoint

Execute with Context

在这里插入图片描述

我们先看一下GetComponentGetOriginalComponent

UPCGComponent* UPCGBlueprintHelpers::GetComponent(FPCGContext& Context)
{return Context.SourceComponent.Get();
}UPCGComponent* UPCGBlueprintHelpers::GetOriginalComponent(FPCGContext& Context)
{if (Context.SourceComponent.IsValid() &&Cast<APCGPartitionActor>(Context.SourceComponent->GetOwner()) &&Cast<APCGPartitionActor>(Context.SourceComponent->GetOwner())->GetOriginalComponent(Context.SourceComponent.Get())){return Cast<APCGPartitionActor>(Context.SourceComponent->GetOwner())->GetOriginalComponent(Context.SourceComponent.Get());}else{return Context.SourceComponent.Get();}
}

再看看它是如何获取GetActorLocalBoundsPCG

UPCGBlueprintHelpers::GetActorLocalBoundsPCG

FBox UPCGBlueprintHelpers::GetActorLocalBoundsPCG(AActor* InActor, bool bIgnorePCGCreatedComponents)
{return PCGHelpers::GetActorLocalBounds(InActor, bIgnorePCGCreatedComponents);
}

PCGHelpers::GetActorLocalBounds

FBox GetActorLocalBounds(const AActor* InActor, bool bIgnorePCGCreatedComponents){// Specialized version of CalculateComponentsBoundingBoxInLocalScape that skips over PCG generated components// This is to ensure stable bounds and no timing issues (cleared ISMs, etc.)FBox Box(EForceInit::ForceInit);const bool bNonColliding = true;const bool bIncludeFromChildActors = true;if (InActor){const FTransform& ActorToWorld = InActor->GetTransform();const FTransform WorldToActor = ActorToWorld.Inverse();InActor->ForEachComponent<UPrimitiveComponent>(bIncludeFromChildActors, [bNonColliding, bIgnorePCGCreatedComponents, &WorldToActor, &Box](const UPrimitiveComponent* InPrimComp){if ((bNonColliding || InPrimComp->IsCollisionEnabled()) &&(!bIgnorePCGCreatedComponents || !InPrimComp->ComponentTags.Contains(DefaultPCGTag))){const FTransform ComponentToActor = InPrimComp->GetComponentTransform() * WorldToActor;Box += InPrimComp->CalcBounds(ComponentToActor).GetBox();}});}else{UE_LOG(LogPCG, Error, TEXT("Actor is invalid in GetActorLocalBounds"));}return Box;}

所谓LocalBounds就是把所属Actor的所有PrimitiveComponent叠加起来获得最大的FBox

在这里插入图片描述

这篇关于UE5《Electric Dreams》项目PCG技术解析 之 PCGCustomNodes详解(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/822294

相关文章

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

SpringBoot项目中Maven剔除无用Jar引用的最佳实践

《SpringBoot项目中Maven剔除无用Jar引用的最佳实践》在SpringBoot项目开发中,Maven是最常用的构建工具之一,通过Maven,我们可以轻松地管理项目所需的依赖,而,... 目录1、引言2、Maven 依赖管理的基础概念2.1 什么是 Maven 依赖2.2 Maven 的依赖传递机

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代