Compositing, layers, and effects
Rune Engine treats compositing as snapshot metadata. The submitted root and ordinary child snapshots can isolate opacity or blur as one flattened image. A child boundary can additionally flatten into a projected 3D plane before it is drawn back into the parent.
Mental model
CMD_DRAW_CHILD boundary
root snapshot -> optional root opacity / root blur
child CMD_DRAW_CHILD boundary
-> inspect child snapshot metadata
-> choose direct replay, opacity layer, blur capture, or 3D capture
-> draw one composed result in painter orderResponsibilities and boundaries
- Commands decide where child content appears in painter order.
- Snapshot metadata decides whether that child is direct, opacity-isolated, motion-blurred, or projected as Layer 3D.
- Root metadata can isolate the complete submitted scene with group opacity or capture it for the same analytical 2D motion-blur treatment.
- Ancestor transforms and clips stay outside the captured subtree and apply to the final composed result.
Stable current behavior
Group opacity is a boundary property
group_opacity is applied once at the child boundary, not redistributed to every descendant. Without blur, opacity below one wraps direct replay in a D2D layer. With blur or 3D capture, opacity surrounds the final DrawImage result. The submitted root follows the same one-time opacity rule around the complete root result.
Motion blur samples history analytically
For ordinary layers and the submitted root, replay resolves the same snapshot twice:
- once at the current frame time
- once at
t - exposure
The difference between those resolved presentations produces one blur vector. Because the same snapshot is sampled analytically, blur works with retargeted animations, expression outputs, and path followers without preserving per-frame simulation state.
Layer 3D is flatten-then-project
An active 3D layer:
- captures its subtree into a command list,
- projects that flattened image with
CLSID_D2D13DTransform, - optionally applies post-projection directional blur, and
- draws the final image once in painter order.
There is no depth buffer or Z sorting. Layer 3D is still one painter-ordered image at the child boundary.
Whole-frame rendering stays explicit
On every non-skipped frame, the current backend clears the whole target and replays the whole submitted root. Layer bounds help source capture and transient allocation, but they are not a damage-tracking system.
Current limitations
- Active root Layer 3D is unsupported and skipped.
- An active 3D layer cannot contain another active 3D descendant or an ordinary descendant with active motion blur.
- Motion blur uses one directional kernel, so rotations with corners moving in different directions are approximated by the strongest projected motion.
blend_modeandcache_hintare stored on snapshots today, but the current audited backend does not change output for them.
How the pieces connect
Compositing begins when recording publishes child boundaries and layer metadata. Commit freezes that metadata beside immutable child slots. Replay then decides at each child boundary whether to recurse directly or flatten into an image first.
Root isolation handles whole-scene opacity or blur before presentation. Child boundaries add painter-ordered isolation and optional 3D projection. Together, that arrangement lets Story layer systems, camera scenes, Layer 3D samples, and motion-blurred presentations reuse the same snapshot tree and frame clock without inventing a separate scene graph for effects.