123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- import { Nullable } from "../types";
- import { Scene } from "../scene";
- import { Material } from "./material";
- import { _TypeStore } from "../Misc/typeStore";
- import { serialize, expandToProperty, serializeAsTexture, SerializationHelper } from '../Misc/decorators';
- import { MaterialFlags } from './materialFlags';
- import { MaterialHelper } from './materialHelper';
- import { BaseTexture } from './Textures/baseTexture';
- import { UniformBuffer } from './uniformBuffer';
- import { IAnimatable } from '../Animations/animatable.interface';
- /**
- * @hidden
- */
- export interface IMaterialDetailMapDefines {
- DETAIL: boolean;
- DETAILDIRECTUV : number;
- DETAIL_NORMALBLENDMETHOD: number;
- /** @hidden */
- _areTexturesDirty: boolean;
- }
- /**
- * Define the code related to the detail map parameters of a material
- *
- * Inspired from:
- * Unity: https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@9.0/manual/Mask-Map-and-Detail-Map.html and https://docs.unity3d.com/Manual/StandardShaderMaterialParameterDetail.html
- * Unreal: https://docs.unrealengine.com/en-US/Engine/Rendering/Materials/HowTo/DetailTexturing/index.html
- * Cryengine: https://docs.cryengine.com/display/SDKDOC2/Detail+Maps
- */
- export class DetailMapConfiguration {
- private _texture: Nullable<BaseTexture> = null;
- /**
- * The detail texture of the material.
- */
- @serializeAsTexture("detailTexture")
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public texture: Nullable<BaseTexture>;
- /**
- * Defines how strongly the detail diffuse/albedo channel is blended with the regular diffuse/albedo texture
- * Bigger values mean stronger blending
- */
- @serialize()
- public diffuseBlendLevel = 1;
- /**
- * Defines how strongly the detail roughness channel is blended with the regular roughness value
- * Bigger values mean stronger blending. Only used with PBR materials
- */
- @serialize()
- public roughnessBlendLevel = 1;
- /**
- * Defines how strong the bump effect from the detail map is
- * Bigger values mean stronger effect
- */
- @serialize()
- public bumpLevel = 1;
- private _normalBlendMethod = Material.MATERIAL_NORMALBLENDMETHOD_WHITEOUT;
- /**
- * The method used to blend the bump and detail normals together
- */
- @serialize()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public normalBlendMethod: number;
- private _isEnabled = false;
- /**
- * Enable or disable the detail map on this material
- */
- @serialize()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public isEnabled = false;
- /** @hidden */
- private _internalMarkAllSubMeshesAsTexturesDirty: () => void;
- /** @hidden */
- public _markAllSubMeshesAsTexturesDirty(): void {
- this._internalMarkAllSubMeshesAsTexturesDirty();
- }
- /**
- * Instantiate a new detail map
- * @param markAllSubMeshesAsTexturesDirty Callback to flag the material to dirty
- */
- constructor(markAllSubMeshesAsTexturesDirty: () => void) {
- this._internalMarkAllSubMeshesAsTexturesDirty = markAllSubMeshesAsTexturesDirty;
- }
- /**
- * Gets whether the submesh is ready to be used or not.
- * @param defines the list of "defines" to update.
- * @param scene defines the scene the material belongs to.
- * @returns - boolean indicating that the submesh is ready or not.
- */
- public isReadyForSubMesh(defines: IMaterialDetailMapDefines, scene: Scene): boolean {
- const engine = scene.getEngine();
- if (defines._areTexturesDirty && scene.texturesEnabled) {
- if (engine.getCaps().standardDerivatives && this._texture && MaterialFlags.DetailTextureEnabled) {
- // Detail texture cannot be not blocking.
- if (!this._texture.isReady()) {
- return false;
- }
- }
- }
- return true;
- }
- /**
- * Update the defines for detail map usage
- * @param defines the list of "defines" to update.
- * @param scene defines the scene the material belongs to.
- */
- public prepareDefines(defines: IMaterialDetailMapDefines, scene: Scene): void {
- if (this._isEnabled) {
- defines.DETAIL_NORMALBLENDMETHOD = this._normalBlendMethod;
- const engine = scene.getEngine();
- if (defines._areTexturesDirty) {
- if (engine.getCaps().standardDerivatives && this._texture && MaterialFlags.DetailTextureEnabled && this._isEnabled) {
- MaterialHelper.PrepareDefinesForMergedUV(this._texture, defines, "DETAIL");
- defines.DETAIL_NORMALBLENDMETHOD = this._normalBlendMethod;
- } else {
- defines.DETAIL = false;
- }
- }
- } else {
- defines.DETAIL = false;
- }
- }
- /**
- * Binds the material data.
- * @param uniformBuffer defines the Uniform buffer to fill in.
- * @param scene defines the scene the material belongs to.
- * @param isFrozen defines whether the material is frozen or not.
- */
- public bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, isFrozen: boolean): void {
- if (!this._isEnabled) {
- return;
- }
- if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
- if (this._texture && MaterialFlags.DetailTextureEnabled) {
- uniformBuffer.updateFloat4("vDetailInfos", this._texture.coordinatesIndex, this.diffuseBlendLevel, this.bumpLevel, this.roughnessBlendLevel);
- MaterialHelper.BindTextureMatrix(this._texture, uniformBuffer, "detail");
- }
- }
- // Textures
- if (scene.texturesEnabled) {
- if (this._texture && MaterialFlags.DetailTextureEnabled) {
- uniformBuffer.setTexture("detailSampler", this._texture);
- }
- }
- }
- /**
- * Checks to see if a texture is used in the material.
- * @param texture - Base texture to use.
- * @returns - Boolean specifying if a texture is used in the material.
- */
- public hasTexture(texture: BaseTexture): boolean {
- if (this._texture === texture) {
- return true;
- }
- return false;
- }
- /**
- * Returns an array of the actively used textures.
- * @param activeTextures Array of BaseTextures
- */
- public getActiveTextures(activeTextures: BaseTexture[]): void {
- if (this._texture) {
- activeTextures.push(this._texture);
- }
- }
- /**
- * Returns the animatable textures.
- * @param animatables Array of animatable textures.
- */
- public getAnimatables(animatables: IAnimatable[]): void {
- if (this._texture && this._texture.animations && this._texture.animations.length > 0) {
- animatables.push(this._texture);
- }
- }
- /**
- * Disposes the resources of the material.
- * @param forceDisposeTextures - Forces the disposal of all textures.
- */
- public dispose(forceDisposeTextures?: boolean): void {
- if (forceDisposeTextures) {
- this._texture?.dispose();
- }
- }
- /**
- * Get the current class name useful for serialization or dynamic coding.
- * @returns "DetailMap"
- */
- public getClassName(): string {
- return "DetailMap";
- }
- /**
- * Add the required uniforms to the current list.
- * @param uniforms defines the current uniform list.
- */
- public static AddUniforms(uniforms: string[]): void {
- uniforms.push("vDetailInfos");
- }
- /**
- * Add the required samplers to the current list.
- * @param samplers defines the current sampler list.
- */
- public static AddSamplers(samplers: string[]): void {
- samplers.push("detailSampler");
- }
- /**
- * Add the required uniforms to the current buffer.
- * @param uniformBuffer defines the current uniform buffer.
- */
- public static PrepareUniformBuffer(uniformBuffer: UniformBuffer): void {
- uniformBuffer.addUniform("vDetailInfos", 4);
- uniformBuffer.addUniform("detailMatrix", 16);
- }
- /**
- * Makes a duplicate of the current instance into another one.
- * @param detailMap define the instance where to copy the info
- */
- public copyTo(detailMap: DetailMapConfiguration): void {
- SerializationHelper.Clone(() => detailMap, this);
- }
- /**
- * Serializes this detail map instance
- * @returns - An object with the serialized instance.
- */
- public serialize(): any {
- return SerializationHelper.Serialize(this);
- }
- /**
- * Parses a detail map setting from a serialized object.
- * @param source - Serialized object.
- * @param scene Defines the scene we are parsing for
- * @param rootUrl Defines the rootUrl to load from
- */
- public parse(source: any, scene: Scene, rootUrl: string): void {
- SerializationHelper.Parse(() => this, source, scene, rootUrl);
- }
- }
|