# ADR 0046: Schema-driven material inputs and processed textures

## Status

Accepted

## Context

The first Material asset format stored a resolved `MaterialDesc` plus a second generic parameter
list. The editor consequently rendered Standard Lit twice, could not pair a scalar or color with its
texture, and had no stable place to describe future shader-graph inputs. Texture files also carried
no import intent, so color maps, normals, and packed mask data could be sampled interchangeably.

## Decision

Material, direct-base Material Instance, and Shader Schema documents use schema v2.
`MaterialInputSchema` is the presentation and validation contract for built-in Standard Lit,
custom Surface evaluators, and future generated shaders. `MaterialInputSet` is the only authored
value/texture store; instance sets remain sparse. Scalar texture bindings select R, G, B, or A,
and scalar values multiply the sampled value. Standard Lit pairs Base Color with albedo, Metallic
and Roughness with scalar maps, Occlusion with a scalar map, and Emissive Color/Intensity with an
emissive map.

The registry uses v3 `AssetImportSettings`, with typed Model and Texture settings. Texture settings
own semantic, color space, mip policy, compression, size limit, filtering, wrapping, anisotropy,
and normal convention. One GPU-free processor is called by editor publication, imports, the
watcher refresh path, and `cargo process-assets`. It writes content-addressed UASTC Basis or
uncompressed KTX2 artifacts below `assets/.import-cache/runtime/`, records sampler/color-space data
in runtime catalog v2, and canonicalizes authored AO/Roughness/Metallic selections to R/G/B ARM.
Source images remain editable and unchanged. Processing computes the normalized content key before
image decode or compression. An existing artifact at that key is reused directly, so validation and
catalog repair do not recompress unchanged Texture or packed-Material inputs.

The actor inspector and asset editors consume the same schema-driven controls. A renderable owns
one compact material-slot header; expanding it edits the resolved shared Material or Instance.
Slot provenance and diagnostics live outside parameter rows. Valid authoring changes refresh the
shared runtime handle immediately but only mark the asset document dirty. Explicit save uses the
two-phase source/derived boundary from [ADR 0047](0047-editor-authored-asset-documents.md), without
recompiling an unchanged Surface evaluator or scheduling a project-wide watcher pass.

This is an intentional foundation break. Normal loading accepts current documents only; explicit
`cargo upgrade-project --project <root> --apply` converts the repository's v1/v2 documents and
backs up every replaced file transactionally.

## Consequences

- Shader additions no longer require bespoke inspector layout code when their schema can describe
  the input.
- Color-space and packed-channel choices are deterministic in editor, CI, and packages.
- Cached content-addressed artifacts keep `process-assets --check` and unchanged dependency refreshes
  on the source-hash/catalog path instead of the image-compression path.
- Runtime and Solari receive the same canonical input mapping.
- Changing a Texture setting can invalidate dependent packed Material artifacts.
- The future node-graph compiler must emit this schema and Surface WGSL; graph authoring itself is
  outside this decision.
