Blend Modes Reference
Texturge Beta defines blending between every glyph animation layer through the ETextAnimationBlendMode enum. Blending executes per channel in FPerLayerCurves::Evaluate; each FBakedGlyph holds a layer-organized TArray<FPerLayerCurves> (each layer with its own BlendMode).
Mode Overview
| Enum value | Name | Behavior | Typical scenario |
|---|---|---|---|
Additive | additive blending | current layer value added to the accumulated result | effect stacking (shake + swing) |
Override | override blending | current layer value replaces the accumulated result | mutually exclusive style switching / base layer |
Multiply | multiply blending | current layer value multiplied with the accumulated result | intensity modulation (fade × bounce) |
CrossFade | cross fade | interpolates with the accumulated result at a fixed weight | blend transitions |
Per-Mode Details
Additive
Result[channel] = Accumulated[channel] + CurrentLayer[channel]
- Later layers accumulate on top of all previous layers
- Suitable for combining multiple effects; multi-layer Additive is the common combination pattern in the preset library (Bounce / Shake etc.)
NOTE
Multi-layer Additive accumulation can push values beyond reasonable ranges; control amplitudes in your animation curves.
Override
Result[channel] = CurrentLayer[channel]
- Completely replaces the accumulated result
- Usually used as the base layer (specified in
CreateLayer); later layers use it only when full replacement is needed
Multiply
Result[channel] = Accumulated[channel] × CurrentLayer[channel]
- Scales or attenuates upstream layer effects
- Channel value 1.0 leaves the upstream result unchanged; 0.0 fully eliminates it
CrossFade
Result[channel] = Lerp(Accumulated[channel], CurrentLayer[channel], 0.5f)
Per-Channel Evaluation Semantics
FPerLayerCurves::Evaluate(float LocalTime, FGlyphAnimationState& InOutState) processes every curve channel independently:
- Empty channels skipped — channels with
Keys.Num() == 0do not participate, preserving existingInOutStatevalues. This guarantees no cross-layer contamination: Layer[0] has ScaleX but no Opacity, Layer[1] has Opacity but no ScaleX → final ScaleX comes from Layer[0], Opacity from Layer[1] - Non-empty channels first build a temporary
FRichCurve,Eval(LocalTime), then combine by this layer’s BlendMode - Combination proceeds layer by layer starting from
FGlyphAnimationState::Identity()
Per-layer combination example:
OutState = Identity()
Layer[0] (Override) → OutState.PositionOffset = (10, 0), Scale = (1, 1)
Layer[1] (Additive) → OutState.PositionOffset += (5, 5) → (15, 5)
Layer[2] (Multiply) → OutState.Scale *= (1.2, 1.0) → (1.2, 1)
Final: PositionOffset=(15, 5), Scale=(1.2, 1)
NOTE
A single
FPerLayerCurveshas only one BlendMode (applied to all non-empty channels); there is no per-channel independent BlendMode. Split into multiple layers when different blending semantics are needed.
Tint Channel Stacking Rules
Color channels (Color / ShadowColor) blend differently from other channels:
- The tint identity is
Transparent (0,0,0,0); applying the multiply rule0 × anything = 0would permanently tint black - Therefore tint channels use additive stacking:
Base.Color += Layer.Color(consistent with the bake pipeline, fixed in 0.4.0) - Multi-layer tinting controls intensity through the A channel (tint share):
A=1.0fully tinted,A=0.51:1 with the text color
Visual Comparison Table
| Scenario | Additive | Override | Multiply | CrossFade |
|---|---|---|---|---|
| Offset stacking | shake + swing → compound offset | keep swing offset only | shake × swing → reduced offset | fixed 0.5 interpolation |
| Color blending | tints stack → brighter/stronger | keep top tint only | not applicable to tint (identity-0 trap) | fixed 0.5 interpolation |
| Scale modulation | scale up + down → cancel out | keep down-scale only | scale up × 0.5 → half scale | fixed 0.5 interpolation |
Interaction with Stage Transitions
Stage transitions are configured by UTextAnimationBlueprint::StageTransitionConfig (FStageTransitionConfig):
| Field | Default | Description |
|---|---|---|
IntroToDefaultCrossFade | 0.1 | intro → default transition duration (seconds) |
DefaultToOutroCrossFade | 0.1 | default → outro transition duration (seconds) |
EasingFunc | EEasingFunc::Linear | transition easing function |
Layer hierarchy:
Glyph render state
└─ FBakedGlyph::Evaluate —— per-layer blending (ETextAnimationBlendMode, within a layer)
└─ UTextAnimationStageController —— stage transitions (FStageTransitionConfig, across stages)