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.
3.8 KiB
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
MaterialAssetdocuments. AMaterialInstanceAssetreferences one direct baseMaterialAssetand stores parameter and texture overrides. Nested material instances are invalid. MaterialRefis the assignment type. Its registry UUID and subasset ID are authoritative;source_pathis a cached loading hint that validation or migration may repair after a move.StaticMeshRendererandSkinnedMeshRenderereach own aRendererMaterialSet. They do not share a mesh component or hydration path. EachRendererMaterialSlothas a stable ID, a presentation name, a read-only importedsource_material, and an optional explicitmaterialassignment. 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.
HydratedRendererMaterialBindingidentifies 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.MaterialPropertyBlocksare 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 transactionalcargo upgrade-projectcommand; 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
MaterialDescpaths 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.