import type {Color, Event, IUniform, Material, MaterialParameters, Shader} from 'three' import type {IDisposable, IJSONSerializable} from 'ts-browser-helpers' import type {MaterialExtension} from '../materials' import type {ChangeEvent, IUiConfigContainer} from 'uiconfig.js' import type {SerializationMetaType} from '../utils' import type {IObject3D} from './IObject' import {ISetDirtyCommonOptions} from './IObject' import type {ITexture} from './ITexture' import type {IImportResultUserData} from '../assetmanager' export type IMaterialParameters = MaterialParameters & {customMaterialExtensions?: MaterialExtension[]} export type IMaterialEventTypes = 'dispose' | 'materialUpdate' | 'beforeRender' | 'beforeCompile' | 'afterRender' | 'textureUpdate' | 'beforeDeserialize' export type IMaterialEvent = Event & { type: T bubbleToObject?: boolean bubbleToParent?: boolean material?: IMaterial texture?: ITexture oldTexture?: ITexture uiChangeEvent?: ChangeEvent } export interface IMaterialSetDirtyOptions extends ISetDirtyCommonOptions{ /** * @default true */ bubbleToObject?: boolean, /** * @default true */ needsUpdate?: boolean, [key: string]: any } export interface IMaterialUserData extends IImportResultUserData{ uuid?: string // adding to userdata also, so that its saved in gltf /** * Automatically dispose material when not used by any object in the scene * @default true */ disposeOnIdle?: boolean renderToGBuffer?: boolean /** * Same as {@link renderToGBuffer} but for depth only, not normal or flags etc */ renderToDepth?: boolean // only for materials that have envMapIntensity separateEnvMapIntensity?: boolean // default: false cloneId?: string cloneCount?: number __envIntensity?: number // temp storage for envMapIntensity while rendering __isVariation?: boolean inverseAlphaMap?: boolean // only for physical material right now /** * See {@link MaterialManager.dispose} as {@link BaseGroundPlugin._refreshMaterial} */ runtimeMaterial?: boolean /** * See {@link GBufferPlugin} */ gBufferData?: { materialId?: number /** * @default true */ tonemapEnabled?: boolean [key: string]: any } // todo: move these to respective plugins /** * For SSCSPlugin */ sscsDisabled?: boolean /** * For SSRPlugin */ ssreflDisabled?: boolean /** * For SSRPlugin */ ssreflNonPhysical?: boolean [key: string]: any // legacy, to be removed /** * @deprecated */ setDirty?: (options?: IMaterialSetDirtyOptions) => void /** * @deprecated Use {@link postTonemap.tonemapEnabled} instead. This is kept because used in old files. */ postTonemap?: boolean } export interface IMaterial extends Material, IJSONSerializable, IDisposable, IUiConfigContainer { constructor: { TYPE: string TypeSlug: string MaterialProperties?: Record MaterialTemplate?: IMaterialTemplate } assetType: 'material' setDirty(options?: IMaterialSetDirtyOptions): void; // clone?: ()=> any; needsUpdate: boolean; // toJSON same as three.js Material.toJSON // toJSON(meta?: any): any; // copyProps should be just setValues setValues(parameters: Material|(MaterialParameters&{type?:string}), allowInvalidType?: boolean, clearCurrentUserData?: boolean): this; toJSON(meta?: SerializationMetaType, _internal?: boolean): any; fromJSON(json: any, meta?: SerializationMetaType, _internal?: boolean): this | null; extraUniformsToUpload: Record materialExtensions: MaterialExtension[] registerMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void; unregisterMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void; /** * Managed internally, do not change manually */ generator?: IMaterialGenerator /** * Managed internally, do not change manually */ appliedMeshes: Set lastShader?: Shader // Note: for userData: add _ in front of for private use, which is preserved while cloning but not serialisation, and __ for private use, which is not preserved while cloning and serialisation userData: IMaterialUserData /** * Disposes the material from the GPU. * Set force to false if not sure the material is used by any object in the scene. * // todo add check for visible in scene also? or is that overkill * @param force - when true, same as three.js dispose. when false, only disposes if disposeOnIdle not false and not used by any object in the scene. default: true */ dispose(force?: boolean): void // optional from subclasses, added here for autocomplete flatShading?: boolean map?: ITexture | null alphaMap?: ITexture | null envMap?: ITexture | null envMapIntensity?: number aoMap?: ITexture | null lightMap?: ITexture | null normalMap?: ITexture | null bumpMap?: ITexture | null displacementMap?: ITexture | null aoMapIntensity?: number lightMapIntensity?: number roughnessMap?: ITexture | null metalnessMap?: ITexture | null roughness?: number metalness?: number transmissionMap?: ITexture | null transmission?: number color?: Color wireframe?: boolean linewidth?: number isRawShaderMaterial?: boolean isPhysicalMaterial?: boolean isUnlitMaterial?: boolean isGBufferMaterial?: boolean // [key: string]: any } export type IMaterialGenerator = (params: any)=>T export interface IMaterialTemplate{ templateUUID?: string, name: string, typeSlug?: string, alias?: string[], // alternate names materialType: string, generator?: IMaterialGenerator, params?: TP }