MaterialSpec.variant ​

Contract 2.0.0 · package sha256 a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e · generated from configurator-runtime.d.ts by services/onsite-scripter/scripts/build-contract-docs.mjs; edit the source, not this file.

Property of MaterialSpec · inherited by MaterialInput · labs, @experimental · since 2.0.0

ts
variant?: string;

A KHR_materials_variants variant of the GLB the mesh comes from (AssetManifest.variants): the base this rule's fields merge over is that variant's material for the mesh instead of the one it wears, so { variant: 'Walnut', roughness: 0.35 } shows the GLB's walnut, glossier. A mesh the variant maps no material to keeps its own, as the glTF extension reverts it. A name the mesh's model doesn't declare records 'unsupported-spec' with path 'patch.material.variant' (a find(q).set or node(id).set; 'scene.rules[i].set.material.variant' for a rule apply lists), naming the meshes and the names it declares, and the fields lay over what the mesh wears. The variant's material loads on first use: the mesh shows its own until it lands, and idle() waits for it. Experimental: check supports('spec.material.variant') before writing it, and keep the mesh's own material where it answers false. Only in a rule's material over a GLB's mesh: a whole material (materials.create, apply's materials) has no GLB under it and rejects it (HoloInputError 'invalid-input'). Null in a rule removes it. The stored format has no field for it (materialNodeFromSpec lists it in unstorable). The fake checks the name against FakeModel.variants (fakeModelFromGlb fills it from the file), else FakeModel.manifest.variants.

Default: undefined (the material the mesh wears)

Example ​

Imports: values (has, validate, the Holo*Error classes, the pure helpers) from @holostep-configurators/runtime-client, types from @holostep-configurators/runtime-client/contract, /math and /testing names from those entries; boot from the runtime module the root's loadRuntimeAtFloor resolves to. A type your page defines is your app's: declare it there, never import it from the package.

Compiled under the contract's strict settings (examples/declaration/08-MaterialSpec.variant.ts):

ts
import type { Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
// the GLB's own walnut on the doors, a little glossier; reset with null
const doors = session.find({ node: 'cab', slot: 'Front' });
if (session.supports('spec.material.variant')) {
  const r = await doors.set({ material: { variant: 'Walnut', roughness: 0.35 } });
  for (const p of r.problems) console.warn(p.code, p.message); // a name the GLB lacks
}

Generic-API test (spec 3.1) ​

Rule Result
1. Neutral name pass: variant names no product
2. A precedent pass (through its owner MaterialSpec): glTF 2.0 metallic-roughness material (row K10); glTF KHR_materials_sheen (row K10); glTF KHR_materials_transmission (row K10); glTF KHR_materials_unlit (row K10)
3. Two apps, or labs labs (@experimental at a stable path, reached through has() or supports()): it graduates when a second app uses it; apps today: app-04c2774145, app-0c773a4ee3, app-37356bf09f, app-378d190f1b, app-4762caacdc, app-4f16d2f6da, app-4fd23bc869, app-510d750508, app-59c5b5751e, app-822bb9d6aa, app-8675b3225c, app-b362a81c85, app-b4ae2fce25, app-bcb7ef21da, app-c1384707fc, app-ceb4eccc72, app-ddfb017681, app-e3b47169bc, app-e61a0b42ad, app-e9a33606d2, app-f07e9033d9, app-f3598fad77, app-f9a32142f1, app-fb16dd1985, app-fc07850558, app-fc306ec3dc, app-fd09090420, configurator-template
4. The cheaper fix first decided per need in Appendix B: rows K10 (through its owner MaterialSpec) at tier stable (a member only where no rule, data, asset or app code serves the need)