Electric Dreams PCG技术详解(四)——远景、雾气、自定义节点及子图表

图片


资产变化


图片


这一步完全由

PCGDemo_Background_VariantsSubGraph完成。它的主要任务是,将你在放置步骤中生成的每个点,分配给两个PCG设置资产,以供选择。

  • 子图表的“In”输入从前一个步骤(点的放置)获取点。
  • 这个子图表有两个“源变体(SourceVariant)”输入,两个输入分别连接一个PCG设置资产,代表被树木覆盖的岩石。
  • “设置(Settings)”输入连接相同的CurrentSettings_Far属性集(控制前面的放置步骤),用于控制子图表的输出。
  • “参考点(ReferencePoint)”输入提供“Global_WorldOrigin”向量参数。


图片

PCGDemo_Background_VariantsSubGraph的布局。


图片

PCGDemo_Background_VariantsSubGraph的输出。


这个子图表主要通过将源点(PCG设置资产点)分配给目标点(通过放置步骤获得的堆叠点)执行复制点(Copy Points)操作。


鉴于这个图表知道它需要生成的资产组合以及它们的最终位置,它可以根据资产位置和太阳方向,为材质覆盖准备和保存元数据属性,从而为植被资产添加变化。


最后它还进行了优化,通过删除朝外部分山上的树木实例,删除了大约一半的树木实例。


为了实现这一目标,子图表将进行下列操作:

  • 根据Trees属性的值,将从PCG设置资产变体AB中获得点分为两组不同的点:TreesRocks

  • 根据一个随机值(密度噪点/点过滤),将从前一个步骤(“放置”)中获得点分为两组点:AB,作为复制点(Copy Points)的目标点。

  • 从资产变体AB获得的岩石点将立即被分别复制到输入点AB中。 

  • 从资产变体AB获得的树木点将分别经历密度噪点和密度筛选过程,在设置(Settings)属性集输入的控制下,控制树的覆盖。

  • 从资产变体AB获得的树木点将被分别赋予相应的属性,以设置树叶覆盖材质,通过点配对和设置(Point Match And Set)节点,为树木添加加权的颜色变化。

  • 计算输入点AB朝向太阳的方向并将结果存储为点的颜色属性。

  • 从资产变体AB获得的树木点被分别复制到输入点AB上,保留源于源点属性的材质覆盖和源于目标点颜色属性的太阳方向。

  • 每个树木复制点(Copy Points)节点输出的数据都将标记Tree标签,以便后续识别和筛选。


图片

  • 在更复杂的版本中,这个图表还有一个树木剔除步骤,用于删除不可见的树木:

    • 输入点AB将根据方向进行划分(Y轴向内 vs Y轴向外)

    • 从资产变体AB获得的树木点将基于其在源资产中的位置,按照Y值的符号进行划分。 

    • 使用额外的一组“复制点(Copy Points)”节点:

      • Y值为正的树木与Y轴向内的输入点相关。

      • Y值为负的树木与Y轴向外的输入点相关。


图片图片有和没有树木剔除



网格体生成


图片


这是最终生成岩石和树木的地方。


  • 通过树木复制点(Copy Point)节点PCGDemo_Background_VariantsSubGraph子图表中添加标签“Trees”,用于区分树木和岩石数据,并将它们输入不同的静态网格体生成器(Static Mesh Spawner)节点。

  • 树木点还将根据它们的颜色属性做进一步区分,颜色属性中保存着它们朝向太阳的方向,这一方向是在该子图表中计算得到的。

    • 使用这一颜色值(只使用红色通道),将朝向太阳的点输入对树木应用材质覆盖的静态网格体生成器(Static Mesh Spawner),使用材质(Material)元数据属性,使它们比阴影中的树木看起来更干一些。


图片


  • 所有树木都以ISM 生成,没有碰撞效果,对距离场光照没有影响。

  • 所有岩石都以ISM 生成,没有碰撞效果。



更远的远景

图片


更远的远景其实是一个PCG设置资产,通过将一个点放置在世界中,以实例化静态网格体的形式生成。
  • 远景的源关卡位于:

    /Game/PCG/Assets/PCGAssemblies/Background/VistaCliffs_01



附加信息

基于结构体的预设系统

背景规则使用和森林规则类似的基于蓝图结构体的系统来控制它从Actor蓝图获取的参数。

图片
图片
背景规则使用不同预设的示例

使用从Current Settings Near、Current Settings Mid和Current SettingsFar蓝图变量获得的值,通过“获取Actor属性(GetActorProperty)”节点控制PCG图表。


图片



PCGDemo_BackgroundBP使用了一个预设系统,可用的6个预设为:


图片


  • 每个预设都包含不同的数值,可以通过背景PCG图表生成不同的视觉效果。

  • 应用下一项设置(Apply Next Settings)按钮将在不同的设置间循环。每次点击这个按钮,下一项预设的数值就会被复制到Current Settings Near、Current Settings Mid和Current SettingsFar结构体变量中,PCG图表会自动更新。

  • 当前设置索引(Current Settings index)用于显示当前使用的预设。

  • 将当前设置复制到当前索引的已保存设置中(Copy Current Settings to Saved Settings at Current Index)按钮用于从当前设置更新当前预设。



PCG构建的PCG设置资产

图片


由“PCGDemo_Background”放置的PCG设置资产是使用PCG自己产生的。


  • 这些PCG设置资产的源关卡位于:

    /Game/PCG/Assets/PCGAssemblies/Background/

  • 其中包含手动放置的岩石结构和一个PCG体积,PCG体积使用简单的规则放置树木,使用“世界射线命中(World Ray Hit)”节点对岩石碰撞进行采样。

  • 最终生成的树木静态网格体和手动放置的岩石通过关卡到PCG资产实用工具导出为PCG设置资产。



DistanceToNeighbors(到相邻点的距离)

图片


PCGDemo_Background_PlacementSubGraph使用DistanceToNeighbors(到相邻点的距离)自定义蓝图节点定义哪些点是独立的或点集群的一部分。


  • 这个节点的工作原理是在用户指定的范围内,将输入的每个点投影到相同输入的多个点上。而这个范围由“Search Distance(搜索距离)”参数构建。

  • 一个源点在一组目标点上的投影结果是产生一个新的点,该点具有表示边界内所有目标点平均值的属性。

  • 在使用DistanceToNeighbors(到相邻点的距离)节点时,点对多点投影可以用来确定一个点在搜索距离内离相邻点的平均位置有多近。

  • 在特殊情况下,如果一个点的位置与其相邻点的平均位置完全相同,则可以认为在放置子图表(Placement Subgraph)中,输入点在测试边界(单个点的平均位置等于该点的位置)内单独存在,因此不是集群的一部分。

  • 还有一种方法,可以将点到其平均相邻点的3D距离写入元数据属性。这有助于确定点是否比相邻点高或低,对于检测点是否靠近悬崖边缘或位于山脚下来说非常有用。






雾气卡片

图片



描述

在背景山脉中放置雾气卡片是为了创建深度和远距离的叠层。雾气卡片PCG图表主要通过一系列属性操作来定义有效点的位置和设置点的变换。 


设置

雾气卡片程序化生成依赖以下条件:
  • 地形

  • 带Actor标签“Sunlight”的定向光源

  • 用于执行雾气卡片图表的PCG组件

  • 父项蓝图Actor的PCG体积或盒体碰撞组件,用于生成内容


雾气卡片图表位于:
  • /Game/PCG/Graphs/FX/PCGDemo_FogCards


独立的蓝图Actor(包含用于执行雾气卡片图表的PCG组件)和背景图表位于: 
  • /Game/PCG/Graphs/Forest/PCGDemo_BackgroundBP


《Electric Dreams》环境示例项目中已经包含雾气卡片规则的关卡:
  • ElectricDreams_Env:/Game/Levels/ElectricDreams_Env

  • ElectricDreams_PCG:/Game/Levels/PCG/ElectricDreams_PCG



逻辑


图表概览


图片



采样和根据定向光源放置点


图片


对地形表面进行采样,获得稀疏的网格阵列,准备初始雾气卡片点进行变换。

  • 使用“获取地形数据(Get Landscape Data)”和“获取Actor属性(Get Actor Properties)”节点为“表面采样器(Surface Sampler)”提供输入。种子由“PCGDemo_BackgroundBP”的“CurrentSettings_Far”结构中的变量驱动。


图片


  • “获取Actor数据(Get Actor Data)”节点通过“Sunlight”Actor标签检索定向光源太阳。

  • 使用属性向量运算(Dot)节点,根据阳光$Rotation.向上向量计算点$Rotation.向前向量,再将结果反转并写入$Density,然后进行筛选,并删除负值。

  • 剩余点的密度值将通过属性数学运算Pow,与Dot的运算结果进行对比,然后再进行筛选。


图片


  • 这部分提供的点按照太阳当前的照射方向将处于阴影中,这就是我们想放置雾气卡片的地方。



缩放、删除重叠、旋转和控制雾气卡片点的密度


图片


对雾气卡片点进行变换、重定向和剔除。


  • 将点的$Scale属性与在前面的操作中被复制到$Density值中的Dot结果相乘。越有可能被阳光照亮的点越小。

  • 使用“自我调整(Self Pruning)”节点删除重叠的点,以免雾气效果过重,避免雾气卡片重叠引起闪烁。


图片


  • 自定义PCG蓝图元素“Look At(看向)”会旋转所有雾气卡片点,使它们朝向世界中心。参见工具部分了解Look At的详细说明。


图片


  • 自定义PCG蓝图元素“Distance to Density(距离到密度)”会使用雾气卡片点到世界中心的距离重置密度值。新的密度值将使用“密度过滤器(Density Filter)”进行筛选,剔除位于世界中心的点,这些点会与山下的森林和手动放置的区域重叠。


图片



最后的缩放、位置调整和生成


图片


在生成雾气卡片网格体之前,对点的变换做最后的调整。

  • 再对阳光$Rotation.向前向量进行一次Dot运算,但这次先使用$Rotation.右向量将点转向世界中心再进行计算。这将缩小面向太阳的雾气卡片。

图片


  • 重复使用Dot运算的结果,面向太阳的点降低。

  • 最后一部分操作将根据点与世界原点的距离来缩放点的大小。

图片


  • 完成最终的变换和生成,在山脉和远景范围内的阴影区域集中生成雾气卡片,基于阳光的方向与世界中心对齐。


图片图片不使用/使用雾气卡片



自定义节点和子图表




PCG自定义节点和子图表旨在满足《Electric Dreams》中的PCG图表的特定要求。

SG_CopyPointsWithHierarchy和应用层级结构(ApplyHierarchy)


图片

描述

“SG_CopyPointsWithHierarchy”以及
“ApplyHierarchy(应用层级结构)”节点与使用关卡到PCG资产实用工具创建的PCG设置资产一起使用。

这些节点都用于设置点的层级结构,方式和设置关卡中的Actor的层级结构类似:点可以继承其父点的变换。

例如,使用这个功能,表示树干的点可以随机旋转和缩放,它们的子点,也就是表示树枝的点会自动跟随父点进行变换,然后在此基础上叠加它们自己的随机旋转或缩放效果。

点还可以用“点过滤(PointFilter)”删除,它们的子点也会自动删除,这可以用于为复杂的点设置添加随机变化。



设置

两个节点都显示在《Electric Dreams》项目的节点控制板中,也可以在图表区域通过PCG编辑器的上下文菜单获取。

SG_CopyPointsWithHierarchy子图表位于:
Game/PCG/Assets/PCGCustomNodes/SG_CopyPointsWithHierarchy

ApplyHierarchy(应用层级结构)自定义节点位于:
/Game/PCG/Assets/PCGCustomNodes/ApplyHierarchy

下列PCG图表使用这些节点:
  • /Game/PCG/Graphs/Ditch/PCGDemo_DitchBP

  • /Game/PCG/Graphs/Ground/PCGDemo_GroundBP

  • /Game/PCG/Assets/BP_PCG_LargeAssembly

  • /Game/Levels/PCG/Breakdown_Levels/ElectricDreams_PCGSplineExample



用法


图片

层级结构节点在PCG图表中的典型用法


典型用法:

1. 使用关卡到PCG资产实用工具将关卡转换为包含PCGPoints的PCG设置资产,并将相关场景的层级结构信息存储为元数据属性。
2. 使用SG_CopyPointsWithHierarchy子图表和目标点变换在多个位置复制PCG设置资产,类似于复制点(CopyPoints)节点,但也要保持和偏离层级结构属性值,确保父项信息对原始资产点的每个副本来说都是唯一的。
3. 使用点过滤(PointFilter)节点按属性选择点。
4. 使用变换点(TransformPoints)节点以及“Apply To Attributes(应用到属性)”选项,变换选择点的相对变换属性。
5. 使用合并(Merge)节点重新合并同一数据流和同一层级结构中的所有点。
6. 使用ApplyHierarchy(应用层级结构)节点对点应用相对变换属性,结合父项变换。



由PCG设置节点产生的层级结构属性


图片

倒下的树PCG设置资产的层级结构属性视图


在将关卡Actor导出为PCG设置资产时,源关卡中的Actor层级结构信息使用元数据属性与每个PCG点相关联。

这些属性包括: 
  • Actor索引(ActorIndex)(整型):为点提供独特的标识符。

  • 父项Actor索引(ParentActorIndex)(整型):识别点的父点。

  • 层级结构深度(HierarchyDepth)(整型):提示点在父子层级结构中的深度(点和根点之间存在多少父点)

  • 相对变换(RelativeTransform)(变换):点和其位于PCG设置资产源关卡中的父点的偏移变换。


层级结构的根用虚拟点表示,其层级结构深度值为0,Actor索引值为0,父项Actor索引值为-1,变换1个单位。

所有在源关卡层级结构中没有指定父项的点都是这个根点的子点,以免碰到孤点/根点的特殊情况。



由SG_CopyPointsWithHierarchy变换的层级结构属性:


图片

由SG_CopyPointsWithHierarchy产生的每个PCG资产副本的Actor和父项Actor索引。注意6个不同根点的Actor索引值。



图片

SG_CopyPointsWithHierarchy子图表


处理层级结构索引需要使用自定义版本的“复制点(Copy Points)”节点。它的作用是确保当一个点在寻找其父点时,该点与其已解析的父点都属于由“复制点(Copy Points)”节点产生的相同复制点/点集。
 
自定义“复制点(Copy Points)”节点以子图表的形式应用,其中包含:
  • 一个常规的复制点(Copy Points)节点。

  • 一个PostCopyPoints-OffsetIndices蓝图节点,负责为每个副本分配一组唯一的ID(由原始索引、副本编号和唯一的任务ID计算获得)。

  • 两个创建属性(Create Attribute)节点,用于将“忽略父项旋转(IgnoreParentRotation)”和“忽略父项缩放(IgnoreParentScale)”布尔属性初始化为False。



层级结构中的点操作


点被复制到由“SG_CopyPointsWithHierarchy”目标点指定的位置之后,可能会通过使用“点过滤(PointFilter)”节点,根据PCG设置资产中显示的属性筛选最终获得的点:


图片

PCGDemo_Ditch中筛选点,使用“Clutter”属性随机删除层级结构中的点。


图片

PCGDemo_Ditch中筛选点,使用“RotZ”属性随机旋转层级结构中的点。



在上述两个示例中,点是通过标签选择的,要么筛除,要么旋转,然后再与没有被“点过滤(PointFilter)”选中的点合并。


这里的合并(Merge)操作很重要,因为它将确保所有点,无论是否变换,都在相同的数据流中,并且可以在应用最终的变换时一起处理。


图片


如果在层级结构中使用变换点(Transform Points),必须要注意,变换不能直接应用到点的变换上,而是要应用到“相对变换(RelativeTransform)”属性上,使用Apply To Attribute(应用到属性)选项,输入RelativeTransform名称。


或者,如果想部分继承父点的变换,可以将“忽略父项旋转(IgnoreParentRotation)”和/或“忽略父项缩放(IgnoreParentScale)”属性设为True。


图片


最后,在生成网格体前,使用“ApplyHierarchy(应用层级结构)”节点。

这个节点的作用:
  • 按升序(从层级结构深度点属性解析获得)遍历现有的所有层级结构级别。

    • 根据其父项变换及其相对变换属性值计算点的最终变换。

    • 删除父项已被废弃的点。






Flat Area 检测器


图片



描述


这个子图表主要用于确定表面是否足够平坦,能够放置特定大小的点,以免资产错误放置,例如一部分漂浮在地面上。
  • 它可以在水平或倾斜的表面上发挥作用,围绕每个源点在4个不同的位置对表面进行采样。

  • 如果4个采样位置中的任何一个不与由输入点位置和方向定义的平面相交,则将废弃该等输入点。(上图蓝色部分)

  • 如果4个采样位置中任何一个位置的表面方向偏离输入点的方向,该等输入点也将被废弃。 


使用这个子图表的图表有:
  • /Game/PCG/Graphs/Ground/PCGDemo_Ground,用于在粗糙的岩石网格体表面放置三叶草草丛。

  • /Game/PCG/Graphs/Forest/PCGDemo_Forest,用于在地形上放置大型扁平石块和主要岩石装备件。


图片

大型扁平石块部分漂浮在地形上的示例。


图片

删除漂浮的扁平石块。



设置和用法


子图表位于:

/Game/PCG/Graphs/Forest/DiscardPointsInBumpyAreas


要在PCG图表中将子图表作为节点使用,需要将子图表从内容浏览器拖入PCG图表编辑器。


图片


引脚描述:

  • In(点):此引脚用于连接对表面进行测试的输入点。

  • InNoProjection(点):非强制性引脚。这是一个优化选项,如果输入点已经在表面上,它可以替代In引脚提供输入点。

  • ProjectionTarget(表面):此引脚需连接必须评估平整度的表面。它可以是由“获取地形数据(Get Landscape Data)”或“世界射线命中(World Ray Hit)”节点生成的表面。

  • SampleDistance(属性集-双精度浮点型):获取浮点/双精度浮点属性输入。可以由“创建属性(Create Attribute)”节点提供,控制每个源点和用于探测表面的采样点之间的距离。上图中以蓝色方框的XY范围表示。

  • HeightThreshold(属性集-双精度浮点型):获取浮点/双精度浮点属性输入。可以由“创建属性(Create Attribute)”节点提供。与蓝色方框表面的距离超过这一数值的采样点将被视为不在平面内,并将用于删除输入点。不在平面内的点在上图中以红色表示。

  • NormalThreshold(属性集-双精度浮点型):获取浮点/双精度浮点属性输入。可以由“创建属性(Create Attribute)”节点提供。用于控制多少采样点的向上向量可能偏离输入点的向上向量,再用于删除输入点。这个值必须为负数,使用更小/更接近零的值会删除更多的点。

  • Out:通过高度与法线测试的剩余点。



子图表概览


图片


图片


使用属性数学运算和变换点(Transform Points)节点创建4个采样点。
  • 采样点被放在围绕每个输入点的一个2D方框中。 

  • 方框大小由“SampleDistance(采样距离)”属性决定。

  • 每个采样点的边界由“HeightThreshold(高度阈值)”属性决定。


图片


使用属性数学运算,根据“SampleDistance(采样距离)”属性构建蓝色平面范围(其实是一个平面点)。


图片


将4个采样点投影到表面上(位置+方向),计算这些投影点和蓝色平面的差异。“差异(Difference)”节点会输出位于平面外的点。


重要提示:启用这3个节点的调试状态可以显示蓝色平面,4个采样点为绿色,与蓝色平面不相交的采样点为红色,如上图所示。


图片


这一部分预估采样点方向变化。


从输入点创建一个点,按照“NormalThreshold(法线阈值)”沿其向上向量负向平移。(下图中以实心蓝色平面表示)


计算这个点和平面采样点的交集,与表面法线对齐(蓝色线框)


图片图片


第一张图表示“NormalThreshold(法线阈值)”为-300,将实心蓝色平面沿其向上向量向下移动。


第二张图表示“NormalThreshold(法线阈值)”为-10,使用这个值,通过交集计算输出一个点,以红色三角轴显示。


这表示我们可以基于采样点方向的变化,使用“NormalThreshold(法线阈值)”来控制交集运算的输出。(平行采样点/平面只有在法线阈值为0时才会与实心蓝点相交)


图片


最后,从这两个测试中得到的点将被扩大,作为与输入点的差异来筛选输入点,只留下符合所提供参数的点。






Look At(看向)


图片


描述


自定义蓝图元素“LookAt”作为三维向量属性,用于将点重定向到目标点。这个属性可以通过属性数学运算和距离节点创建。


在《Electric Dreams》中,地面规则使用这个属性,根据大型Assembly的样条来重新为点定向,以实现想要的河床效果。它还被用于旋转雾气卡片点,使其朝向雾气卡片和森林图表中的区域中点。



设置


这个自定义PCG蓝图元素位于:

/Game/PCG/Assets/PCGCustomNodes/LookAt



用法

LookAt节点会迭代单个点数据输入并使用三维向量属性,让各个点朝向目标坐标轴。


图片


  • 创建点数据

  • 使用“添加属性(AddAttribute)”节点,设为“形成源参数”,为你的点数据添加新的“LookAt”属性。

  • 通过下列任意选项覆盖“属性(Attributes)”:

    • 创建属性(Create Attribute)节点,类型为向量,设置你的LookAt坐标轴

    • 获取Actor属性(Get Actor Property)节点,获取蓝图三维向量变量(可以公开以便自定义)

    • 在图表设置中创建一个PCG三维向量图表参数,在图表中获取“参数名称”,在每个图表实例上公开该名称,使其在每个PCG组件上可供编辑。

  • 设置LookAt节点

    • LookAt目标 = 要使用的属性名称 

    • 2D LookAt = 忽略Z组件

    • 前向X = LookAt使用X轴而非Y


图片