123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- import { SerializationHelper, serialize, expandToProperty, serializeAsColor3, serializeAsTexture } from "../../Misc/decorators";
- import { UniformBuffer } from "../../Materials/uniformBuffer";
- import { Color3 } from '../../Maths/math.color';
- import { Scene } from "../../scene";
- import { MaterialFlags } from "../../Materials/materialFlags";
- import { MaterialHelper } from "../../Materials/materialHelper";
- import { BaseTexture } from "../../Materials/Textures/baseTexture";
- import { Nullable } from "../../types";
- import { IAnimatable } from '../../Animations/animatable.interface';
- import { EffectFallbacks } from '../effectFallbacks';
- /**
- * @hidden
- */
- export interface IMaterialSheenDefines {
- SHEEN: boolean;
- SHEEN_TEXTURE: boolean;
- SHEEN_TEXTURE_ROUGHNESS: boolean;
- SHEEN_TEXTUREDIRECTUV: number;
- SHEEN_LINKWITHALBEDO: boolean;
- SHEEN_ROUGHNESS: boolean;
- SHEEN_ALBEDOSCALING: boolean;
- SHEEN_USE_ROUGHNESS_FROM_TEXTURE: boolean;
- SHEEN_TEXTURE_ROUGHNESS_IDENTICAL: boolean;
- /** @hidden */
- _areTexturesDirty: boolean;
- }
- /**
- * Define the code related to the Sheen parameters of the pbr material.
- */
- export class PBRSheenConfiguration {
- private _isEnabled = false;
- /**
- * Defines if the material uses sheen.
- */
- @serialize()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public isEnabled = false;
- private _linkSheenWithAlbedo = false;
- /**
- * Defines if the sheen is linked to the sheen color.
- */
- @serialize()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public linkSheenWithAlbedo = false;
- /**
- * Defines the sheen intensity.
- */
- @serialize()
- public intensity = 1;
- /**
- * Defines the sheen color.
- */
- @serializeAsColor3()
- public color = Color3.White();
- private _texture: Nullable<BaseTexture> = null;
- /**
- * Stores the sheen tint values in a texture.
- * rgb is tint
- * a is a intensity or roughness if the roughness property has been defined and useRoughnessFromTexture is true (in that case, textureRoughness won't be used)
- * If the roughness property has been defined and useRoughnessFromTexture is false then the alpha channel is not used to modulate roughness
- */
- @serializeAsTexture()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public texture: Nullable<BaseTexture> = null;
- private _useRoughnessFromMainTexture = true;
- /**
- * Indicates that the alpha channel of the texture property will be used for roughness.
- * Has no effect if the roughness (and texture!) property is not defined
- */
- @serialize()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public useRoughnessFromMainTexture = true;
- private _roughness: Nullable<number> = null;
- /**
- * Defines the sheen roughness.
- * It is not taken into account if linkSheenWithAlbedo is true.
- * To stay backward compatible, material roughness is used instead if sheen roughness = null
- */
- @serialize()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public roughness: Nullable<number> = null;
- private _textureRoughness: Nullable<BaseTexture> = null;
- /**
- * Stores the sheen roughness in a texture.
- * alpha channel is the roughness. This texture won't be used if the texture property is not empty and useRoughnessFromTexture is true
- */
- @serializeAsTexture()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public textureRoughness: Nullable<BaseTexture> = null;
- private _albedoScaling = false;
- /**
- * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
- * It allows the strength of the sheen effect to not depend on the base color of the material,
- * making it easier to setup and tweak the effect
- */
- @serialize()
- @expandToProperty("_markAllSubMeshesAsTexturesDirty")
- public albedoScaling = false;
- /** @hidden */
- private _internalMarkAllSubMeshesAsTexturesDirty: () => void;
- /** @hidden */
- public _markAllSubMeshesAsTexturesDirty(): void {
- this._internalMarkAllSubMeshesAsTexturesDirty();
- }
- /**
- * Instantiate a new istance of clear coat configuration.
- * @param markAllSubMeshesAsTexturesDirty Callback to flag the material to dirty
- */
- constructor(markAllSubMeshesAsTexturesDirty: () => void) {
- this._internalMarkAllSubMeshesAsTexturesDirty = markAllSubMeshesAsTexturesDirty;
- }
- /**
- * Specifies that the submesh is ready to be used.
- * @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: IMaterialSheenDefines, scene: Scene): boolean {
- if (defines._areTexturesDirty) {
- if (scene.texturesEnabled) {
- if (this._texture && MaterialFlags.SheenTextureEnabled) {
- if (!this._texture.isReadyOrNotBlocking()) {
- return false;
- }
- }
- if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {
- if (!this._textureRoughness.isReadyOrNotBlocking()) {
- return false;
- }
- }
- }
- }
- return true;
- }
- /**
- * Checks to see if a texture is used in the material.
- * @param defines the list of "defines" to update.
- * @param scene defines the scene the material belongs to.
- */
- public prepareDefines(defines: IMaterialSheenDefines, scene: Scene): void {
- if (this._isEnabled) {
- defines.SHEEN = this._isEnabled;
- defines.SHEEN_LINKWITHALBEDO = this._linkSheenWithAlbedo;
- defines.SHEEN_ROUGHNESS = this._roughness !== null;
- defines.SHEEN_ALBEDOSCALING = this._albedoScaling;
- defines.SHEEN_USE_ROUGHNESS_FROM_TEXTURE = this._useRoughnessFromMainTexture;
- defines.SHEEN_TEXTURE_ROUGHNESS_IDENTICAL = this.texture !== null && this.texture._texture === this.textureRoughness?._texture;
- if (defines._areTexturesDirty) {
- if (scene.texturesEnabled) {
- if (this._texture && MaterialFlags.SheenTextureEnabled) {
- MaterialHelper.PrepareDefinesForMergedUV(this._texture, defines, "SHEEN_TEXTURE");
- } else {
- defines.SHEEN_TEXTURE = false;
- }
- if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {
- MaterialHelper.PrepareDefinesForMergedUV(this._textureRoughness, defines, "SHEEN_TEXTURE_ROUGHNESS");
- } else {
- defines.SHEEN_TEXTURE_ROUGHNESS = false;
- }
- }
- }
- }
- else {
- defines.SHEEN = false;
- defines.SHEEN_TEXTURE = false;
- defines.SHEEN_LINKWITHALBEDO = false;
- defines.SHEEN_ROUGHNESS = false;
- defines.SHEEN_ALBEDOSCALING = false;
- defines.SHEEN_USE_ROUGHNESS_FROM_TEXTURE = false;
- defines.SHEEN_TEXTURE_ROUGHNESS_IDENTICAL = 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 wether the material is frozen or not.
- */
- public bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, isFrozen: boolean): void {
- if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
- if ((this._texture || this._textureRoughness) && MaterialFlags.SheenTextureEnabled) {
- uniformBuffer.updateFloat4("vSheenInfos", this._texture?.coordinatesIndex ?? this._textureRoughness?.coordinatesIndex ?? 0, this._texture?.level ?? 0, 0 /* not used */, this._textureRoughness?.level ?? 0);
- if (this._texture) {
- MaterialHelper.BindTextureMatrix(this._texture, uniformBuffer, "sheen");
- } else if (this._textureRoughness) {
- MaterialHelper.BindTextureMatrix(this._textureRoughness, uniformBuffer, "sheen");
- }
- }
- // Sheen
- uniformBuffer.updateFloat4("vSheenColor",
- this.color.r,
- this.color.g,
- this.color.b,
- this.intensity);
- if (this._roughness !== null) {
- uniformBuffer.updateFloat("vSheenRoughness", this._roughness);
- }
- }
- // Textures
- if (scene.texturesEnabled) {
- if (this._texture && MaterialFlags.SheenTextureEnabled) {
- uniformBuffer.setTexture("sheenSampler", this._texture);
- }
- if (this.textureRoughness && (this.texture === null || this.texture._texture !== this.textureRoughness._texture) && MaterialFlags.SheenTextureEnabled) {
- uniformBuffer.setTexture("sheenRoughnessSampler", this._textureRoughness);
- }
- }
- }
- /**
- * 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;
- }
- if (this._textureRoughness === 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);
- }
- if (this._textureRoughness) {
- activeTextures.push(this._textureRoughness);
- }
- }
- /**
- * 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);
- }
- if (this._textureRoughness && this._textureRoughness.animations && this._textureRoughness.animations.length > 0) {
- animatables.push(this._textureRoughness);
- }
- }
- /**
- * Disposes the resources of the material.
- * @param forceDisposeTextures - Forces the disposal of all textures.
- */
- public dispose(forceDisposeTextures?: boolean): void {
- if (forceDisposeTextures) {
- this._texture?.dispose();
- this._textureRoughness?.dispose();
- }
- }
- /**
- * Get the current class name of the texture useful for serialization or dynamic coding.
- * @returns "PBRSheenConfiguration"
- */
- public getClassName(): string {
- return "PBRSheenConfiguration";
- }
- /**
- * Add fallbacks to the effect fallbacks list.
- * @param defines defines the Base texture to use.
- * @param fallbacks defines the current fallback list.
- * @param currentRank defines the current fallback rank.
- * @returns the new fallback rank.
- */
- public static AddFallbacks(defines: IMaterialSheenDefines, fallbacks: EffectFallbacks, currentRank: number): number {
- if (defines.SHEEN) {
- fallbacks.addFallback(currentRank++, "SHEEN");
- }
- return currentRank;
- }
- /**
- * Add the required uniforms to the current list.
- * @param uniforms defines the current uniform list.
- */
- public static AddUniforms(uniforms: string[]): void {
- uniforms.push("vSheenColor", "vSheenRoughness", "vSheenInfos", "sheenMatrix");
- }
- /**
- * Add the required uniforms to the current buffer.
- * @param uniformBuffer defines the current uniform buffer.
- */
- public static PrepareUniformBuffer(uniformBuffer: UniformBuffer): void {
- uniformBuffer.addUniform("vSheenColor", 4);
- uniformBuffer.addUniform("vSheenRoughness", 1);
- uniformBuffer.addUniform("vSheenInfos", 4);
- uniformBuffer.addUniform("sheenMatrix", 16);
- }
- /**
- * Add the required samplers to the current list.
- * @param samplers defines the current sampler list.
- */
- public static AddSamplers(samplers: string[]): void {
- samplers.push("sheenSampler");
- samplers.push("sheenRoughnessSampler");
- }
- /**
- * Makes a duplicate of the current configuration into another one.
- * @param sheenConfiguration define the config where to copy the info
- */
- public copyTo(sheenConfiguration: PBRSheenConfiguration): void {
- SerializationHelper.Clone(() => sheenConfiguration, this);
- }
- /**
- * Serializes this BRDF configuration.
- * @returns - An object with the serialized config.
- */
- public serialize(): any {
- return SerializationHelper.Serialize(this);
- }
- /**
- * Parses a anisotropy Configuration 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);
- }
- }
|