/** Physical surface families; these describe appearance, never geometry or simulation. */ export type MaterialFamily = "standard" | "fabric" | "hair" | "glass" | "metal" | "skin" | "stone" | "plastic"; /** Renderer features an authored material explicitly requires. */ export type MaterialCapability = "pbr" | "sheen" | "anisotropy" | "clearcoat" | "specular" | "transmission" | "volume" | "iridescence" | "alpha"; /** Sparse surface edits. Omitted values preserve the imported material. Angles are radians. */ export interface MaterialSurfaceParameters { color?: string; metalness?: number; roughness?: number; emissive?: string; emissiveIntensity?: number; normalScale?: [number, number]; alphaMode?: "opaque" | "mask" | "blend"; alphaCutoff?: number; opacity?: number; doubleSided?: boolean; sheen?: number; sheenColor?: string; sheenRoughness?: number; anisotropy?: number; anisotropyRotation?: number; clearcoat?: number; clearcoatRoughness?: number; ior?: number; specularIntensity?: number; specularColor?: string; transmission?: number; thickness?: number; attenuationColor?: string; /** Positive metres. Omit for no volume attenuation; Infinity is not serializable. */ attenuationDistance?: number; iridescence?: number; iridescenceIOR?: number; iridescenceThicknessRange?: [number, number]; } /** Supported texture semantics; packed channels follow glTF and Three's PBR shaders. */ export type MaterialTextureRole = "color" | "normal" | "roughness" | "metalness" | "ao" | "emissive" | "alpha" | "height" | "sheenColor" | "sheenRoughness" | "anisotropy" | "clearcoat" | "clearcoatRoughness" | "clearcoatNormal" | "specularIntensity" | "specularColor" | "transmission" | "thickness" | "iridescence" | "iridescenceThickness"; /** Texture channels used by the pinned standard/physical shader path. */ export type MaterialTextureChannel = "r" | "g" | "b" | "a" | "rgb" | "rgba"; /** Portable material or image authorship. */ export interface MaterialProvenance { author: string; license: string; sourceUrl?: string; description?: string; } /** Serializable sampling and UV metadata; metres are descriptive, UV transforms drive rendering. */ export interface MaterialTextureMetadata { url: string; colorSpace: "srgb" | "linear"; channel?: MaterialTextureChannel; uvSet?: 0 | 1 | 2 | 3; transform?: { offset?: [number, number]; scale?: [number, number]; rotation?: number; }; physicalSize?: [number, number]; normalConvention?: "opengl" | "directx"; sampler?: { wrapS?: "repeat" | "clamp" | "mirror"; wrapT?: "repeat" | "clamp" | "mirror"; minFilter?: "nearest" | "linear" | "nearest-mipmap-nearest" | "nearest-mipmap-linear" | "linear-mipmap-nearest" | "linear-mipmap-linear"; magFilter?: "nearest" | "linear"; anisotropy?: number; }; compression?: "none" | "ktx2" | "basisu" | "webp"; provenance?: MaterialProvenance; } /** Shared, versioned authoring data. IDs survive rename, save and export. */ export interface MaterialAsset { schemaVersion: 1; id: string; name: string; family: MaterialFamily; capabilities: readonly MaterialCapability[]; provenance?: MaterialProvenance; surface: MaterialSurfaceParameters; textures?: Partial>; fabric?: FabricAppearance; hair?: HairAppearance; } /** Procedural cloth surface response; this does not create or bend cloth geometry. */ export interface FabricAppearance { construction: "woven" | "fuzzy"; weaveDirection?: number; threadScale?: number; normalStrength?: number; variation?: number; } /** Anisotropic surface approximation for existing hair cards or strand meshes, without grooming. */ export interface HairAppearance { geometry: "cards" | "strands"; /** Radians from UV U; cards generated by hairCards use V for strand length (PI/2). */ strandDirection?: number; /** Thin-sheet direct-light approximation on cards, independent of physical transmission. */ backlightStrength?: number; backlightColor?: string; } /** Names constrain mesh and imported material slot independently; all provided tests must match. */ export interface MaterialSelector { mesh?: string; slot?: string; /** Index in this mesh's material array, independent of the glTF global material index. */ slotIndex?: number; } /** A reusable asset reference with an optional instance-only sparse edit. */ export interface MaterialAssignment { materialId: string; selector: MaterialSelector; overrides?: MaterialSurfaceParameters; } /** * Exact name/index selector matching shared by authoring and rendering. * @capability material-slot-selection match named meshes and imported material slots independently */ export declare function matchesMaterialSelector(selector: MaterialSelector, mesh: string, slot: string, slotIndex: number): boolean; /** Shader channel defaults; standalone alpha maps use green, base-color alpha stays in its color map. */ export declare const MATERIAL_TEXTURE_SEMANTICS: Readonly>; /** An actionable authoring/import diagnostic. */ export interface MaterialDiagnostic { severity: "error" | "warning"; code: string; path: string; message: string; } /** Feature declarations required by each sparse physical parameter. */ export declare const MATERIAL_SURFACE_CAPABILITIES: Partial>; /** Feature declarations required by authored texture roles. */ export declare const MATERIAL_TEXTURE_CAPABILITIES: Readonly>>; /** Determine feature requirements from authored fields, including intentional zero values. */ export declare function materialCapabilitiesForSurface(surface: MaterialSurfaceParameters): MaterialCapability[]; /** * Determine required shader features from surface fields, maps and appearance adapters without editing them. * @capability material-feature-requirements Declare material shader requirements when authors add maps or appearance adapters. */ export declare function materialCapabilitiesForAsset(asset: Pick): MaterialCapability[]; /** * Validate sparse surface edits without mutating them or guessing unsupported fields. * @capability material-surface-validation diagnose unsupported or physically invalid sparse surface edits */ export declare function validateMaterialSurface(value: unknown, path?: string): MaterialDiagnostic[]; /** Validate material JSON and renderer prerequisites before saving or assigning it. */ export declare function validateMaterialAsset(value: unknown): MaterialDiagnostic[]; /** Parse assignment JSON at editor/RPC boundaries. Invalid data fails with an actionable path. */ export declare function parseMaterialAssignments(value: unknown): MaterialAssignment[]; /** Optional renderer limits; ordinary model assignment accepts every supported texture role. */ export interface MaterialAssignmentValidationOptions { disallowedTextureRoles?: readonly MaterialTextureRole[]; } /** * Validate references and selectors without accepting accidental whole-model assignment. * @capability material-slot-selection validate reusable asset references and explicit per-slot selectors */ export declare function validateMaterialAssignments(assignments: readonly MaterialAssignment[], assets: readonly MaterialAsset[], options?: MaterialAssignmentValidationOptions): MaterialDiagnostic[]; /** Editable engine-authored surface starting points, independent of any game's palette or assets. */ export type MaterialTemplate = "wool" | "cotton" | "silk" | "brushed-metal" | "glass" | "coated-plastic" | "stone" | "hair-cards"; /** Create fresh, serializable material data with provenance; templates create no textures or geometry. */ export declare function createMaterialTemplate(template: MaterialTemplate, id: string, name?: MaterialTemplate): MaterialAsset;