From b50e1ab22a396ffe2ac5423a79a897ff28928752 Mon Sep 17 00:00:00 2001 From: sebavan Date: Thu, 18 Apr 2024 01:21:26 +0200 Subject: [PATCH 1/3] replace KHR_materials_translucency with KHR_materials_diffuse_transmission --- .../Node/Blocks/PBR/subSurfaceBlock.ts | 5 + .../PBR/pbrSubSurfaceConfiguration.ts | 86 ++++++++++-- .../dev/core/src/Materials/materialFlags.ts | 18 ++- .../ShadersInclude/pbrBlockSubSurface.fx | 28 +++- .../ShadersInclude/pbrFragmentDeclaration.fx | 7 + .../pbrFragmentSamplersDeclaration.fx | 1 + .../ShadersInclude/pbrVertexDeclaration.fx | 5 + packages/dev/core/src/Shaders/pbr.fragment.fx | 8 ++ packages/dev/core/src/Shaders/pbr.vertex.fx | 2 + .../pbrMaterialPropertyGridComponent.tsx | 17 +++ .../actionTabs/tabs/tools/gltfComponent.tsx | 6 +- .../inspector/src/components/globalState.ts | 2 +- .../Extensions/KHR_animation_pointer.data.ts | 14 ++ ... => KHR_materials_diffuse_transmission.ts} | 54 +++++--- .../Extensions/KHR_materials_dispersion.ts | 2 +- .../2.0/Extensions/KHR_materials_volume.ts | 2 +- .../loaders/src/glTF/2.0/Extensions/index.ts | 2 +- .../KHR_materials_diffuse_transmission.ts | 122 ++++++++++++++++++ .../2.0/Extensions/KHR_materials_volume.ts | 2 +- .../src/glTF/2.0/Extensions/index.ts | 1 + .../babylon.glTF2Interface.d.ts | 10 +- .../devHost/src/babylon.glTF2Interface.ts | 10 +- 22 files changed, 356 insertions(+), 48 deletions(-) rename packages/dev/loaders/src/glTF/2.0/Extensions/{KHR_materials_translucency.ts => KHR_materials_diffuse_transmission.ts} (60%) create mode 100644 packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts diff --git a/packages/dev/core/src/Materials/Node/Blocks/PBR/subSurfaceBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/PBR/subSurfaceBlock.ts index 850775451fa..d7c557e3530 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/PBR/subSurfaceBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/PBR/subSurfaceBlock.ts @@ -55,6 +55,7 @@ export class SubSurfaceBlock extends NodeMaterialBlock { state._excludeVariableName("subSurfaceOut"); state._excludeVariableName("vThicknessParam"); state._excludeVariableName("vTintColor"); + state._excludeVariableName("vTranslucencyColor"); state._excludeVariableName("vSubSurfaceIntensity"); state._excludeVariableName("dispersion"); } @@ -248,6 +249,10 @@ export class SubSurfaceBlock extends NodeMaterialBlock { #endif #ifdef SS_TRANSLUCENCY ${translucencyDiffusionDistance}, + vTintColor, + #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE + vec4(0.), + #endif #endif subSurfaceOut ); diff --git a/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts index 14b37c79fa5..07ad7f7a6c2 100644 --- a/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts +++ b/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts @@ -42,6 +42,8 @@ export class MaterialSubSurfaceDefines extends MaterialDefines { public SS_REFRACTIONINTENSITY_TEXTUREDIRECTUV = 0; public SS_TRANSLUCENCYINTENSITY_TEXTURE = false; public SS_TRANSLUCENCYINTENSITY_TEXTUREDIRECTUV = 0; + public SS_TRANSLUCENCYCOLOR_TEXTURE = false; + public SS_TRANSLUCENCYCOLOR_TEXTUREDIRECTUV = 0; public SS_REFRACTIONMAP_3D = false; public SS_REFRACTIONMAP_OPPOSITEZ = false; @@ -279,7 +281,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { * Stores the intensity of the different subsurface effects in the thickness texture. * Note that if refractionIntensityTexture and/or translucencyIntensityTexture is provided it takes precedence over thicknessTexture + useMaskFromThicknessTexture * * the green (red if useGltfStyleTextures = true) channel is the refraction intensity. - * * the blue channel is the translucency intensity. + * * the blue (alpha if useGltfStyleTextures = true) channel is the translucency intensity. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") @@ -297,23 +299,41 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { private _translucencyIntensityTexture: Nullable = null; /** * Stores the intensity of the translucency. If provided, it takes precedence over thicknessTexture + useMaskFromThicknessTexture - * * the blue channel is the translucency intensity. + * * the blue (alpha if useGltfStyleTextures = true) channel is the translucency intensity. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") public translucencyIntensityTexture: Nullable = null; - private _scene: Scene; - private _useGltfStyleTextures = false; + /** + * Defines the translucency tint of the material. + * If not set, the tint color will be used instead. + */ + @serializeAsColor3() + public translucencyColor: Nullable = null; + + private _translucencyColorTexture: Nullable = null; + /** + * Defines the translucency tint color of the material as a texture. + * This is multiplied against the translucency color to add variety and realism to the material. + * If translucencyColor is not set, the tint color will be used instead. + */ + @serializeAsTexture() + @expandToProperty("_markAllSubMeshesAsTexturesDirty") + public translucencyColorTexture: Nullable = null; + + private _useGltfStyleTextures = true; /** * Use channels layout used by glTF: * * thicknessTexture: the green (instead of red) channel is the thickness * * thicknessTexture/refractionIntensityTexture: the red (instead of green) channel is the refraction intensity - * * thicknessTexture/translucencyIntensityTexture: no change, use the blue channel for the translucency intensity + * * thicknessTexture/translucencyIntensityTexture: the alpha (instead of blue) channel is the translucency intensity */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useGltfStyleTextures: boolean = false; + public useGltfStyleTextures: boolean = true; + + private _scene: Scene; /** @internal */ private _internalMarkAllSubMeshesAsTexturesDirty: () => void; @@ -353,6 +373,12 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { } } + if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled) { + if (!this._translucencyColorTexture.isReadyOrNotBlocking()) { + return false; + } + } + const refractionTexture = this._getRefractionTexture(scene); if (refractionTexture && MaterialFlags.RefractionTextureEnabled) { if (!refractionTexture.isReadyOrNotBlocking()) { @@ -393,6 +419,8 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false; defines.SS_USE_THICKNESS_AS_DEPTH = false; defines.SS_USE_GLTF_TEXTURES = false; + defines.SS_TRANSLUCENCYCOLOR_TEXTURE = false; + defines.SS_TRANSLUCENCYCOLOR_TEXTUREDIRECTUV = 0; return; } @@ -421,6 +449,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { defines.SS_ALBEDOFORTRANSLUCENCYTINT = false; defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false; defines.SS_USE_THICKNESS_AS_DEPTH = false; + defines.SS_TRANSLUCENCYCOLOR_TEXTURE = false; if (defines._areTexturesDirty) { if (scene.texturesEnabled) { @@ -435,6 +464,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled) { PrepareDefinesForMergedUV(this._translucencyIntensityTexture, defines, "SS_TRANSLUCENCYINTENSITY_TEXTURE"); } + + if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled) { + PrepareDefinesForMergedUV(this._translucencyColorTexture, defines, "SS_TRANSLUCENCYCOLOR_TEXTURE"); + } } } @@ -511,9 +544,9 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { BindTextureMatrix(this._refractionIntensityTexture, uniformBuffer, "refractionIntensity"); } - if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled && defines.SS_TRANSLUCENCYINTENSITY_TEXTURE) { - uniformBuffer.updateFloat2("vTranslucencyIntensityInfos", this._translucencyIntensityTexture.coordinatesIndex, this._translucencyIntensityTexture.level); - BindTextureMatrix(this._translucencyIntensityTexture, uniformBuffer, "translucencyIntensity"); + if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled && defines.SS_TRANSLUCENCYCOLOR_TEXTURE) { + uniformBuffer.updateFloat2("vTranslucencyColorInfos", this._translucencyColorTexture.coordinatesIndex, this._translucencyColorTexture.level); + BindTextureMatrix(this._translucencyColorTexture, uniformBuffer, "translucencyColor"); } if (refractionTexture && MaterialFlags.RefractionTextureEnabled) { @@ -555,6 +588,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { uniformBuffer.updateColor3("vDiffusionDistance", this.diffusionDistance); uniformBuffer.updateFloat4("vTintColor", this.tintColor.r, this.tintColor.g, this.tintColor.b, Math.max(0.00001, this.tintColorAtDistance)); + uniformBuffer.updateColor4("vTranslucencyColor", this.translucencyColor ?? this.tintColor, 0); uniformBuffer.updateFloat3("vSubSurfaceIntensity", this.refractionIntensity, this.translucencyIntensity, 0); @@ -575,6 +609,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { uniformBuffer.setTexture("translucencyIntensitySampler", this._translucencyIntensityTexture); } + if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled && defines.SS_TRANSLUCENCYCOLOR_TEXTURE) { + uniformBuffer.setTexture("translucencyColorSampler", this._translucencyColorTexture); + } + if (refractionTexture && MaterialFlags.RefractionTextureEnabled) { if (lodBasedMicrosurface) { uniformBuffer.setTexture("refractionSampler", refractionTexture); @@ -639,6 +677,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { return true; } + if (this._translucencyColorTexture === texture) { + return true; + } + return false; } @@ -658,6 +700,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { if (this._refractionTexture) { activeTextures.push(this._refractionTexture); } + + if (this._translucencyColorTexture) { + activeTextures.push(this._translucencyColorTexture); + } } public getAnimatables(animatables: IAnimatable[]): void { @@ -668,6 +714,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { if (this._refractionTexture && this._refractionTexture.animations && this._refractionTexture.animations.length > 0) { animatables.push(this._refractionTexture); } + + if (this._translucencyColorTexture && this._translucencyColorTexture.animations && this._translucencyColorTexture.animations.length > 0) { + animatables.push(this._translucencyColorTexture); + } } public dispose(forceDisposeTextures?: boolean): void { @@ -679,6 +729,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { if (this._refractionTexture) { this._refractionTexture.dispose(); } + + if (this._translucencyColorTexture) { + this._translucencyColorTexture.dispose(); + } } } @@ -697,7 +751,15 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { } public getSamplers(samplers: string[]): void { - samplers.push("thicknessSampler", "refractionIntensitySampler", "translucencyIntensitySampler", "refractionSampler", "refractionSamplerLow", "refractionSamplerHigh"); + samplers.push( + "thicknessSampler", + "refractionIntensitySampler", + "translucencyIntensitySampler", + "refractionSampler", + "refractionSamplerLow", + "refractionSamplerHigh", + "translucencyColorSampler" + ); } public getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } { @@ -721,6 +783,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { { name: "vRefractionSize", size: 3, type: "vec3" }, { name: "scatteringDiffusionProfile", size: 1, type: "float" }, { name: "dispersion", size: 1, type: "float" }, + + { name: "vTranslucencyColor", size: 4, type: "vec4" }, + { name: "vTranslucencyColorInfos", size: 2, type: "vec2" }, + { name: "translucencyColorMatrix", size: 16, type: "mat4" }, ], }; } diff --git a/packages/dev/core/src/Materials/materialFlags.ts b/packages/dev/core/src/Materials/materialFlags.ts index 5ab28129f1d..3075233532b 100644 --- a/packages/dev/core/src/Materials/materialFlags.ts +++ b/packages/dev/core/src/Materials/materialFlags.ts @@ -331,7 +331,7 @@ export class MaterialFlags { * Are translucency intensity textures enabled in the application. */ public static get TranslucencyIntensityTextureEnabled(): boolean { - return this._ThicknessTextureEnabled; + return this._TranslucencyIntensityTextureEnabled; } public static set TranslucencyIntensityTextureEnabled(value: boolean) { if (this._TranslucencyIntensityTextureEnabled === value) { @@ -342,6 +342,22 @@ export class MaterialFlags { Engine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag); } + private static _TranslucencyColorTextureEnabled = true; + /** + * Are translucency tint textures enabled in the application. + */ + public static get TranslucencyColorTextureEnabled(): boolean { + return this._TranslucencyColorTextureEnabled; + } + public static set TranslucencyColorTextureEnabled(value: boolean) { + if (this._TranslucencyColorTextureEnabled === value) { + return; + } + + this._TranslucencyColorTextureEnabled = value; + Engine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag); + } + private static _IridescenceTextureEnabled = true; /** * Are translucency intensity textures enabled in the application. diff --git a/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockSubSurface.fx b/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockSubSurface.fx index c7a4f3c02d5..8b367044c41 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockSubSurface.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockSubSurface.fx @@ -241,6 +241,10 @@ struct subSurfaceOutParams #endif #ifdef SS_TRANSLUCENCY in vec3 vDiffusionDistance, + in vec4 vTranslucencyColor, + #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE + in vec4 translucencyColorMap, + #endif #endif out subSurfaceOutParams outParams ) @@ -258,12 +262,13 @@ struct subSurfaceOutParams outParams.alpha = 1.0; #endif #endif + #ifdef SS_TRANSLUCENCY float translucencyIntensity = vSubSurfaceIntensity.y; #endif #ifdef SS_THICKNESSANDMASK_TEXTURE - #if defined(SS_USE_GLTF_TEXTURES) + #ifdef SS_USE_GLTF_TEXTURES float thickness = thicknessMap.g * vThicknessParam.y + vThicknessParam.x; #else float thickness = thicknessMap.r * vThicknessParam.y + vThicknessParam.x; @@ -274,7 +279,7 @@ struct subSurfaceOutParams #endif #if defined(SS_REFRACTION) && defined(SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS) - #if defined(SS_USE_GLTF_TEXTURES) + #ifdef SS_USE_GLTF_TEXTURES refractionIntensity *= thicknessMap.r; #else refractionIntensity *= thicknessMap.g; @@ -282,7 +287,11 @@ struct subSurfaceOutParams #endif #if defined(SS_TRANSLUCENCY) && defined(SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS) - translucencyIntensity *= thicknessMap.b; + #ifdef SS_USE_GLTF_TEXTURES + translucencyIntensity *= thicknessMap.a; + #else + translucencyIntensity *= thicknessMap.b; + #endif #endif #else float thickness = vThicknessParam.y; @@ -297,7 +306,11 @@ struct subSurfaceOutParams #endif #if defined(SS_TRANSLUCENCY) && defined(SS_TRANSLUCENCYINTENSITY_TEXTURE) - translucencyIntensity *= translucencyIntensityMap.b; + #ifdef SS_USE_GLTF_TEXTURES + translucencyIntensity *= translucencyIntensityMap.a; + #else + translucencyIntensity *= translucencyIntensityMap.b; + #endif #endif // _________________________________________________________________________________________ @@ -305,7 +318,12 @@ struct subSurfaceOutParams // _________________________________________________________________________________________ #ifdef SS_TRANSLUCENCY thickness = maxEps(thickness); - vec3 transmittance = transmittanceBRDF_Burley(vTintColor.rgb, vDiffusionDistance, thickness); + vec4 translucencyColor = vTranslucencyColor; + #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE + translucencyColor *= translucencyColorMap; + #endif + + vec3 transmittance = transmittanceBRDF_Burley(translucencyColor.rgb, vDiffusionDistance, thickness); transmittance *= translucencyIntensity; outParams.transmittance = transmittance; outParams.translucencyIntensity = translucencyIntensity; diff --git a/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx b/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx index e5f379b8b52..b2b55b6bd9f 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx @@ -188,6 +188,13 @@ uniform mat4 view; uniform vec3 vDiffusionDistance; uniform vec4 vTintColor; uniform vec3 vSubSurfaceIntensity; + + uniform vec4 vTranslucencyColor; + + #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE + uniform vec2 vTranslucencyColorInfos; + uniform mat4 translucencyColorMatrix; + #endif #endif #ifdef PREPASS diff --git a/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.fx b/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.fx index c6ffdb3a344..ccb10f78c17 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.fx @@ -114,4 +114,5 @@ #include(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness,_SAMPLERNAME_,thickness) #include(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity,_SAMPLERNAME_,refractionIntensity) #include(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity,_SAMPLERNAME_,translucencyIntensity) + #include(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor,_SAMPLERNAME_,translucencyColor) #endif \ No newline at end of file diff --git a/packages/dev/core/src/Shaders/ShadersInclude/pbrVertexDeclaration.fx b/packages/dev/core/src/Shaders/ShadersInclude/pbrVertexDeclaration.fx index ca3cf798c28..c0a908c642e 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/pbrVertexDeclaration.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/pbrVertexDeclaration.fx @@ -144,6 +144,11 @@ uniform float pointSize; uniform vec2 vTranslucencyIntensityInfos; uniform mat4 translucencyIntensityMatrix; #endif + + #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE + uniform vec2 vTranslucencyColorInfos; + uniform mat4 translucencyColorMatrix; + #endif #endif #ifdef NORMAL diff --git a/packages/dev/core/src/Shaders/pbr.fragment.fx b/packages/dev/core/src/Shaders/pbr.fragment.fx index 1384f5f97a5..a3fbd2d3183 100644 --- a/packages/dev/core/src/Shaders/pbr.fragment.fx +++ b/packages/dev/core/src/Shaders/pbr.fragment.fx @@ -518,6 +518,10 @@ void main(void) { vec4 translucencyIntensityMap = texture2D(translucencyIntensitySampler, vTranslucencyIntensityUV + uvOffset); #endif + #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE + vec4 translucencyColorMap = texture2D(translucencyColorSampler, vTranslucencyColorUV + uvOffset); + #endif + subSurfaceBlock( vSubSurfaceIntensity, vThicknessParam, @@ -592,6 +596,10 @@ void main(void) { #endif #ifdef SS_TRANSLUCENCY vDiffusionDistance, + vTranslucencyColor, + #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE + translucencyColorMap, + #endif #endif subSurfaceOut ); diff --git a/packages/dev/core/src/Shaders/pbr.vertex.fx b/packages/dev/core/src/Shaders/pbr.vertex.fx index a07cb4ccca6..40d6c43baec 100644 --- a/packages/dev/core/src/Shaders/pbr.vertex.fx +++ b/packages/dev/core/src/Shaders/pbr.vertex.fx @@ -66,6 +66,7 @@ attribute vec4 color; #include(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness) #include(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity) #include(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity) + #include(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor) #endif // Output @@ -239,6 +240,7 @@ void main(void) { #include(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness,_MATRIXNAME_,thickness,_INFONAME_,ThicknessInfos.x) #include(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity,_MATRIXNAME_,refractionIntensity,_INFONAME_,RefractionIntensityInfos.x) #include(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity,_MATRIXNAME_,translucencyIntensity,_INFONAME_,TranslucencyIntensityInfos.x) + #include(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor,_MATRIXNAME_,translucencyColor,_INFONAME_,TranslucencyColorInfos.x) #endif // TBN diff --git a/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx b/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx index 53becef0c8b..7e91c7469a4 100644 --- a/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx +++ b/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx @@ -937,6 +937,23 @@ export class PBRMaterialPropertyGridComponent extends React.Component + + (material.subSurface.translucencyColorTexture = texture)} + onTextureRemoved={() => (material.subSurface.translucencyColorTexture = null)} + material={material} + onSelectionChangedObservable={this.props.onSelectionChangedObservable} + onDebugSelectionChangeObservable={this._onDebugSelectionChangeObservable} + /> )} diff --git a/packages/dev/inspector/src/components/actionTabs/tabs/tools/gltfComponent.tsx b/packages/dev/inspector/src/components/actionTabs/tabs/tools/gltfComponent.tsx index 3917a0c9a35..57719632728 100644 --- a/packages/dev/inspector/src/components/actionTabs/tabs/tools/gltfComponent.tsx +++ b/packages/dev/inspector/src/components/actionTabs/tabs/tools/gltfComponent.tsx @@ -214,9 +214,9 @@ export class GLTFComponent extends React.Component { onSelect={(value) => (extensionStates["KHR_materials_transmission"].enabled = value)} /> extensionStates["KHR_materials_translucency"].enabled} - onSelect={(value) => (extensionStates["KHR_materials_translucency"].enabled = value)} + label="KHR_materials_diffuse_transmission" + isSelected={() => extensionStates["KHR_materials_diffuse_transmission"].enabled} + onSelect={(value) => (extensionStates["KHR_materials_diffuse_transmission"].enabled = value)} /> 1)], + diffuseTransmissionTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.translucencyIntensityTexture"), + }, + }, + diffuseTransmissionColorFactor: [new MaterialAnimationPropertyInfo(Animation.ANIMATIONTYPE_COLOR3, "subSurface.translucencyColor", getColor3, () => 3)], + diffuseTransmissionColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.translucencyColorTexture"), + }, + }, + }, }, }, }; diff --git a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_translucency.ts b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts similarity index 60% rename from packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_translucency.ts rename to packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts index 9781aa54363..c2d7f5c7ee1 100644 --- a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_translucency.ts +++ b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts @@ -5,16 +5,17 @@ import type { BaseTexture } from "core/Materials/Textures/baseTexture"; import type { IMaterial, ITextureInfo } from "../glTFLoaderInterfaces"; import type { IGLTFLoaderExtension } from "../glTFLoaderExtension"; import { GLTFLoader } from "../glTFLoader"; -import type { IKHRMaterialsTranslucency } from "babylonjs-gltf2interface"; +import type { IKHRMaterialsDiffuseTransmission } from "babylonjs-gltf2interface"; +import { Color3 } from "core/Maths/math.color"; -const NAME = "KHR_materials_translucency"; +const NAME = "KHR_materials_diffuse_transmission"; /** * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825) * !!! Experimental Extension Subject to Changes !!! */ // eslint-disable-next-line @typescript-eslint/naming-convention -export class KHR_materials_translucency implements IGLTFLoaderExtension { +export class KHR_materials_diffuse_transmission implements IGLTFLoaderExtension { /** * The name of this extension. */ @@ -52,7 +53,7 @@ export class KHR_materials_translucency implements IGLTFLoaderExtension { * @internal */ public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable> { - return GLTFLoader.LoadExtensionAsync(context, material, this.name, (extensionContext, extension) => { + return GLTFLoader.LoadExtensionAsync(context, material, this.name, (extensionContext, extension) => { const promises = new Array>(); promises.push(this._loader.loadMaterialBasePropertiesAsync(context, material, babylonMaterial)); promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); @@ -61,10 +62,11 @@ export class KHR_materials_translucency implements IGLTFLoaderExtension { }); } - private _loadTranslucentPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, extension: IKHRMaterialsTranslucency): Promise { + private _loadTranslucentPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, extension: IKHRMaterialsDiffuseTransmission): Promise { if (!(babylonMaterial instanceof PBRMaterial)) { throw new Error(`${context}: Material type not supported`); } + const pbrMaterial = babylonMaterial as PBRMaterial; // Enables "translucency" texture which represents diffusely-transmitted light. @@ -76,26 +78,46 @@ export class KHR_materials_translucency implements IGLTFLoaderExtension { pbrMaterial.subSurface.minimumThickness = 0.0; pbrMaterial.subSurface.maximumThickness = 0.0; - // Albedo colour will tint transmission. - pbrMaterial.subSurface.useAlbedoToTintTranslucency = true; + // Tint color will be used for transmission. + pbrMaterial.subSurface.useAlbedoToTintTranslucency = false; - if (extension.translucencyFactor !== undefined) { - pbrMaterial.subSurface.translucencyIntensity = extension.translucencyFactor; + if (extension.diffuseTransmissionFactor !== undefined) { + pbrMaterial.subSurface.translucencyIntensity = extension.diffuseTransmissionFactor; } else { pbrMaterial.subSurface.translucencyIntensity = 0.0; pbrMaterial.subSurface.isTranslucencyEnabled = false; return Promise.resolve(); } - if (extension.translucencyTexture) { - (extension.translucencyTexture as ITextureInfo).nonColorData = true; - return this._loader.loadTextureInfoAsync(`${context}/translucencyTexture`, extension.translucencyTexture).then((texture: BaseTexture) => { - pbrMaterial.subSurface.translucencyIntensityTexture = texture; - }); + const promises = new Array>(); + + pbrMaterial.subSurface.useGltfStyleTextures = true; + + if (extension.diffuseTransmissionTexture) { + (extension.diffuseTransmissionTexture as ITextureInfo).nonColorData = true; + promises.push( + this._loader.loadTextureInfoAsync(`${context}/diffuseTransmissionTexture`, extension.diffuseTransmissionTexture).then((texture: BaseTexture) => { + pbrMaterial.subSurface.translucencyIntensityTexture = texture; + }) + ); + } + + if (extension.diffuseTransmissionColorFactor !== undefined) { + pbrMaterial.subSurface.translucencyColor = Color3.FromArray(extension.diffuseTransmissionColorFactor); } else { - return Promise.resolve(); + pbrMaterial.subSurface.translucencyColor = Color3.White(); + } + + if (extension.diffuseTransmissionColorTexture) { + promises.push( + this._loader.loadTextureInfoAsync(`${context}/diffuseTransmissionColorTexture`, extension.diffuseTransmissionColorTexture).then((texture: BaseTexture) => { + pbrMaterial.subSurface.translucencyColorTexture = texture; + }) + ); } + + return Promise.all(promises).then(() => {}); } } -GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_materials_translucency(loader)); +GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_materials_diffuse_transmission(loader)); diff --git a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts index e36607a6088..d4f4608f8f7 100644 --- a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts +++ b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts @@ -64,7 +64,7 @@ export class KHR_materials_dispersion implements IGLTFLoaderExtension { } // If transparency isn't enabled already, this extension shouldn't do anything. - // i.e. it requires either the KHR_materials_transmission or KHR_materials_translucency extensions. + // i.e. it requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. if (!babylonMaterial.subSurface.isRefractionEnabled || !extension.dispersion) { return Promise.resolve(); } diff --git a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts index 3dc8900c230..44cd51335a0 100644 --- a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts +++ b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts @@ -72,7 +72,7 @@ export class KHR_materials_volume implements IGLTFLoaderExtension { } // If transparency isn't enabled already, this extension shouldn't do anything. - // i.e. it requires either the KHR_materials_transmission or KHR_materials_translucency extensions. + // i.e. it requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. if ((!babylonMaterial.subSurface.isRefractionEnabled && !babylonMaterial.subSurface.isTranslucencyEnabled) || !extension.thicknessFactor) { return Promise.resolve(); } diff --git a/packages/dev/loaders/src/glTF/2.0/Extensions/index.ts b/packages/dev/loaders/src/glTF/2.0/Extensions/index.ts index 923024e679b..1cd54557d92 100644 --- a/packages/dev/loaders/src/glTF/2.0/Extensions/index.ts +++ b/packages/dev/loaders/src/glTF/2.0/Extensions/index.ts @@ -16,7 +16,7 @@ export * from "./KHR_materials_specular"; export * from "./KHR_materials_ior"; export * from "./KHR_materials_variants"; export * from "./KHR_materials_transmission"; -export * from "./KHR_materials_translucency"; +export * from "./KHR_materials_diffuse_transmission"; export * from "./KHR_materials_volume"; export * from "./KHR_materials_dispersion"; export * from "./KHR_mesh_quantization"; diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts new file mode 100644 index 00000000000..d5a18fda883 --- /dev/null +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts @@ -0,0 +1,122 @@ +import type { IMaterial, IKHRMaterialsDiffuseTransmission } from "babylonjs-gltf2interface"; +import type { IGLTFExporterExtensionV2 } from "../glTFExporterExtension"; +import { _Exporter } from "../glTFExporter"; +import type { Material } from "core/Materials/material"; +import { PBRMaterial } from "core/Materials/PBR/pbrMaterial"; +import type { BaseTexture } from "core/Materials/Textures/baseTexture"; + +const NAME = "KHR_materials_diffuse_transmission"; + +/** + * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export class KHR_materials_diffuse_transmission implements IGLTFExporterExtensionV2 { + /** Name of this extension */ + public readonly name = NAME; + + /** Defines whether this extension is enabled */ + public enabled = true; + + /** Defines whether this extension is required */ + public required = false; + + private _exporter: _Exporter; + + private _wasUsed = false; + + constructor(exporter: _Exporter) { + this._exporter = exporter; + } + + public dispose() {} + + /** @internal */ + public get wasUsed() { + return this._wasUsed; + } + + /** + * After exporting a material, deal with additional textures + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns array of additional textures to export + */ + public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] { + const additionalTextures: BaseTexture[] = []; + + if (babylonMaterial instanceof PBRMaterial) { + if (this._isExtensionEnabled(babylonMaterial)) { + if (babylonMaterial.subSurface.thicknessTexture) { + additionalTextures.push(babylonMaterial.subSurface.thicknessTexture); + } + return additionalTextures; + } + } + + return additionalTextures; + } + + private _isExtensionEnabled(mat: PBRMaterial): boolean { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + const subs = mat.subSurface; + if (!subs.isTranslucencyEnabled) { + return false; + } + + return ( + !mat.unlit && + !subs.useAlbedoToTintTranslucency && + subs.useGltfStyleTextures && + subs.volumeIndexOfRefraction === 1 && + subs.minimumThickness === 0 && + subs.maximumThickness === 0 + ); + } + + private _hasTexturesExtension(mat: PBRMaterial): boolean { + return mat.subSurface.translucencyIntensityTexture != null || mat.subSurface.translucencyColorTexture != null; + } + + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns promise that resolves with the updated node + */ + public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise { + return new Promise((resolve) => { + if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) { + this._wasUsed = true; + + const subs = babylonMaterial.subSurface; + + const diffuseTransmissionFactor = subs.translucencyIntensity == 1 ? undefined : subs.translucencyIntensity; + const diffuseTransmissionTexture = this._exporter._glTFMaterialExporter._getTextureInfo(subs.translucencyIntensityTexture) ?? undefined; + const diffuseTransmissionColorFactor = !subs.translucencyColor || subs.translucencyColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.translucencyColor.asArray(); + const diffuseTransmissionColorTexture = this._exporter._glTFMaterialExporter._getTextureInfo(subs.translucencyColorTexture) ?? undefined; + + const diffuseTransmissionInfo: IKHRMaterialsDiffuseTransmission = { + diffuseTransmissionFactor, + diffuseTransmissionTexture, + diffuseTransmissionColorFactor, + diffuseTransmissionColorTexture, + hasTextures: () => { + return this._hasTexturesExtension(babylonMaterial); + }, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = diffuseTransmissionInfo; + } + resolve(node); + }); + } +} + +_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_diffuse_transmission(exporter)); diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts index 7109672fb10..c932c965079 100644 --- a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts @@ -65,7 +65,7 @@ export class KHR_materials_volume implements IGLTFExporterExtensionV2 { return false; } const subs = mat.subSurface; - // this extension requires either the KHR_materials_transmission or KHR_materials_translucency extensions. + // this extension requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. if (!subs.isRefractionEnabled && !subs.isTranslucencyEnabled) { return false; } diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts index b992ff21e63..cd981e5901e 100644 --- a/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts @@ -12,3 +12,4 @@ export * from "./KHR_materials_dispersion"; export * from "./KHR_materials_transmission"; export * from "./EXT_mesh_gpu_instancing"; export * from "./KHR_materials_emissive_strength"; +export * from "./KHR_materials_diffuse_transmission"; diff --git a/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts b/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts index dd1b80847fb..4193da355f3 100644 --- a/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts +++ b/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts @@ -1158,14 +1158,16 @@ declare module BABYLON.GLTF2 { } /** - * Interfaces from the KHR_materials_translucency extension + * Interfaces from the KHR_materials_diffuse_transmission extension * !!! Experimental Extension Subject to Changes !!! */ /** @internal */ - interface IKHRMaterialsTranslucency extends IMaterialExtension { - translucencyFactor?: number; - translucencyTexture?: ITextureInfo; + interface IKHRMaterialsDiffuseTransmission extends IMaterialExtension { + diffuseTransmissionFactor?: number; + diffuseTransmissionTexture?: ITextureInfo; + diffuseTransmissionColorFactor?: number[]; + diffuseTransmissionColorTexture?: ITextureInfo; } /** diff --git a/packages/tools/devHost/src/babylon.glTF2Interface.ts b/packages/tools/devHost/src/babylon.glTF2Interface.ts index ef1b8dea1e4..9df496583e1 100644 --- a/packages/tools/devHost/src/babylon.glTF2Interface.ts +++ b/packages/tools/devHost/src/babylon.glTF2Interface.ts @@ -1145,14 +1145,16 @@ interface IKHRMaterialsSheen extends IMaterialExtension { } /** - * Interfaces from the KHR_materials_translucency extension + * Interfaces from the KHR_materials_diffuse_transmission extension * !!! Experimental Extension Subject to Changes !!! */ /** @internal */ -interface IKHRMaterialsTranslucency extends IMaterialExtension { - translucencyFactor?: number; - translucencyTexture?: ITextureInfo; +interface IKHRMaterialsDiffuseTransmission extends IMaterialExtension { + diffuseTransmissionFactor?: number; + diffuseTransmissionTexture?: ITextureInfo; + diffuseTransmissionColorFactor?: number; + diffuseTransmissionColorTexture?: ITextureInfo; } /** From 5db27b5dcaecfcbdb16c2f0f5357eaa795b6e4bc Mon Sep 17 00:00:00 2001 From: sebavan Date: Thu, 18 Apr 2024 01:24:38 +0200 Subject: [PATCH 2/3] add missing inspector texture --- .../materials/pbrMaterialPropertyGridComponent.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx b/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx index 7e91c7469a4..308516f19ea 100644 --- a/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx +++ b/packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx @@ -923,6 +923,15 @@ export class PBRMaterialPropertyGridComponent extends React.Component + (material.subSurface.translucencyIntensityTexture = texture)} + onTextureRemoved={() => (material.subSurface.translucencyIntensityTexture = null)} + material={material} + onSelectionChangedObservable={this.props.onSelectionChangedObservable} + onDebugSelectionChangeObservable={this._onDebugSelectionChangeObservable} + /> Date: Thu, 18 Apr 2024 03:44:50 +0200 Subject: [PATCH 3/3] fix test compat --- packages/tools/tests/test/visualization/config.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/tools/tests/test/visualization/config.json b/packages/tools/tests/test/visualization/config.json index 764a4fc6fb8..8df98967261 100644 --- a/packages/tools/tests/test/visualization/config.json +++ b/packages/tools/tests/test/visualization/config.json @@ -931,17 +931,17 @@ }, { "title": "PBR shader code coverage 1", - "playgroundId": "#QI7TL3#16", + "playgroundId": "#QI7TL3#55", "referenceImage": "pbr-codecoverage1.png" }, { "title": "PBR shader code coverage 2", - "playgroundId": "#QI7TL3#17", + "playgroundId": "#QI7TL3#57", "referenceImage": "pbr-codecoverage2.png" }, { "title": "PBR shader code coverage 3", - "playgroundId": "#QI7TL3#18", + "playgroundId": "#QI7TL3#56", "referenceImage": "pbr-codecoverage3.png" }, {