Add dedicated skinned rendering, pose restoration, shared Material and Material Instance slots, registry-driven components, Surface/Solari integration, transactional schema upgrades, navigation authoring, documentation, and evaluation evidence.
97 lines
5.4 KiB
Markdown
97 lines
5.4 KiB
Markdown
# Renderer, Material, and Component Foundation Evaluation
|
|
|
|
Date: 2026-07-11
|
|
Branch: `codex/renderer-material-component-foundation`
|
|
|
|
This record captures implementation evidence for the dedicated skinned renderer, shared Material
|
|
and Material Instance workflow, registry-driven authoring components, and custom Surface contract.
|
|
The permanent design contracts live in [ADR 0033](../../../adr/0033-dedicated-skinned-mesh-renderer.md),
|
|
[ADR 0034](../../../adr/0034-registry-driven-authoring-components.md),
|
|
[ADR 0035](../../../adr/0035-shared-material-assets-and-renderer-slots.md), and
|
|
[ADR 0036](../../../adr/0036-surface-abi-and-solari-parity.md). The user workflow lives in the
|
|
[material-system guide](../../material-system.md).
|
|
|
|
## Live editor evidence
|
|
|
|
All images below are native Wayland captures from the running editor. The temporary actors and
|
|
assignments used for visual verification were not saved into the authored scene.
|
|
|
|
### Dedicated skinned renderer and stable material slots
|
|
|
|

|
|
|
|
The actor is hydrated through `SkinnedMeshRenderer`, not `StaticMeshRenderer`. Its imported
|
|
hierarchy remains intact, the configured default Standing clip is sampled in edit mode, and every
|
|
draw binding exposes a stable slot ID plus source-material fallback.
|
|
|
|
### Shared custom Surface assigned through a Material Instance
|
|
|
|

|
|
|
|
Applying `surface_tint_instance` updates the existing hydrated draw bindings in place. The visible
|
|
blue Surface evaluation does not respawn the hierarchy or reset the sampled pose.
|
|
|
|
### Sparse Material Instance authoring
|
|
|
|

|
|
|
|
Instances reference one direct base Material. Unchecked values inherit; selecting or dropping a
|
|
texture creates only that override, and **Clear** removes the binding so inheritance resumes.
|
|
|
|
### Registry-driven component composition
|
|
|
|

|
|
|
|
The actor combines renderer and light components without an `ActorKind` exclusivity rule. The
|
|
registry owns add/remove/reset/copy/paste/history/persistence behavior; `ActorKind` remains a
|
|
derived compatibility and presentation hint.
|
|
|
|
### Larger material thumbnail previews
|
|
|
|

|
|
|
|
Material spheres now fill roughly 78-81% of the preview while retaining edge padding. Model and
|
|
mesh-subasset framing is unchanged.
|
|
|
|
Additional captures:
|
|
|
|
- [Material editor and Create Instance action](material-editor-create-instance.png)
|
|
- [Registry-driven Add Component categories](component-registry-add-menu.png)
|
|
|
|
## Acceptance results
|
|
|
|
| Area | Result | Evidence |
|
|
|------|--------|----------|
|
|
| Dedicated static/skinned ownership | Pass | Separate authored/hydrated renderer types; rigged/animated manifests are rejected by static hydration |
|
|
| Pose lifecycle | Pass | Explicit stable default clip; transform and morph-weight baseline restore on stop, controller removal, preview reset, and PIE exit |
|
|
| Renderer material slots | Pass | Stable named IDs, imported fallback, explicit assignment, orphan retention, and in-place material patching |
|
|
| Material assets/instances | Pass | Versioned shared assets, direct-base sparse instances, transient property blocks, Apply/Revert/Create Instance |
|
|
| Texture parameters | Pass | Project-wide picker includes imported texture subassets; base/schema/stored/instance slots share browse, drop, reject, and clear behavior |
|
|
| Component lifecycle | Pass | Stable registry IDs, reflected transactions/history, persistence allowlist, independent active state, and compatible composition |
|
|
| Surface raster/Solari semantics | Pass for eligible geometry | Shared ABI packing, evaluator, textures, normal/emissive/unlit values, and cutout predicate |
|
|
| Project migration | Pass | Transactional schema-v4 upgrader, backup/rollback path, canonical slots and active-state split; second dry run is empty |
|
|
| Project validation | Pass | 59 dependencies, 5 non-blocking findings, 0 blocking errors |
|
|
|
|
## Automated verification
|
|
|
|
| Command/suite | Result |
|
|
|---------------|--------|
|
|
| `cargo test -p shared --offline` | 84 passed |
|
|
| `cargo test -p scene --offline` | 64 passed, 1 ignored migration fixture |
|
|
| `cargo test -p game --lib --offline` | 37 passed |
|
|
| `cargo test -p game_hot --lib --offline` | 16 passed |
|
|
| `cargo test -p editor --lib --offline` | 171 passed |
|
|
| `cargo test -p blacksite_surface --offline` | 3 passed plus doc tests |
|
|
| `cargo test -p bevy_solari --lib --offline` | 1 passed |
|
|
| `cargo --locked --offline validate-levels` | 0 blocking errors |
|
|
| `cargo --offline upgrade-project --project . --json` | No pending changes or warnings |
|
|
| `cargo fmt --all -- --check` / `git diff --check` | Pass |
|
|
|
|
## Deliberate boundary
|
|
|
|
Bevy 0.19's maintained Solari path does not expose dynamic post-morph/post-skin vertex buffers and
|
|
BLAS updates. Skinned and morph-deformed actors therefore remain visible in raster but are omitted
|
|
from ray tracing with an actionable diagnostic. This is safer than tracing a stale bind-pose ghost;
|
|
dynamic deformed BLAS support remains future work and the corresponding Gitea acceptance item stays
|
|
open.
|