import type { AssetContainer } from "@babylonjs/core/assetContainer";
import type { ISceneLoaderProgressEvent } from "@babylonjs/core/Loading/sceneLoader";
import { Material } from "@babylonjs/core/Materials/material";
import type { BaseTexture } from "@babylonjs/core/Materials/Textures/baseTexture";
import type { Mesh } from "@babylonjs/core/Meshes/mesh";
import { Scene } from "@babylonjs/core/scene";
import type { Nullable } from "@babylonjs/core/types";
import type { IMmdMaterialBuilder, MaterialInfo, ReferencedMesh, TextureInfo } from "./IMmdMaterialBuilder";
import { MmdStandardMaterial } from "./mmdStandardMaterial";
import type { ILogger } from "./Parser/ILogger";
import type { IArrayBufferFile } from "./referenceFileResolver";
import { ReferenceFileResolver } from "./referenceFileResolver";
import { TextureAlphaChecker } from "./textureAlphaChecker";
/**
 * Render method of MMD standard material
 *
 * The drawing behavior of MMD is not conducive to modern renderers like Babylon.js
 * That's why you need to decide which shading method is right for your use case
 */
export declare enum MmdStandardMaterialRenderMethod {
    /**
     * Force depth write alpha blending with alpha evaluation
     *
     * This approach first determines via alpha evaluation if the meshes to be rendered are opaque,
     * and then only enables forceDepthWrite and performs alphaBlending on non-opaque meshes
     *
     * This approach is similar to mmd, but is more performance friendly and partially solves the draw order problem
     */
    DepthWriteAlphaBlendingWithEvaluation = 0,
    /**
     * Force depth write alpha blending
     *
     * Materials loaded this way will all have forceDepthWrite true and will alphaBlend true
     *
     * Since it does depth writing and alpha blending, the draw order becomes very important
     *
     * This approach gives you exactly the same results as mmd,
     * but it introduces a problem that mmd is known for: manually managing the draw order
     */
    DepthWriteAlphaBlending = 1,
    /**
     * Alpha evaluation
     *
     * This method uses an alpha evaluation to determine whether the mesh is best rendered as opaque, alphatest, or alphablend
     *
     * Since this method does not use forceDepthWrite, it can give different results than mmd but has better compatibility for several shader effects
     */
    AlphaEvaluation = 2
}
/**
 * MMD standard material builder
 *
 * Use `MmdStandardMaterial` to create a mesh material
 */
export declare class MmdStandardMaterialBuilder implements IMmdMaterialBuilder {
    /**
     * Render method of MMD standard material (default: DepthWriteAlphaBlendingWithEvaluation)
     */
    renderMethod: MmdStandardMaterialRenderMethod;
    /**
     * Whether to force disable alpha evaluation (default: false)
     *
     * If true, load time alpha evaluation will be disabled
     *
     * For load time optimization, it is recommended to disable alpha evaluation feature and set the blending mode for the material manually
     */
    forceDisableAlphaEvaluation: boolean;
    /**
     * The threshold of material alpha to use transparency mode. (default: 195)
     *
     * lower value is more likely to use transparency mode. (0 - 255)
     */
    alphaThreshold: number;
    /**
     * The threshold of transparency mode to use alpha blend. (default: 100)
     *
     * lower value is more likely to use alpha test mode. otherwise use alpha blend mode
     */
    alphaBlendThreshold: number;
    /**
     * The canvas resolution to evaluate alpha (default: 512)
     *
     * Resolution of the render canvas used to evaluate alpha internally
     *
     * The higher the resolution, the higher the accuracy and the longer the load time
     */
    alphaEvaluationResolution: number;
    /**
     * Whether to delete the texture buffer after loading (default: true)
     */
    deleteTextureBufferAfterLoad: boolean;
    private readonly _textureLoader;
    /**
     * Next starting alpha index for force depth write alpha blending rendering
     */
    nextStartingAlphaIndex: number;
    /**
     * Alpha index increments per model for force depth write alpha blending rendering
     */
    alphaIndexIncrementsPerModel: number;
    protected _setMeshesAlphaIndex(meshes: Mesh[]): void;
    buildMaterials(uniqueId: number, materialsInfo: readonly MaterialInfo[], texturesInfo: readonly TextureInfo[], imagePathTable: readonly string[], rootUrl: string, fileRootId: string, referenceFiles: readonly File[] | readonly IArrayBufferFile[], referencedMeshes: (readonly ReferencedMesh[])[], meshes: Mesh[], scene: Scene, assetContainer: Nullable<AssetContainer>, textureNameMap: Nullable<Map<BaseTexture, string>>, logger: ILogger, onTextureLoadProgress?: (event: ISceneLoaderProgressEvent) => void, onTextureLoadComplete?: () => void): Material[];
    private _buildTextureNameMap;
    /**
     * Load general scalar properties (diffuse, specular, ambient, alpha, shininess)
     *
     * This method can be overridden for customizing the material loading process
     * @param material Material
     * @param materialInfo Material information
     * @param meshes Meshes that use the material
     */
    loadGeneralScalarProperties: (material: MmdStandardMaterial, materialInfo: MaterialInfo, meshes: readonly ReferencedMesh[]) => Promise<void> | void;
    /**
     * Load diffuse texture
     *
     * This method can be overridden for customizing the material loading process
     * @param uniqueId Model unique id
     * @param material Material
     * @param materialInfo Material information
     * @param imagePathTable Image path table
     * @param textureInfo Texture information
     * @param scene Scene
     * @param assetContainer Asset container
     * @param rootUrl Root url
     * @param referenceFileResolver Reference file resolver
     * @param meshes Meshes that use the material
     * @param logger Logger
     * @param getTextureAlphaChecker Get texture alpha checker
     * @param onTextureLoadComplete Texture load complete callback
     */
    loadDiffuseTexture: (uniqueId: number, material: MmdStandardMaterial, materialInfo: MaterialInfo, imagePathTable: readonly string[], textureInfo: Nullable<TextureInfo>, scene: Scene, assetContainer: Nullable<AssetContainer>, rootUrl: string, referenceFileResolver: ReferenceFileResolver, logger: ILogger, onTextureLoadComplete?: () => void) => Promise<void> | void;
    protected _evaluateDiffuseTextureTransparencyMode(diffuseTexture: BaseTexture, evaluatedTransparency: number, referencedMeshes: readonly ReferencedMesh[], logger: ILogger, getTextureAlphaChecker: () => Nullable<TextureAlphaChecker>): Promise<Nullable<number>>;
    setAlphaBlendMode: (material: MmdStandardMaterial, materialInfo: MaterialInfo, meshes: readonly ReferencedMesh[], logger: ILogger, getTextureAlphaChecker: () => Nullable<TextureAlphaChecker>) => Promise<void> | void;
    /**
     * Load sphere texture
     *
     * This method can be overridden for customizing the material loading process
     * @param uniqueId Model unique id
     * @param material Material
     * @param materialInfo Material information
     * @param imagePathTable Texture path table
     * @param textureInfo Texture information
     * @param scene Scene
     * @param assetContainer Asset container
     * @param rootUrl Root url
     * @param referenceFileResolver Reference file resolver
     * @param logger Logger
     * @param onTextureLoadComplete Texture load complete callback
     */
    loadSphereTexture: (uniqueId: number, material: MmdStandardMaterial, materialInfo: MaterialInfo, imagePathTable: readonly string[], textureInfo: Nullable<TextureInfo>, scene: Scene, assetContainer: Nullable<AssetContainer>, rootUrl: string, referenceFileResolver: ReferenceFileResolver, logger: ILogger, onTextureLoadComplete?: () => void) => Promise<void> | void;
    /**
     * Load toon texture
     *
     * This method can be overridden for customizing the material loading process
     * @param uniqueId Model unique id
     * @param material Material
     * @param materialInfo Material information
     * @param imagePathTable Image path table
     * @param textureInfo Texture information
     * @param scene Scene
     * @param assetContainer Asset container
     * @param rootUrl Root url
     * @param referenceFileResolver Reference file resolver
     * @param logger Logger
     * @param onTextureLoadComplete Texture load complete callback
     */
    loadToonTexture: (uniqueId: number, material: MmdStandardMaterial, materialInfo: MaterialInfo, imagePathTable: readonly string[], textureInfo: Nullable<TextureInfo>, scene: Scene, assetContainer: Nullable<AssetContainer>, rootUrl: string, referenceFileResolver: ReferenceFileResolver, logger: ILogger, onTextureLoadComplete?: () => void) => Promise<void> | void;
    /**
     * Load outline rendering properties
     *
     * This method can be overridden for customizing the material loading process
     * @param material Material
     * @param materialInfo Material information
     * @param logger Logger
     */
    loadOutlineRenderingProperties: (material: MmdStandardMaterial, materialInfo: MaterialInfo, logger: ILogger) => Promise<void> | void;
    /**
     * Called after building a single material
     *
     * This method is called after the material and textures have been loaded
     * @param material Material
     * @param materialIndex Material index
     * @param materialInfo Material information
     * @param imagePathTable Image path table
     * @param texturesInfo Texture information
     * @param scene Scene
     * @param rootUrl Root url
     */
    afterBuildSingleMaterial: (material: MmdStandardMaterial, materialIndex: number, materialInfo: MaterialInfo, imagePathTable: readonly string[], texturesInfo: readonly TextureInfo[], scene: Scene, rootUrl: string) => void;
}
