PCG 常用节点记录
比较随意的记录。
约定一些术语表达
中文翻译 | 原文 | 说明 |
---|---|---|
属性 | Attribute | 每个输出都有自己的属性,可以理解为表头 |
属性行 | Point Data / Metadata | 同一个输出里都有相同的表头,但数据不一样,多个Point就有多行 |
属性集(表) | Attribute Set | 属性 + 全部属性行 形成的一张表格 |
集组 | Attribute Sets / Attributes | 属性集作为元素的数组 |
Merge 合并
是把多个属性集合并成一个属性集。
//类似数组合并
merge([a,a] ,[b]) = [a,a,b]
Reduce 归约
归约支持多个模式,sum,average,max,min,Join
//类似函数式编程里的reduce
reduce([a,b,c],Math::Sum) = a + b + c
- Merger Output Attributes: 用于把集组合并成单一的属性集
Copy Points
这是很迷惑的名字,直面意思是复制点,实际上的意思大概是:
Copy Points 节点是PCG系统中一个重要的点操作节点,其主要功能是将源点(Source Points)复制到目标点(Target Points)上。这个节点最常见的使用场景是:以相对位置的方式,将输入源的点附加到目标点上,其中目标点作为输入源点的轴心点(Pivot)。
详细用法参考B站Up ZzxxH 总结的图:
详细说明
点的复制模式
- 笛卡尔积模式 (bCopyEachSourceOnEveryTarget = true)
NumIterations = NumSources * NumTargets;
const int32 SourceIndex = i / NumTargets;
const int32 TargetIndex = i % NumTargets;
- 每个源点都会复制到每个目标点上
- 产生 N * M 个输出点
- 一对一模式 (bCopyEachSourceOnEveryTarget = false)
if (NumSources != NumTargets && NumSources != 1 && NumTargets != 1)
{
// 报错:只支持 N:N, 1:N 和 N:1 操作
}
NumIterations = FMath::Max(NumSources, NumTargets);
- 支持 N:N, 1:N 和 N:1 的映射关系
- 产生 max(N, M) 个输出点
元数据处理
- 元数据继承模式
// 五种模式
SourceFirst // 优先源点元数据,添加目标点独有属性
TargetFirst // 优先目标点元数据,添加源点独有属性
SourceOnly // 仅使用源点元数据
TargetOnly // 仅使用目标点元数据
None // 不使用元数据
- 属性合并优化
// 使用并行处理来设置属性值
ParallelFor(AttributeCountInCurrentDispatch, [&](int32 WorkerIndex) {
FPCGMetadataAttributeBase* Attribute = AttributesToSet[AttributeOffset + WorkerIndex];
Attribute->SetValuesFromValueKeys(Values, false);
});
Attribute Partition 属性分组
这个其实就是 函数式编程里的 GroupBy
, 根据输入的属性值进行归组
// 类似GroupBy`操作
GroupBy([{id:1, type:"A"}, {id:2, type:"A"}, {id:3, type:"B"}], "type") = {
"A": [{id:1, type:"A"}, {id:2, type:"A"}],
"B": [{id:3, type:"B"}]
}
- Assign Index Partition : 分配一个序号
Filter Data By Index 和 FilterElementsByIndex
Filter Data By Index节点有个输出,选中的 和 未选中的
名字里的Data是集组的意思,该节点用于在集组里面筛选出自己要的 属性集
如果要获取属性集里的点数据,可以使用 FilterElementsByIndex
但FilterElementsByIndex 节点只输出 选中的
都支持选中语法:
- 8 (返回索引为8的值)
- 1:8 (返回索引1到7的值)
- :8 (返回索引0到7的值)
- -1 (返回倒数第一个值)
- -8: (返回倒数第8到倒数第1)
- 1:5,10:15 (返回索引1到5,索引10到15的值)
Grammar相关节点
Attract 吸附节点
给定一个搜索距离,寻找最近或者的的远的点
支持3个吸引模式:
- Closest Mode
- 功能:将源点吸引到最近的目标点
- 实现原理:在指定搜索半径内使用点的Position(Transform.Location)计算欧几里得距离
- 使用场景:需要简单的就近吸引时使用
- MinAttribute Mode
- 功能:吸引到属性值最小的目标点
- 实现原理:在搜索半径内比较目标点的指定属性值,选择最小值
- 支持任何可比较的属性类型
- 使用场景:例如将物体吸引到最低高度的位置
- MaxAttribute Mode
- 功能:吸引到属性值最大的目标点
- 实现原理:在搜索半径内比较目标点的指定属性值,选择最大值
- 支持任何可比较的属性类型
- 使用场景:例如将物体吸引到密度最大的区域
(目前应该是有bug,选择MinAttribute和MaxAttribute的时候,设置了可以比大小的属性,但还是没有效果。)
所以通常还是用Closest Mode, 使用weight控制位置插值,weight越大,插值越近目标值。
源码:OutputValue = FMath::Lerp(SourceValue, TargetValue, Alpha);
alpha 就是 weight。
使用weight的时候,这个配置不能没有:
参数
Distance
: 搜索半径,决定吸引的作用范围Weight
: 吸引强度(0-1)- 0: 保持在原始位置(不吸引)
- 1: 完全吸引到目标位置
bRemoveUnattractedPoints
: 是否移除未被吸引的点TargetAttribute
: MinAttribute和MaxAttribute模式下用于比较的属性SourceWeightAttribute
/TargetWeightAttribute
: 源点和目标点的权重属性
Difference 差集
Intersection 交集
可以添加多个secondary input
主输入(Primary Input)
- 主要输入
Primary Input Pin
是交集计算的起点,每个输入都会被单独计算。 - 每个主输入的数据会与所有其他输入进行交集计算,并生成新的空间数据。
- 主要输入
次要输入(Secondary Input)
- 所有次要输入数据默认会被自动联合(unioned),然后才与主输入进行交集计算。
- 例如:
- 输入 A(主输入)
- 输入 B1、B2、B3(次要输入)
- 在计算时,B1、B2、B3 会先合并成一个整体 B,然后
A ∩ (B1 ∪ B2 ∪ B3)
进行交集计算。
空数据处理
- 如果某个输入为空(无数据),默认情况下,该输入会返回空结果。
- 但如果勾选了
Ignore Empty Secondary Input
,那么空的次要输入将不会影响计算,而是会跳过它们。