import { BufferGeometry, Camera, Color, Event, IUniform, Material, MaterialEventMap, MaterialParameters, Object3D, Scene, Texture, WebGLProgramParametersWithUniforms, WebGLRenderer } from 'three';
import { IDisposable, IJSONSerializable } from 'ts-browser-helpers';
import { MaterialExtension } from '../materials';
import { ChangeEvent, IUiConfigContainer } from 'uiconfig.js';
import { SerializationMetaType, AnimateTime } from '../utils';
import { IObject3D, ISetDirtyCommonOptions } from './IObject';
import { ITexture } from './ITexture';
import { IImportResultUserData } from '../assetmanager';
export type IMaterialParameters = MaterialParameters & {
    customMaterialExtensions?: MaterialExtension[];
};
export interface IMaterialEventMap extends MaterialEventMap {
    beforeCompile: {
        shader: WebGLProgramParametersWithUniforms;
        renderer: WebGLRenderer;
    };
    beforeRender: {
        renderer: WebGLRenderer;
        scene: Scene;
        camera: Camera;
        geometry: BufferGeometry;
        object: Object3D;
    };
    afterRender: {
        renderer: WebGLRenderer;
        scene: Scene;
        camera: Camera;
        geometry: BufferGeometry;
        object: Object3D;
    };
    /**
     * Fires when the material is set/added to a mesh
     * This is applicable of all types of Object3D, like Line etc, not just Mesh
     */
    addToMesh: {
        object: Object3D;
    };
    /**
     * Fires when the material is changed/removed to a mesh
     * This is applicable of all types of Object3D, like Line etc, not just Mesh
     */
    removeFromMesh: {
        object: Object3D;
    };
    /**
     * For internal use
     */
    beforeDeserialize: {
        data: unknown;
        meta?: SerializationMetaType;
        bubbleToObject: boolean;
        bubbleToParent: boolean;
    };
    texturesChanged: {
        textures: Set<ITexture>;
        oldTextures: Set<ITexture>;
        addedTextures: Set<ITexture>;
        removedTextures: Set<ITexture>;
        material: IMaterial;
        bubbleToObject?: boolean;
        bubbleToParent?: boolean;
    };
}
declare module 'three' {
    interface MaterialEventMap {
        materialUpdate: {
            bubbleToObject?: boolean;
            bubbleToParent?: boolean;
            uiChangeEvent?: ChangeEvent;
        } & IMaterialSetDirtyOptions;
        textureUpdate: {
            texture: ITexture;
            bubbleToObject?: boolean;
            bubbleToParent?: boolean;
            uiChangeEvent?: ChangeEvent;
        };
        select: {
            ui?: boolean;
            bubbleToObject?: boolean;
            bubbleToParent?: boolean;
            material: IMaterial;
            value?: /* IObject3D | */ IMaterial | null;
            source?: string;
        };
    }
}
export interface IMaterialSetDirtyOptions extends ISetDirtyCommonOptions {
    /**
     * @default true
     */
    bubbleToObject?: boolean;
    /**
     * @default true
     */
    needsUpdate?: boolean;
    /**
     * Change identifier that triggered the `setDirty` call.
     * This is different from `key` in that it is used to identify the property/key that is changed. In many cases these could be same, but they could also be different eg, key might be x, with change being position.
     */
    change?: string | keyof IMaterial;
    [key: string]: any;
}
export interface IMaterialUserData extends IImportResultUserData {
    uuid?: string;
    /**
     * 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;
    /**
     * Flag to tell the scene to prefer `material.envMapIntensity` over `scene.environmentIntensity`
     * only for materials that have envMapIntensity
     */
    separateEnvMapIntensity?: boolean;
    /**
     * The environment map to use in the `RootScene`. To use this, object with the material must be in the RootScene, and the key should exist in the `RootScene`'s `textureSlots`.
     *
     * only for materials that have envMap
     */
    envMapSlotKey?: string;
    /**
     * Automatically register this material in the {@link MaterialManager} when added to the scene.
     * This provides hook to other plugins to extend the material, add uiconfig etc.
     * @default true
     */
    autoRegisterInManager?: boolean;
    cloneId?: string;
    cloneCount?: number;
    __isVariation?: boolean;
    inverseAlphaMap?: boolean;
    /**
     * See {@link MaterialManager.dispose} as {@link BaseGroundPlugin._refreshMaterial}
     */
    runtimeMaterial?: boolean;
    /**
     * See {@link GBufferPlugin}
     */
    gBufferData?: {
        materialId?: number;
        /**
         * @default true
         */
        tonemapEnabled?: boolean;
        [key: string]: any;
    };
    /**
     * Force a depth value in GBuffer.
     * This is useful to force center values like 0 to the depth.
     */
    forcedLinearDepth?: number;
    /**
     * General flag to disable multiple plugins on the material at once, like SSAO, SSR, Bloom etc.
     */
    pluginsDisabled?: boolean;
    /**
     * For SSCSPlugin
     */
    sscsDisabled?: boolean;
    /**
     * For SSRPlugin
     */
    ssreflDisabled?: boolean;
    /**
     * For SSRPlugin
     */
    ssreflNonPhysical?: boolean;
    /**
     * List of properties that will be saved in the glb/material files when this material is saved.
     * The other properties are expected to be loaded/filled at runtime by default values or from an external material loaded from {@link IImportResultUserData.rootPath}.
     */
    sProperties?: string[];
    /**
     * If this is a placeholder/dummy material. These materials are not saved in asset/glTF files.
     */
    isPlaceholder?: boolean;
    [key: string]: any;
    /**
     * @deprecated
     */
    setDirty?: (options?: IMaterialSetDirtyOptions) => void;
    /**
     * @deprecated Use {@link postTonemap.tonemapEnabled} instead. This is kept because used in old files.
     */
    postTonemap?: boolean;
}
export interface AnimateTimeMaterial extends AnimateTime {
    from?: IMaterial;
}
export interface IMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends Material<TE>, IJSONSerializable<any, SerializationMetaType>, IDisposable, IUiConfigContainer {
    constructor: {
        TYPE: string;
        TypeSlug: string;
        TypeAlias?: string[];
        MaterialProperties?: Record<string, any>;
        MapProperties?: string[];
        InterpolateProperties?: string[];
        new (...args: any[]): IMaterial;
    };
    assetType: 'material';
    setDirty(options?: IMaterialSetDirtyOptions): void;
    needsUpdate: boolean;
    /**
     *
     * @param parameters - An existing `Material` object or a plain JavaScript object with properties that will be copied to the material.
     * @param allowInvalidType - Copy properties even if the type is different. Not used by default, but implemented in some material classes.
     * @param clearCurrentUserData - clears the userData instead of merging first level. Default - true if `Material` object is passed, false if parameters object is passed
     * @param time - parameters to animate the setting of properties
     */
    setValues(parameters: Material | (MaterialParameters & {
        type?: string;
    }), allowInvalidType?: boolean, clearCurrentUserData?: boolean, time?: AnimateTimeMaterial): void;
    toJSON(meta?: SerializationMetaType, _internal?: boolean): any;
    fromJSON(json: any, meta?: SerializationMetaType, _internal?: boolean): /* this*/ any | null;
    extraUniformsToUpload: Record<string, IUniform>;
    materialExtensions: MaterialExtension[];
    registerMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void;
    unregisterMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void;
    /**
     * Objects in the scene that are using this material.
     * This is set in the {@link Object3DManager} when the objects are added/removed from the scene. Do not modify this set directly.
     */
    appliedMeshes: Set<IObject3D>;
    lastShader?: WebGLProgramParametersWithUniforms;
    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;
    /**
     * Clones the Material.
     * This is a shallow clone, so the properties are copied by reference.
     *
     * @param track - if true, the clone id and count will be tracked in the userData and a suffix will be appended to the name. default - false
     */
    clone(track?: boolean): any;
    /**
     * A promise can be set by the object to indicate that the material(or any of its properties) is loading.
     * This can be used by the scene, viewer, plugins to defer actions until the material is loaded.
     */
    _loadingPromise?: Promise<void | any>;
    color?: Color;
    wireframe?: boolean;
    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;
    emissiveMap?: ITexture | null;
    emissiveIntensity?: number;
    emissive?: Color;
    linewidth?: number;
    isRawShaderMaterial?: boolean;
    isPhysicalMaterial?: boolean;
    isLineMaterial?: boolean;
    isLineBasicMaterial?: boolean;
    isUnlitMaterial?: boolean;
    isGBufferMaterial?: boolean;
    isLineMaterial2?: boolean;
    isUnlitLineMaterial?: boolean;
    /**
     * @internal
     */
    ['__textureUpdate']?: (e: Event<'update', Texture>) => void;
    /**
     * @internal
     */
    ['_mapRefs']?: Set<ITexture>;
}
declare module 'three' {
    interface IUniform {
        needsUpdate?: boolean;
    }
}
//# sourceMappingURL=../src/core/IMaterial.d.ts.map