|
@@ -15,10 +15,13 @@ import { EffectFallbacks } from '../effectFallbacks';
|
|
|
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;
|
|
@@ -61,12 +64,22 @@ export class PBRSheenConfiguration {
|
|
|
/**
|
|
|
* Stores the sheen tint values in a texture.
|
|
|
* rgb is tint
|
|
|
- * a is a intensity or roughness if roughness has been defined
|
|
|
+ * 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.
|
|
@@ -77,6 +90,15 @@ export class PBRSheenConfiguration {
|
|
|
@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.
|
|
@@ -117,6 +139,12 @@ export class PBRSheenConfiguration {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {
|
|
|
+ if (!this._textureRoughness.isReadyOrNotBlocking()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -134,6 +162,8 @@ export class PBRSheenConfiguration {
|
|
|
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) {
|
|
@@ -142,6 +172,12 @@ export class PBRSheenConfiguration {
|
|
|
} else {
|
|
|
defines.SHEEN_TEXTURE = false;
|
|
|
}
|
|
|
+
|
|
|
+ if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {
|
|
|
+ MaterialHelper.PrepareDefinesForMergedUV(this._textureRoughness, defines, "SHEEN_TEXTURE_ROUGHNESS");
|
|
|
+ } else {
|
|
|
+ defines.SHEEN_TEXTURE_ROUGHNESS = false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -151,6 +187,8 @@ export class PBRSheenConfiguration {
|
|
|
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;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -162,9 +200,13 @@ export class PBRSheenConfiguration {
|
|
|
*/
|
|
|
public bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, isFrozen: boolean): void {
|
|
|
if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
|
|
|
- if (this._texture && MaterialFlags.SheenTextureEnabled) {
|
|
|
- uniformBuffer.updateFloat2("vSheenInfos", this._texture.coordinatesIndex, this._texture.level);
|
|
|
- MaterialHelper.BindTextureMatrix(this._texture, uniformBuffer, "sheen");
|
|
|
+ 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
|
|
@@ -184,6 +226,9 @@ export class PBRSheenConfiguration {
|
|
|
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);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -197,6 +242,10 @@ export class PBRSheenConfiguration {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ if (this._textureRoughness === texture) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -208,6 +257,10 @@ export class PBRSheenConfiguration {
|
|
|
if (this._texture) {
|
|
|
activeTextures.push(this._texture);
|
|
|
}
|
|
|
+
|
|
|
+ if (this._textureRoughness) {
|
|
|
+ activeTextures.push(this._textureRoughness);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -218,6 +271,10 @@ export class PBRSheenConfiguration {
|
|
|
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);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -226,9 +283,8 @@ export class PBRSheenConfiguration {
|
|
|
*/
|
|
|
public dispose(forceDisposeTextures?: boolean): void {
|
|
|
if (forceDisposeTextures) {
|
|
|
- if (this._texture) {
|
|
|
- this._texture.dispose();
|
|
|
- }
|
|
|
+ this._texture?.dispose();
|
|
|
+ this._textureRoughness?.dispose();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -269,7 +325,7 @@ export class PBRSheenConfiguration {
|
|
|
public static PrepareUniformBuffer(uniformBuffer: UniformBuffer): void {
|
|
|
uniformBuffer.addUniform("vSheenColor", 4);
|
|
|
uniformBuffer.addUniform("vSheenRoughness", 1);
|
|
|
- uniformBuffer.addUniform("vSheenInfos", 2);
|
|
|
+ uniformBuffer.addUniform("vSheenInfos", 4);
|
|
|
uniformBuffer.addUniform("sheenMatrix", 16);
|
|
|
}
|
|
|
|
|
@@ -279,6 +335,7 @@ export class PBRSheenConfiguration {
|
|
|
*/
|
|
|
public static AddSamplers(samplers: string[]): void {
|
|
|
samplers.push("sheenSampler");
|
|
|
+ samplers.push("sheenRoughnessSampler");
|
|
|
}
|
|
|
|
|
|
/**
|