Bake Pipeline Overview
Texturge’s bake pipeline compiles a UTextAnimationBlueprint and the given text into precomputed FBakedAnimation data. Baking happens on demand (widget initialization, text changes, after Blueprint compilation); runtime only performs efficient evaluation.
NOTE
Texturge has no font → SDF texture bake pipeline. The animation compilation pipeline processes per-glyph curve data and does not involve GPU texture generation.
Pipeline Entry Point
FAnimationCompiler::BakeAllStages() is the single entry point of the bake pipeline:
struct TEXTURGE_API FAnimationCompiler
{
static constexpr int32 MinFramesBetweenRebakes = 3;
using FAnimInstanceCustomizer = TFunction<void(UTextAnimInstance*)>;
static FBakedAnimation BakeAllStages(
UTextAnimationBlueprint* Blueprint,
const FString& Text,
const FAnimInstanceCustomizer& InstanceCustomizer = nullptr);
};
The third parameter InstanceCustomizer injects into the temporary bake instance (e.g. applying parameter overrides); the Blueprint CDO is never modified.
Pipeline Stages
Stage 1: Building Schedule Infos
BuildScheduleInfos(Text)iterates all Unicode code points of the text, generatingTArray<FGlyphScheduleInfo>- Prefills each glyph’s index, string, and classification (Whitespace / Punctuation / CJK / Decorator)
- Classification is determined by the
Texturge::Unicodeutilities; surrogate pairs (Emoji) map to a single glyph
Stage 2: Blueprint Event Baking
- Creates a temporary
UTextAnimInstance(Blueprint->GeneratedClass) - If an
InstanceCustomizeris passed, applies it to the temporary instance first (parameter override injection point) ProcessEventinvokes the BP-overriddenBuildDefaultAnimation(GlyphCount, Text)- If the Blueprint override returns an invalid result, falls back to the C++ default
_Implementation:
BuildScheduleInfos(Text)
→ CreateLayer(GlyphAnimations[0], Override, Schedule) ← base layer
→ CreateFactory(BaseLayer, Schedule)
→ for i in 1..N: Factory->AddLayer(CreateLayer(GlyphAnimations[i], Additive, Schedule))
→ Factory->Bake() → FBakedStage
Stage 3: Factory Baking (UGlyphAnimationFactory::Bake)
Bake() returns FBakedStage and runs a three-step pipeline:
STEP 1: per-layer independent baking
for each Layer: BakeStageWithCurves(Layer.Curves, Layer.Schedule)
→ each Glyph gets a single-layer bake result
STEP 1.5: consume Layer-level ordered tweak steps
for each Layer: ApplyGlyphOverrideSteps(Layer.GlyphCurveOverrides)
→ execute Multiply/Divide/Add/Subtract on TArray<FRichCurveKey> in order
→ multiply/divide: Value/Tangent/Weight scaled proportionally (weighted Bezier tangents)
→ add/subtract: Value only
→ empty tracks: create identity key pairs from existing key time ranges
STEP 2: per-Glyph per-Layer copy
for each Glyph:
for each Layer:
SrcCurveSet.OffsetBy(LayerStartTime)
FBakedGlyph.AddLayer() → FPerLayerCurves
→ curves are not merged; each layer keeps independent curve data
STEP 3: factory-level global post-processing
3a: ApplyFactorySchedule(Skip/StartDelay) — acts on merged Glyph StartTime
3b: Factory.GlyphCurveOverrides baked into FBakedGlyph.FactoryOverride
→ applied once to the final blended state during evaluation
3c: animation clipping (SetAnimationClipAt) — front/back trim (playback axis)
→ skip bIsStatic Glyphs
NOTE
Animation clipping (0.3.0): layer- and factory-level
SetAnimationClipAt(FrontTrim, BackTrim)trims on the playback axis; finite loops are materialized as expansion (only the last loop is modified); fully-trimmed glyphs become static.
Stage 4: Assembling the Final Output
- Assemble
FBakedAnimation:DefaultStagecomes fromBuildDefaultAnimation;IntroStage/OutroStageare nullptr - Compute dual fingerprints:
TextFingerprint = CityHash64(SourceText),BlueprintFingerprint(see below) - Return
FBakedAnimation(move semantics, supports Double-Buffer publishing)
Fingerprint Caching
| Fingerprint | Computation | Invalidation |
|---|---|---|
TextFingerprint | CityHash64(SourceText) | text content changes |
BlueprintFingerprint | Hash of: path name + all GlyphAnimation asset signatures (MovieScene + GetSignature() of all Tracks/Sections) + all BlueprintVisible CDO property values + StageTransitionConfig + CompileCount + GeneratedClass pointer address | Blueprint recompile / parameter changes |
Key mechanisms:
- Track/Section signature traversal: Sequencer edits only update Section signatures, not the parent MovieScene signature — fingerprints must traverse all sub-objects
- CompileCount: a
uint32incremented on every compile, ensuring the fingerprint still changes when UE reuses compiled instances with unchanged addresses - Re-bake cooldown:
MinFramesBetweenRebakes = 3frames, preventing flood re-baking during parameter sweeps - Cache invalidation responsibility lives at the widget layer / editor preview layer (
FTexturgePreviewBakeCache); the compile time does not manage cache refresh policy
TIP
After modifying parameters via
SetBlueprintVariable, the fingerprint change triggers a re-bake, but subject to the 3-frame cooldown — high-frequency parameter sweeps take effect with at most a 3-frame delay.