图层混合模式
ETextAnimationBlendMode 枚举定义 FPerLayerCurves 求值结果合并到 FGlyphAnimationState 时的运算方式。混合在 FPerLayerCurves::Evaluate 内部按通道粒度执行,逐层组合发生在 FBakedGlyph::Evaluate。
四种混合模式
Additive(加法混合)
将当前层的通道值累加到已有状态上:
OutState.Channel += LayerResult.Channel
适用场景:
- 抖动效果叠加(位置抖动 + 旋转抖动)
- 多动画组合(基础位移动画 + 额外波浪动画)
// 基础层设定位置,叠加层添加随机抖动
BaseLayer: PositionOffset.X = 100 → 200 // 从左到右
ShakeLayer: PositionOffset.X = -5 → +5 // Additive → 实际位置 = 95 → 205
Override(覆盖混合)
用当前层通道值直接替换已有状态(基础层通常使用):
OutState.Channel = LayerResult.Channel
适用场景:
- 第一层设定基准变换(
CreateLayer(..., Override, ...)是默认实现的基础层模式) - 某层需要绝对控制特定通道
Multiply(乘法混合)
将当前层通道值与已有状态相乘:
OutState.Channel *= LayerResult.Channel
适用场景:
- 强度调制(全局透明度包络)
- 渐隐渐显控制(通道值为 1.0 不影响,0.0 完全消除)
CrossFade(交叉淡化)
OutState.Channel = Lerp(OutState.Channel, LayerResult.Channel, 0.5f)
逐通道求值语义
FPerLayerCurves::Evaluate(float LocalTime, FGlyphAnimationState& InOutState) 的内部流程:
- 对 21 条通道逐一检查:
Keys.Num() == 0的空通道直接跳过,保留InOutState已有值 - 非空通道临时构建
FRichCurve,在LocalTime插值求值 - 按本层
BlendMode将值组合到InOutState:
for Channel in 21 条非空通道:
Value = CurveEval(Channel, LocalTime)
switch BlendMode:
Additive: InOutState[Channel] += Value
Override: InOutState[Channel] = Value
Multiply: InOutState[Channel] *= Value
CrossFade: InOutState[Channel] = Lerp(Out, Value, 0.5f)
NOTE
层间无交叉污染:Layer[0] 有 ScaleX 但无 Opacity、Layer[1] 有 Opacity 但无 ScaleX → 最终 ScaleX 来自 Layer[0],Opacity 来自 Layer[1]。
染色通道特殊规则
Color / ShadowColor 通道的恒等值为 Transparent (0,0,0,0)。若按乘法规则 0 × 任意 = 0 会永久染黑,因此染色通道使用加性叠色(Base.Color += Layer.Color,与烘焙管线一致)。多层染色通过 A 通道(染色占比)控制强度。
NOTE
染色渲染使用 Pigment-Based Mixing(PBM) 物理颜料混色(
ApplyTint)——基于 Kubelka–Munk(K–M)双流理论、常数参考标定于 Mixbox 2.0 的实时 RGB 颜料混色:黄+蓝变绿、互补色混合产生泥色(橄榄/棕/暗紫)而非灰色、深色加白得到饱和浅色。无查找表、O(1) 常数时间。
多层混合示例
Layer 0: Override — 设定基准位置、缩放、颜色
Layer 1: Additive — 添加微小的位置与旋转抖动
Layer 2: Multiply — 全局透明度包络
Layer 3: Additive — 阴影偏移动画
FBakedGlyph::Evaluate 从 FGlyphAnimationState::Identity() 开始按索引顺序组合各层,FactoryOverride 在全部层混合后整体应用一次。
设计建议
TIP
以下设计建议帮助你有效组织图层混合:
- 首层使用 Override 建立基准值,避免意外叠加
- 中间层使用 Additive 叠加辅助动画,便于独立调整
- 尾层使用 Multiply 进行全局调制,如统一淡入淡出
- 染色层注意乘除陷阱:染色恒等值为 (0,0,0,0),Multiply/Divide 染色会得到错误结果,应使用 Additive 叠色或通过 A 通道(占比)控制