feat(materials): dynamic library registry, picker source tabs, Other category (#525)
* feat(materials): dynamic library registry, picker source tabs, create-material entry point Core gains a runtime material registry (registerLibraryMaterials/ unregisterLibraryMaterials/subscribeLibraryMaterials) so embedders can feed user/community materials; library: refs to registered materials resolve in the viewer unchanged. MaterialCatalogItem carries an optional source (pascal|community|mine|workspace). MaterialPicker gets a source filter row and an optional onCreateMaterialRequest '+ New material' tile, threaded through MaterialPaintPanel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(materials): underline source tabs in picker, matching catalog browse surfaces Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(materials): add 'other' category for uncategorized library materials Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(viewer): rebuild node material when a texture slot is cleared Reused cached WebGPU materials keep a compiled TextureNode per slot; nulling the slot for a cold texture load (or a preset without the map) without needsUpdate leaves the node's per-frame material reference pulling null, crashing the render pass in TextureNode.update. Cold loads are the norm for freshly generated library materials, whose maps aren't in the texture cache. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(viewer): standard materials always carry a displacement texture three's WebGPU shadow pass copies each object's displacementMap onto one shared per-light shadow material while caching per-mesh shadow node graphs against that shared override. A mesh whose shadow graph was built with a displacement TextureNode (painted with a generated material — the only presets carrying height maps) crashes the render pass with "null (reading 'matrix')" the moment a material without a displacement texture is swapped onto it, which is exactly what the paint hover preview does. Give every MeshStandardNodeMaterial a shared 1x1 black displacement texel (zero offset) when it has no real height map, so the copied slot is never null in either direction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bf89b5bcf2
commit
603f5d2242
@@ -157,7 +157,9 @@ export {
|
||||
} from './lib/zone-quantities'
|
||||
export {
|
||||
getCatalogMaterialById,
|
||||
getDynamicLibraryMaterials,
|
||||
getLibraryMaterialIdFromRef,
|
||||
getLibraryMaterialsVersion,
|
||||
getMaterialPresetByRef,
|
||||
getMaterialsForCategory,
|
||||
getSceneMaterialIdFromRef,
|
||||
@@ -168,12 +170,16 @@ export {
|
||||
type MaterialCatalogItem,
|
||||
type MaterialCategory,
|
||||
type MaterialRef,
|
||||
type MaterialSource,
|
||||
type MaterialSurface,
|
||||
type ParsedMaterialRef,
|
||||
parseMaterialRef,
|
||||
registerLibraryMaterials,
|
||||
SCENE_MATERIAL_REF_PREFIX,
|
||||
subscribeLibraryMaterials,
|
||||
toLibraryMaterialRef,
|
||||
toSceneMaterialRef,
|
||||
unregisterLibraryMaterials,
|
||||
} from './material-library'
|
||||
export type {
|
||||
FloorPlacedFootprint,
|
||||
|
||||
Reference in New Issue
Block a user