Electric Dreams PCG技术详解(一)——术语、工具和图表介绍

图片

本系列文章(共四部分)将详细介绍《Electric Dreams》演示中的程序化内容生成(PCG)框架,并介绍该项目中的各类工具、图表、自定义节点和子图表。

另外,如想进一步了解虚幻引擎的PCG框架,可以参阅以下文档:

https://docs.unrealengine.com/5.2/zh-CN/procedural-content-generation--framework-in-unreal-engine/


术语表


PCG图表

PCG图表是PCG的核心组件,它以图形化的数据流形式来描述一系列操作和逻辑。PCG图表可以保存为子图表,在其他图表中使用。


PGG元素

PGG元素,即PGG图表中的节点。这些元素可以通过C++代码或者PCG蓝图元素类创建。


PCG设置

PCG设置,即节点相关的设置,包括类和Attribute。


空间数据

空间数据是一种存在于空间中的数据,可以表示体积、2D表面(例如高度场和纹理等)、1D线条(例如样条和点云)。


点数据

3D空间中的点。每个点都有相关的边界、Property和Attribute信息。它们是操作中最常用的一种PCG数据类型。


Property

点Property是PCG点数据中的一组预定义Property。每个点都有Property。Property可以在Attribute操作中使用,必须以$符号作为前缀。(例如$Density、$Position.x、$Rotation.forward)


Property包括:

变换:变换矩阵:位置(三维向量)、旋转(旋转角度)、缩放(三维向量)

密度:点密度函数的范围是0到1,许多运算过程都会用到这个范围,例如差集、并集、噪点、筛选(浮点)

边界最大/最小值:点边界体积的最大值和最小值(三维向量)

颜色:点的颜色值(四维向量)

陡度:陡度的范围是0到1,表示点密度函数的斜率(浮点)。陡度=1时,密度函数会返回点边界内的最大密度,点边界外为0。陡度<1时,密度函数会返回最大密度值,线性插值最低到0,以点的边界最大/最小值为中心。

种子:由点位置、节点种子和组件种子(int64)计算得到的点种子


Attribute

Attribute是由用户定义的一组额外metadata,属于某个特定类型;Attribute可以覆盖节点参数或者与点关联,还能用于PCG图表中的Attribute操作。Attribute可以通过“Create Attribute”创建,或者在自定义PCG元素中创建。


当前支持的类型仅限于:vec2、vec3、vec4、float、double、int32、int64、bool、string、name、rotator、quaternion


Assembly

Assembly是由一组Actor和视效组件拼合而成的单个资产。《Electric Dreams》环境中的Assembly由Quixel资产、关卡实例或打包型关卡Actor组成,手动创建并放置在关卡四处,此外,在Level to PCG资产工具的帮助下,它们也被作为源内容在PCG图表和PCG Assembly中使用。


PCG Assembly

PCG Assembly是由PCG框架程序化生成的Assembly。PCG Assembly可以通过PCG图表中的一系列操作以多种方式创建,还可以通过更改输入(例如组件和/或公开的参数)进行自定义。PCG Assembly的作用包括生成单个网格体和Actor,以及完全手动制作的Assembly。


工具

下文将介绍《Electric Dreams》演示项目中的PCG工具。


Level to PCG资产工具

描述    

Level to PCG资产工具可以在选定的关卡中将所有静态网格体、分层实例化静态网格体(HISM)和实例化静态网格体(ISM)导出为PCG设置资产。数据以PCG点数据的形式存储:导出的所有视觉效果的点云,包括变换、网格体、材质软对象路径、所有Actor标签和Actor场景层级信息等Attribute。


PCG设置资产可以作为实例化节点,添加到任何PCG图表中。这些点数据可以按规则进行处理,进一步扩充和/或生成。


蓝图资产工具与PCG插件一起发布,启用“显示插件内容”后可按以下路径找到:

/PCG/Utilities/PCGUtility_LevelToPCG


《Electric Dreams》的所有PCG设置及其源关卡可按以下路径找到:

Content > PCG > Assets > PCGAssemblies


使用方法

如何使用 Level to PCG 资产工具:

1. 在内容浏览器中选择一个关卡

2. 右键单击,选择“脚本化资产操作(Scripted Asset Action)”->“PCG”->“Levelto PCG 设置(Level To PCG Settings)”

注意:如果选择的关卡是世界分区/OFPA 关卡,必须先在编辑器中将它打开并加载关卡内容。如果是非 OFPA 关卡,可以直接在内容浏览器中操作,无需在编辑器中打开关卡。


图片


3. 创建或更新的 PCG 设置资产将出现在选中的关卡文件旁边,以关卡名称和“_PCG”后缀命名。

4. 将创建好的 PCG 设置文件从内容浏览器拖到 PCG 图表中,作为一个实例化节点。

5. 在 PCG 图表中,将资产节点的“点(Points)”输出端连接到“复制点(Copy Points)”节点的“源(Source)”输入端,再将这些点连接到需要复制源点的目标上。注意:在“复制点(Copy Points)”节点中,如有可能,应将“Attribute 继承”设置为“仅源”,以加快处理速度。

6. 将“复制点(Copy Points)”节点的输出与“静态网格体生成器(Static MeshSpawner)”节点相连,并将网格体选择器类型设为“PCGMeshSelectorByAttribute”,将“Attribute 名称(Attribute Name)”设为“Mesh”。

注意:如果在导出的视觉效果上使用了材质覆盖,可以通过将“材质(Material)”作为 Index0 的值来激活“通过 Attribute 材质覆盖(By Attribute Material Overrides)”。


图片


此外,还可以在PCG图表中使用“点筛选器(Point Filter)”节点和导出的“Actor标签(Actor Tags)”Attribute来筛选点。


标签筛选用例:基于碰撞要求用“NoCol”进行筛选并生成相应的点;利用“Clutter”添加随机噪声和参数化密度以扩充Assembly;利用“Helper”筛选规则中具有特定目的但不应该生成的点。


Actor Tagger编辑器工具控件

 

图片


介绍

Actor Tagger编辑器工具控件用于在关卡中为资产添加Actor标签,旨在最终导出PCG设置资产的关卡时,加快标签添加的流程。


尽管虚幻引擎中有添加/编辑/删除资产Actor标签的适当流程,但目前还不适用于大规模编辑。例如,选择多个使用不同标签的Actor,可能会导致细节面板中的Actor标签混乱。


开发Actor Tagger编辑器工具控件的原因之一就是为了减少这种编辑器Actor标签行为。与此同时,它还提供了一个本地化操作面板,可以让用户专注于3D视口中的标签合成。


示例项目中的这个编辑器工具控件位于:

●/Game/PCG/Utilities/ActorTagger/EUW_ActorTagger


要运行Actor Tagger,需要在内容浏览器中选中它,右键单击,选择“运行编辑器工具控件”


功能

Select Tag按钮

在加载的关卡中选择包含“选择标签”字段中输入的标签的所有Actor。

当前大纲选择的对象将被上述结果替代。


Remove Tag按钮

搜索当前选中的所有Actor,查找“移除标签”字段中输入的标签。

如果Actor中包含该标签,该标签将会被删除。


Add Tag按钮

为当前选中的所有Actor添加“添加标签”字段中输入的标签。

如果选择的Actor已经包含该标签,该标签不会重复添加。


Hide按钮

隐藏当前选择的Actor,如果当前未选择任何Actor,则将显示之前隐藏的Actor。


Unlit / Lit按钮

切换视口光照模式,在无光照模式和光照模式之间切换。


工具选择

Output Level Tags按钮

在加载的关卡中出现的所有独特标签都将被打印到输出日志中,以便快速预览已加载的关卡中所有的Actor标签。

 

图片


Make Tags Unique按钮

此功能将作用于当前加载的关卡中的所有Actor,并基于每个Actor将重复标签减少到只有一条。


Reference Level按钮

此功能将加载或卸载指定引用关卡,其中可能包含光照和引用对象,以便构建要导出为PCG设置资产的关卡。


图片

 

引用关卡作为临时关卡实例加载到当前关卡中,这可以防止任何引用关卡中的Actor被错误地保存到正在处理的关卡中。

 

图片


在这个示例项目中,作为默认引用关卡的资产是:

●/Game/PCG/Utilities/ActorTagger/ActorTagger_ReferenceLevel


它在Actor Tagger控件初始化的时候分配,这也可以通过在控件构造脚本中更改分配的关卡来实现自定义。

 

图片

Set Reference Level按钮

此功能允许用户自定义想要加载和卸载的引用关卡。只需在内容浏览器中选择一个非世界分区关卡,再选择这个按钮。用户分配的引用不会被控件保存,每次运行控件时都需要重新分配。


图表

为构建《Electric Dreams》环境而创建的图表。


地表

 

图片


描述

地表PCG图表用于生成在Ditch堤墙内形成的小溪床表面。地表规则会根据周围样条和大型Assembly程序化填充其表面区域。使用世界射线散投射在生成表面上的动态岩石、湿贴花以及浅水滩也是由它生成的。


设置

地表程序化生成依赖以下条件:

●世界中存在“PCGDemo_DitchBP”Actor,其闭环样条组件被标记为“Active_Spline”。

●或者:世界中存在一个大型AssemblyActor,其闭环样条组件被标记为“Main_Spline”。

●用于执行Ground图表的PCG组件


Ground图表位于:

●/Game/PCG/Graphs/Ground/PCGDemo_Ground


一个自包含式蓝图Actor,拥有执行Ground图表的PCG组件:

●/Game/PCG/Graphs/Ground/PCGDemo_GroundBP


《Electric Dreams》环境示例项目中已包含地表和Ditch规则的关卡:

●ElectricDreams_Env:/Game/Levels/ElectricDreams_Env

●ElectricDreams_PCG:/Game/Levels/PCG/ElectricDreams_PCG

●ElectricDreams_PCGCloseRange:/Game/Levels/PCG/ElectricDreams_PCGCloseRange


逻辑

图表概览

 

图片

对Spline进行采样

 

图片


在Ground图表中,我们首先要获取世界中其他Actor的样条数据并对其进行采样,然后通过一系列操作创建出表面效果:


●通过“获取样条数据(Get Spline Data)”节点,从Ditch EmbankmentActor和可选的大型Assembly中获取需要的样条。


●利用“按标签筛选(Filter by Tag)”节点,根据组件标签筛选特定的样条数据。这可以分离出特定的样条,为具有多个样条组件的Actor提供支持。


●每个样条使用两个表面取样器,对表面(针对内部区域)和边界(针对样条)进行采样。它们的输出可以为后续操作提供所需的点数据。


●使用名为“PointsFromActorTag”的自定义PCG蓝图元素,获取并为带“PCG_EXCLUDE”标签的每个Actor创建一个点。这些被标记的Actor是位于区域入口和出口的体积,然后通过“差集(Difference)”节点创建空地。


●位于可选的大型Assembly下方的点使用“差集(Difference)”节点中的采样表面点删除。


●此外,浅水滩是使用另一个样条取样器,以固定的世界空间网格模式生成的静态网格体,覆盖整片区域。

 

图片

图片

计算与样条的距离并重新定点

 

图片

要想创建效果逼真的河床,必须计算表面点到边缘的距离,将它们转换为距离场。


第一组采样操作结束后:

●针对样条:合并采样点数据,计算从表面点到这些点的距离.


●识别、选择和筛选可选大型Assembly区域周围的表面点。


●使用自定义PCG蓝图元素“LookAt”在大型Assembly样条周围重新定位被选中的点,以匹配其形状。

 

图片

图片

通过生成地表网格体填充区域

 

图片


计算出与边缘的距离后,就可以通过逐渐降低远离边缘的点,将表面变为河床。距离信息还可以用于选择要生成的对象,方向则根据曲线输入确定。


从单边开始,合并距离流结束后:

●河床的形状过程是通过一系列Attribute数学运算节点,写入每个点的$Position.zProperty,降低点的高度。

 

图片


●基于到边缘的距离,通过使用“密度筛选器(Density Filter)”、“密度噪点(Density Noise)”、“自我裁剪(Self Pruning)”和“变换点(Transform Points)”节点,点已经准备好在多个流中生成“静态网格体生成器”节点中设置的特定静态网格体,以实现想要的河床视觉效果。


图片

图片


添加中央Assembly、枯树和动态岩石Actor

 

图片


河床的中心区域默认由多个Assembly自然形成,这些Assembly是通过Ground图表中的自定义逻辑程序化生成的。在图表的这一部分,表面还将分布额外的细节,例如枯树和动态岩石Actor。


在表面上重复使用原始采样和变换后的点:

●当场景中存在大型Assembly时,中心区域逻辑会受到影响,通过第二个“差集(Difference)”节点防止大型Assembly的样条表面点增加。此步骤可确保中心区域逻辑不会与大型Assembly重叠。


●“复制点(Copy Points)”节点的目标点按照相同的距离和密度运算逻辑准备。这些复制点节点的源输入是使用Level to PCG资产工具(见工具部分的描述)导出为PCG设置资产的Assembly。


●最终获得的Assembly点数据副本使用特定的Actor标签Attribute进行筛选,在这个例子中是“Rocks”和“Clutter”。在密度筛选器之后使用密度噪点,为生成的每个Assembly输出不同的结果,可以大幅减少视觉重复。


●动态岩石在使用“世界射线命中查询(World Ray Hit Query)”的输出生成的河床表面上生成,使用“投射(Projection)”节点投射。动态岩石是使用“生成Actor(Spawn Actor)”节点生成的预构建蓝图模板,设为“无合并(No Merging)”。使用“点匹配和设置(PointMatchAndSet)”节点以及“点筛选(Point Filtering)”选择不同的模板并与每个点关联。

 

图片

图片


自行通过“世界射线命中(World Ray Hit)”生成三叶草和检测平坦区域

 

图片


最后,Ground图表会生成三叶草地。

●三叶草点使用与动态岩石相同的“世界射线命中”方法投射到地表上。


●基于点法向量的第一轮筛选操作是为了防止投影发生后,在陡坡上生成三叶草。


●第二轮筛选是为了检测平坦区域,使用了“DiscardPointsInBumpyAreas”子图,参见自定义节点和子图部分了解更多内容。平坦区域检测对生成三叶草草地这样的对象来说至关重要,避免产生漂浮的问题。


●最后,使用“静态网格体生成器(Static Mesh Spawner)”节点在剩余的点上生成三叶草草地。


附加信息

强制执行依赖

 

图片


在Ground图表中,有两个红色注释框,标题为“WorldRayHit 排序的强制依赖”。其中包含为依赖的下游操作强行实施图表执行顺序的方法。


在这两种情况下,对于这个图表来说,来自“World Ray Hit Query”的依赖必须对生成的网格体发出射线,而这些网格体都是由同一个图表在上游生成的。


“集成(Gather)”节点用于强制执行所需数据的依赖关系,后面跟着一个“按标签筛选(Filter by Tag)”节点,该节点只保留需要的数据。


车辆排除

 

图片


在GDC 2023上展示《Electric Dreams》演示项目时,我们在PIE(在编辑器中运行)会话中为大家现场演示了PCG框架,演示车辆在程序化环境中运行。地表规则生成的动态岩石,如果在车辆碰撞范围内生成,可能会影响车辆的物理效果和稳定性。


为了防止出现这样的问题,我们使用“获取Actor数据(Get Actor Data)”节点和载具边界创建了一个PCG点。最终得到的点会从待生成的动态岩石点中减去。这种方法也可以用于满足其他游戏内特定要求,例如防止资产在玩家上面生成。


Ditch

 

图片

图片


描述

Ditch图表主要用于创建堤墙以及干河与周围高度场地形之间的区域,包括相应细节。使用Assembly关卡生成PCG设置资产,DitchPCG图表会利用这些资产填充场景。


设置

Ditch程序化生成依赖以下条件:

●样条,其组件标记“Active_Spline”

●从父项蓝图Actor中公开的参数

●用于执行Ditch图表的PCG组件


Ditch图表位于:

●/Game/PCG/Graphs/Ditch/PCGDemo_Ditch


一个子样条标记正确的自包含式蓝图Actor,包含用于执行Ditch图表的PCG组件和公开的参数,位于:

●/Game/PCG/Graphs/Ditch/PCGDemo_DitchBP

该蓝图可以直接拖入关卡,用于生成堤墙和周围的细节。

 

图片

这些都是公开变量,可以控制“PCGDemo_DitchBP”资产中的种子和道具密度参数。


《Electric Dreams》环境示例项目中已经包含Ditch规则的关卡:

●ElectricDreams_Env:/Game/Levels/ElectricDreams_Env

●ElectricDreams_PCG:/Game/Levels/PCG/ElectricDreams_PCG

●ElectricDreams_PCGCloseRange:/Game/Levels/PCG/ElectricDreams_PCGCloseRange'

●ElectricDreams_PCGDitchAssembly:/Game/Levels/PCG/Breakdown_Levels/ElectricDreams_PCGDitchAssembly


逻辑

图表概览


图片


Ditch图表包含4个不同的部分:

1 - Ditch Embankment

这部分图表主要用于放置堤墙Assembly,通过各种Assembly杂物Actor道具的变换变化和密度强化堤墙的外观效果。


2 - Ditch Embankment Tree & Rocks

这部分图表主要用于在堤墙周围放置树木和岩石资产,填充干河与周围地形(由PCG森林图表生成)之间的区域。


3 - Ditch Embankment Connection to Landscape

这部分图表将在堤墙周围创造一片虚假的地面,用于添加次要的树木和岩石装饰,这片地面跨越堤墙Assembly和干河周围高度场地形之间的间隙。


4 - Ditch Dirt Decal

这部分图表旨在填充贴花Actor,以便更好地将堤墙Assembly底部与干河床(由地表PCG规则生成)内部地表混合在一起。


图片