Render follow-ups drain: UiTransform paint + degraded effect groups (R1–R2)#71
Closed
intendednull wants to merge 2 commits into
Closed
Render follow-ups drain: UiTransform paint + degraded effect groups (R1–R2)#71intendednull wants to merge 2 commits into
intendednull wants to merge 2 commits into
Conversation
Render now consumes the full 2D affine GlobalTransform already composed by the write_buiy_transform bridge, instead of dropping everything but translation — so a rotated/scaled UI element paints correctly instead of axis-aligned. extracted_node_for reads global_transform.affine().matrix3 xy columns into a new ExtractedNode.affine ([[f32;2];2]); it flows through PackedInstance, the bucket raw record (now [f32;17]), packed_to_raw, the prepare RawBufferVec, the quad vertex layout (stride 52->68, attrs at locations 8/9), and both quad + shadow WGSL (corner = rect_pos + mat2x2(affine) * box-local corner). PackedInstance constraint (campaign-review MAJOR, R2 depends on it): the affine basis is APPENDED after the existing 13 floats, so every existing field offset is unchanged — color stays float 4, alpha float 7. Named COLOR_FLOAT_OFFSET / ALPHA_FLOAT_OFFSET consts now name those offsets (R2's degraded-group re-tint reads alpha via ALPHA_FLOAT_OFFSET). Identity affine = [1,0,0,1] -> every existing pixel/test byte-identical; 4 instance hex snapshots re-blessed with the trailing identity floats. VertexOut slot 4 (rect_center, dead) becomes frag_logical = the affine-transformed window corner for the clip-AABB discard. GPU rotate/scale reftest added (#[ignore], compiles; human runs the GPU lane). Scope = transform-paint only. Residuals kept (NOT closed): transform-origin is a layout-side gap (compose_transform doesn't bake ui.origin, so elements pivot at top-left until that lands); skew / general TransformMatrix::Matrix are bounded by the bridge's TRS-only Transform::from_matrix decompose; perspective / Preserve3d / BackfaceVisibility stay C-tier deferred. clip-and-transform.md §B.5 + follow-ups.md narrowed to transform-paint LANDED with those residuals. Cross-crate: buiy_verify PackedInstance/ExtractedNode sites + 3 snapshot tests updated for the new field; clippy --workspace -D warnings clean; render suites + buiy_verify green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DHcf8nQ9PTT3m5E7u3Q6XV
A degraded effect group (plan_allocation == false under RT-pool budget pressure, no pooled target) previously had its members excluded from the flat draw AND skipped in the step-1 group pass, so its quads + glyphs painted nowhere (vanished). effect-compositor.md §2.3 mandates forward-compositing. prepare_effect_groups now, for each ROOT degraded group (parent == None), folds group.opacity into the ALPHA slot of every member instance in place and merges its quad + glyph ranges into the flat ranges, so the node's flat window draw paints them — the group dims exactly once instead of vanishing. Three correctness points (plan-review majors): - Scope = ROOT degraded only. A nested degraded child must composite into its PARENT's off-screen target, a different draw path (node-side) — conflating it with the window flat pass would paint in the wrong space/clip. Guarded by a debug_assert + filed as a new follow-up (render — nested degraded forward- composite into parent target). - Per-tier dirty gates: the alpha fold runs iff the corresponding BUFFER was repacked this frame (quad fold on quad_dirty, glyph fold on glyph_dirty — the buffer-repack signals, not the wider partition signal), else a retained already-folded buffer would re-multiply and drift to black. The glyph RANGE merge gates on the wider partition signal, kept distinct from the fold. - Glyph alpha is color[3] = float index 11 (new GLYPH_ALPHA_FLOAT_OFFSET in atlas/primitive.rs), NOT quad's ALPHA_FLOAT_OFFSET (7) — folding via the quad offset would corrupt glyph instances. Rebases on R1's PackedInstance layout (quad alpha via ALPHA_FLOAT_OFFSET). Latent today (64 MiB budget degrades nothing); fixtures force degradation via a small RtPoolBudget. GPU degraded-paint test #[ignore] (compiles). Fixed 4 rustdoc -D-warnings intra-doc link errors (pub(crate) prepare_effect_groups -> code spans; offset consts -> full-path links). Tests: buiy_core + buiy_verify 162 ok / 0 failed; fmt + clippy --workspace + doc --workspace clean. Final render-track slice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DHcf8nQ9PTT3m5E7u3Q6XV
acf7311 to
3908c06
Compare
Owner
Author
|
Superseded: this PR was built on Bevy 0.18, but main has since migrated to 0.19-rc (the BSN campaign, #72) which rewrote the render pipeline. R1 (UiTransform affine paint) and R2 (degraded effect groups) are being re-applied fresh on the 0.19 render code in a new PR (both gaps confirmed still open on 0.19; the design ports verbatim since 0.19 left PackedInstance + WGSL untouched). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second track of the follow-ups-drain campaign (
docs/plans/2026-06-18-followups-drain.md): the actionable render follow-ups. Two slices, sequenced because both touch the sharedPackedInstancefloat layout.Slices
37ec57aUiTransform affine paint (rotate + scale) — render now consumes the full 2D affine fromGlobalTransform(already composed by the transform bridge) instead of dropping all but translation, so rotated/scaled UI paints correctly. The affine basis is appended after the existing 13 floats so every field offset is unchanged (alpha stays float 7); namedCOLOR_FLOAT_OFFSET/ALPHA_FLOAT_OFFSETconsts. Identity affine → byte-identical to before. Quad + shadow WGSL transform the corner about box-local origin. GPU rotate/scale reftest (#[ignore]). Residuals kept (not closed): transform-origin is a layout-side gap (elements pivot at top-left); skew/generalMatrixbounded by the bridge's TRS decompose; perspective/Preserve3d/backface stay C-tier deferred.acf7311degraded effect groups forward-composite flat — a budget-degraded group (no pooled target) used to vanish; it now foldsgroup.opacityper-instance and draws flat (effect-compositor.md §2.3). Scoped to root-degraded groups — nested degraded children need a different draw path (composite into the parent's off-screen target), guarded by adebug_assertand filed as a new follow-up. Per-tier dirty gates prevent compounding alpha drift; glyph alpha uses the correct float index 11 (GLYPH_ALPHA_FLOAT_OFFSET), not quad's 7.Verification
cargo fmt --all --check,cargo clippy --workspace --all-targets -D warnings,RUSTDOCFLAGS=-D warnings cargo doc --workspace --no-depsall clean;buiy_core+buiy_verify(the blast radius of the cross-crate PackedInstance growth) 162 ok / 0 failed. GPU reftests stay#[ignore]and compile; the lavapipe CI lane exercises them. Full OS test matrix runs here in CI.🤖 Generated with Claude Code