Blacksite/docs/adr/0035-shared-material-assets-and-renderer-slots.md
Rbanh 0798aa5d57 Build renderer and material component foundations
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.
2026-07-12 00:24:06 -04:00

61 lines
3.8 KiB
Markdown

# ADR 0035: Shared Material Assets and Renderer Slots
## Status
Accepted
## Context
Renderer material authoring previously mixed copied `MaterialDesc` values, imported source-material
defaults, and static-mesh draw data. That made a renderer's ownership unclear, encouraged material
copies per actor, and left rigged geometry without the same assignment model as static geometry.
Matching imported materials by a display name was also unsafe: names are neither unique nor stable
when a model is reimported.
Static and skinned renderers need the same Unity-like authoring contract without sharing their mesh
or hydration components. A project material must be reusable, an instance must express explicit
overrides over one base material, and each renderer must expose stable material slots independently
from its draw or skeleton representation.
## Decision
- Project materials use versioned `MaterialAsset` documents. A `MaterialInstanceAsset` references
one direct base `MaterialAsset` and stores parameter and texture overrides. Nested material
instances are invalid.
- `MaterialRef` is the assignment type. Its registry UUID and subasset ID are authoritative;
`source_path` is a cached loading hint that validation or migration may repair after a move.
- `StaticMeshRenderer` and `SkinnedMeshRenderer` each own a `RendererMaterialSet`. They do not share
a mesh component or hydration path. Each `RendererMaterialSlot` has a stable ID, a presentation
name, a read-only imported `source_material`, and an optional explicit `material` assignment.
Explicit assignment wins; clearing it returns to the imported source material.
- Static draw parts and imported skinned-hierarchy draws bind to material slots by stable IDs.
Reimport reconciles by ID only. An explicit assignment whose source slot disappears is retained as
an `OrphanedMaterialAssignment`; the editor never silently reconnects it by display name.
- Asset Browser **Apply Material** assigns a shared material or material instance to every material
slot on each selected static or skinned renderer. Renderer inspectors provide per-slot
Browse/Select/Locate/Clear controls and expose orphan warnings.
- `HydratedRendererMaterialBinding` identifies each runtime draw's owner, slot, and effective
material. A skinned renderer material-only edit patches the instantiated hierarchy without
reloading its source hierarchy or joints.
- `MaterialPropertyBlocks` are runtime-only, per-slot overrides. They do not mutate a shared asset
and are excluded from scene and prefab persistence. Persisting a reusable variation requires an
explicit material instance.
- Scene schema v4 migrates legacy renderer assignments into `RendererMaterialSet`. Project material,
material-instance, shader-schema, and scene rewrites are performed by the explicit transactional
`cargo upgrade-project` command; ordinary loading remains read-only.
## Consequences
- Static and skinned renderers have a consistent material-slot workflow while retaining distinct
geometry ownership and hydration behavior.
- An assignment remains a reference rather than a copied material value, so editing or replacing a
shared asset does not create actor-local material copies. Material/base/schema/evaluator
dependency revisions update the shared runtime handle in place across all assigned slots.
- Source reimport cannot silently move an override to the wrong draw. Orphans require an explicit
user decision to reassign or discard.
- Legacy primitive/actor `MaterialDesc` paths remain compatibility paths until their consumers move
to renderer slots; new mesh-renderer work uses shared references.
- Runtime property blocks have no editor promotion workflow yet.
- Material graph authoring, nested instances, blended/transmissive materials, and a generalized
per-renderer property-block inspector are outside this decision.