From 1c4778db7ae45c2cad06331a6df6bcce61462b44 Mon Sep 17 00:00:00 2001 From: chubei Date: Fri, 13 Sep 2024 18:31:01 +0800 Subject: [PATCH] Add UV2 morph support and load UV and UV2 morph targets from glTF --- .../Node/Blocks/Vertex/morphTargetsBlock.ts | 56 ++++++++++++++++++- .../Node/Blocks/meshAttributeExistsBlock.ts | 3 + .../core/src/Materials/Node/nodeMaterial.ts | 2 + .../core/src/Materials/PBR/pbrBaseMaterial.ts | 1 + .../src/Materials/materialHelper.functions.ts | 2 + .../dev/core/src/Materials/shaderMaterial.ts | 4 ++ .../core/src/Materials/standardMaterial.ts | 1 + packages/dev/core/src/Morph/morphTarget.ts | 40 +++++++++++++ .../dev/core/src/Morph/morphTargetManager.ts | 27 +++++++++ .../ShadersInclude/morphTargetsVertex.fx | 9 +++ .../morphTargetsVertexDeclaration.fx | 4 ++ .../samplerVertexImplementation.fx | 2 +- .../dev/core/src/Shaders/default.vertex.fx | 9 +++ packages/dev/core/src/Shaders/depth.vertex.fx | 5 +- .../dev/core/src/Shaders/geometry.vertex.fx | 13 +++-- .../src/Shaders/glowMapGeneration.vertex.fx | 9 ++- .../dev/core/src/Shaders/outline.vertex.fx | 5 +- packages/dev/core/src/Shaders/pbr.vertex.fx | 9 +++ .../dev/core/src/Shaders/shadowMap.vertex.fx | 5 +- .../volumetricLightScatteringPass.vertex.fx | 5 +- .../ShadersInclude/morphTargetsVertex.fx | 9 +++ .../morphTargetsVertexDeclaration.fx | 4 ++ .../dev/loaders/src/glTF/2.0/glTFLoader.ts | 18 ++++++ 23 files changed, 227 insertions(+), 15 deletions(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts index d1a056d042a..65ab5792ed2 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts @@ -34,10 +34,12 @@ export class MorphTargetsBlock extends NodeMaterialBlock { NodeMaterialBlockConnectionPointTypes.Color4 | NodeMaterialBlockConnectionPointTypes.Vector4 | NodeMaterialBlockConnectionPointTypes.Vector3 ); this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.Vector2); + this.registerInput("uv2", NodeMaterialBlockConnectionPointTypes.Vector2); this.registerOutput("positionOutput", NodeMaterialBlockConnectionPointTypes.Vector3); this.registerOutput("normalOutput", NodeMaterialBlockConnectionPointTypes.Vector3); this.registerOutput("tangentOutput", NodeMaterialBlockConnectionPointTypes.Vector4); this.registerOutput("uvOutput", NodeMaterialBlockConnectionPointTypes.Vector2); + this.registerOutput("uv2Output", NodeMaterialBlockConnectionPointTypes.Vector2); } /** @@ -70,12 +72,19 @@ export class MorphTargetsBlock extends NodeMaterialBlock { } /** - * Gets the tangent input component + * Gets the uv input component */ public get uv(): NodeMaterialConnectionPoint { return this._inputs[3]; } + /** + * Gets the uv2 input component + */ + public get uv2(): NodeMaterialConnectionPoint { + return this._inputs[4]; + } + /** * Gets the position output component */ @@ -98,12 +107,19 @@ export class MorphTargetsBlock extends NodeMaterialBlock { } /** - * Gets the tangent output component + * Gets the uv output component */ public get uvOutput(): NodeMaterialConnectionPoint { return this._outputs[3]; } + /** + * Gets the uv2 output component + */ + public get uv2Output(): NodeMaterialConnectionPoint { + return this._outputs[4]; + } + public override initialize(state: NodeMaterialBuildState) { state._excludeVariableName("morphTargetInfluences"); @@ -170,6 +186,15 @@ export class MorphTargetsBlock extends NodeMaterialBlock { } uvInput.output.connectTo(this.uv); } + if (!this.uv2.isConnected) { + let uv2Input = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === "uv2" && additionalFilteringInfo(b)); + + if (!uv2Input) { + uv2Input = new InputBlock("uv2"); + uv2Input.setAsAttribute("uv2"); + } + uv2Input.output.connectTo(this.uv2); + } } public override prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) { @@ -208,10 +233,12 @@ export class MorphTargetsBlock extends NodeMaterialBlock { const normal = this.normal; const tangent = this.tangent; const uv = this.uv; + const uv2 = this.uv2; const positionOutput = this.positionOutput; const normalOutput = this.normalOutput; const tangentOutput = this.tangentOutput; const uvOutput = this.uvOutput; + const uv2Output = this.uv2Output; const state = vertexShaderState; const repeatCount = defines.NUM_MORPH_INFLUENCERS as number; @@ -219,6 +246,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock { const hasNormals = manager && manager.supportsNormals && defines["NORMAL"]; const hasTangents = manager && manager.supportsTangents && defines["TANGENT"]; const hasUVs = manager && manager.supportsUVs && defines["UV1"]; + const hasUV2s = manager && manager.supportsUV2s && defines["UV2"]; let injectionCode = ""; @@ -260,6 +288,13 @@ export class MorphTargetsBlock extends NodeMaterialBlock { } else { injectionCode += `${tangentOutput.associatedVariableName}.w = 1.;\n`; } + injectionCode += `vertexID += 1.0;\n`; + injectionCode += `#endif\n`; + } + + if (hasUV2s) { + injectionCode += `#ifdef MORPHTARGETS_UV2\n`; + injectionCode += `${uv2Output.associatedVariableName} += (readVector3FromRawSampler(i, vertexID).xy - ${uv2.associatedVariableName}) * morphTargetInfluences[i];\n`; injectionCode += `#endif\n`; } @@ -291,6 +326,12 @@ export class MorphTargetsBlock extends NodeMaterialBlock { } injectionCode += `#endif\n`; } + + if (hasUV2s) { + injectionCode += `#ifdef MORPHTARGETS_UV2\n`; + injectionCode += `${uv2Output.associatedVariableName}.xy += (uv2_${index} - ${uv2.associatedVariableName}.xy) * morphTargetInfluences[${index}];\n`; + injectionCode += `#endif\n`; + } } } injectionCode += `#endif\n`; @@ -312,6 +353,10 @@ export class MorphTargetsBlock extends NodeMaterialBlock { if (hasUVs) { state.attributes.push(VertexBuffer.UVKind + "_" + index); } + + if (hasUV2s) { + state.attributes.push(VertexBuffer.UV2Kind + "_" + index); + } } } } @@ -333,10 +378,12 @@ export class MorphTargetsBlock extends NodeMaterialBlock { const normal = this.normal; const tangent = this.tangent; const uv = this.uv; + const uv2 = this.uv2; const positionOutput = this.positionOutput; const normalOutput = this.normalOutput; const tangentOutput = this.tangentOutput; const uvOutput = this.uvOutput; + const uv2Output = this.uv2Output; const comments = `//${this.name}`; state.uniforms.push("morphTargetInfluences"); @@ -366,6 +413,11 @@ export class MorphTargetsBlock extends NodeMaterialBlock { state.compilationString += `#else\n`; state.compilationString += `${state._declareOutput(uvOutput)} = vec2(0., 0.);\n`; state.compilationString += `#endif\n`; + state.compilationString += `#ifdef UV2\n`; + state.compilationString += `${state._declareOutput(uv2Output)} = ${uv2.associatedVariableName};\n`; + state.compilationString += `#else\n`; + state.compilationString += `${state._declareOutput(uv2Output)} = vec2(0., 0.);\n`; + state.compilationString += `#endif\n`; // Repeatable content this._repeatableContentAnchor = state._repeatableContentAnchor; diff --git a/packages/dev/core/src/Materials/Node/Blocks/meshAttributeExistsBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/meshAttributeExistsBlock.ts index 4e4f0ac0503..d28135208d6 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/meshAttributeExistsBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/meshAttributeExistsBlock.ts @@ -89,6 +89,9 @@ export class MeshAttributeExistsBlock extends NodeMaterialBlock { case "uvOutput": this.attributeType = MeshAttributeExistsBlockTypes.UV1; break; + case "uv2Output": + this.attributeType = MeshAttributeExistsBlockTypes.UV2; + break; } } }); diff --git a/packages/dev/core/src/Materials/Node/nodeMaterial.ts b/packages/dev/core/src/Materials/Node/nodeMaterial.ts index 32240159de2..d8e0ed5038b 100644 --- a/packages/dev/core/src/Materials/Node/nodeMaterial.ts +++ b/packages/dev/core/src/Materials/Node/nodeMaterial.ts @@ -154,6 +154,8 @@ export class NodeMaterialDefines extends MaterialDefines implements IImageProces public MORPHTARGETS_TANGENT = false; /** Morph target uv */ public MORPHTARGETS_UV = false; + /** Morph target uv2 */ + public MORPHTARGETS_UV2 = false; /** Number of morph influencers */ public NUM_MORPH_INFLUENCERS = 0; /** Using a texture to store morph target data */ diff --git a/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts b/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts index 77138c03e49..85a88e4316a 100644 --- a/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts +++ b/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts @@ -236,6 +236,7 @@ export class PBRMaterialDefines extends MaterialDefines implements IImageProcess public MORPHTARGETS_NORMAL = false; public MORPHTARGETS_TANGENT = false; public MORPHTARGETS_UV = false; + public MORPHTARGETS_UV2 = false; public NUM_MORPH_INFLUENCERS = 0; public MORPHTARGETS_TEXTURE = false; diff --git a/packages/dev/core/src/Materials/materialHelper.functions.ts b/packages/dev/core/src/Materials/materialHelper.functions.ts index 48c106424e7..95d913de2c1 100644 --- a/packages/dev/core/src/Materials/materialHelper.functions.ts +++ b/packages/dev/core/src/Materials/materialHelper.functions.ts @@ -679,6 +679,7 @@ export function PrepareDefinesForMorphTargets(mesh: AbstractMesh, defines: any) const manager = (mesh).morphTargetManager; if (manager) { defines["MORPHTARGETS_UV"] = manager.supportsUVs && defines["UV1"]; + defines["MORPHTARGETS_UV2"] = manager.supportsUV2s && defines["UV2"]; defines["MORPHTARGETS_TANGENT"] = manager.supportsTangents && defines["TANGENT"]; defines["MORPHTARGETS_NORMAL"] = manager.supportsNormals && defines["NORMAL"]; defines["NUM_MORPH_INFLUENCERS"] = manager.numMaxInfluencers || manager.numInfluencers; @@ -687,6 +688,7 @@ export function PrepareDefinesForMorphTargets(mesh: AbstractMesh, defines: any) defines["MORPHTARGETS_TEXTURE"] = manager.isUsingTextureForTargets; } else { defines["MORPHTARGETS_UV"] = false; + defines["MORPHTARGETS_UV2"] = false; defines["MORPHTARGETS_TANGENT"] = false; defines["MORPHTARGETS_NORMAL"] = false; defines["MORPHTARGETS"] = false; diff --git a/packages/dev/core/src/Materials/shaderMaterial.ts b/packages/dev/core/src/Materials/shaderMaterial.ts index 00d3db8d18c..077582723c2 100644 --- a/packages/dev/core/src/Materials/shaderMaterial.ts +++ b/packages/dev/core/src/Materials/shaderMaterial.ts @@ -770,12 +770,16 @@ export class ShaderMaterial extends PushMaterial { const manager = mesh ? (mesh).morphTargetManager : null; if (manager) { const uv = manager.supportsUVs && defines.indexOf("#define UV1") !== -1; + const uv2 = manager.supportsUV2s && defines.indexOf("#define UV2") !== -1; const tangent = manager.supportsTangents && defines.indexOf("#define TANGENT") !== -1; const normal = manager.supportsNormals && defines.indexOf("#define NORMAL") !== -1; numInfluencers = manager.numMaxInfluencers || manager.numInfluencers; if (uv) { defines.push("#define MORPHTARGETS_UV"); } + if (uv2) { + defines.push("#define MORPHTARGETS_UV2"); + } if (tangent) { defines.push("#define MORPHTARGETS_TANGENT"); } diff --git a/packages/dev/core/src/Materials/standardMaterial.ts b/packages/dev/core/src/Materials/standardMaterial.ts index 13591cfe65c..ba0b57cacef 100644 --- a/packages/dev/core/src/Materials/standardMaterial.ts +++ b/packages/dev/core/src/Materials/standardMaterial.ts @@ -159,6 +159,7 @@ export class StandardMaterialDefines extends MaterialDefines implements IImagePr public MORPHTARGETS_NORMAL = false; public MORPHTARGETS_TANGENT = false; public MORPHTARGETS_UV = false; + public MORPHTARGETS_UV2 = false; public NUM_MORPH_INFLUENCERS = 0; public MORPHTARGETS_TEXTURE = false; public NONUNIFORMSCALING = false; // https://playground.babylonjs.com#V6DWIH diff --git a/packages/dev/core/src/Morph/morphTarget.ts b/packages/dev/core/src/Morph/morphTarget.ts index b4b97c193df..6f85cc962c3 100644 --- a/packages/dev/core/src/Morph/morphTarget.ts +++ b/packages/dev/core/src/Morph/morphTarget.ts @@ -27,6 +27,7 @@ export class MorphTarget implements IAnimatable { private _normals: Nullable = null; private _tangents: Nullable = null; private _uvs: Nullable = null; + private _uv2s: Nullable = null; private _influence: number; private _uniqueId = 0; @@ -136,6 +137,13 @@ export class MorphTarget implements IAnimatable { return !!this._uvs; } + /** + * Gets a boolean defining if the target contains texture coordinates 2 data + */ + public get hasUV2s(): boolean { + return !!this._uv2s; + } + /** * Affects position data to this target * @param data defines the position data to use @@ -224,6 +232,28 @@ export class MorphTarget implements IAnimatable { return this._uvs; } + /** + * Affects texture coordinates 2 data to this target + * @param data defines the texture coordinates 2 data to use + */ + public setUV2s(data: Nullable) { + const hadUV2s = this.hasUV2s; + + this._uv2s = data; + + if (hadUV2s !== this.hasUV2s) { + this._onDataLayoutChanged.notifyObservers(undefined); + } + } + + /** + * Gets the texture coordinates 2 data stored in this target + * @returns a FloatArray containing the texture coordinates 2 data (or null if not present) + */ + public getUV2s(): Nullable { + return this._uv2s; + } + /** * Clone the current target * @returns a new MorphTarget @@ -235,6 +265,7 @@ export class MorphTarget implements IAnimatable { newOne._normals = this._normals; newOne._tangents = this._tangents; newOne._uvs = this._uvs; + newOne._uv2s = this._uv2s; return newOne; } @@ -262,6 +293,9 @@ export class MorphTarget implements IAnimatable { if (this.hasUVs) { serializationObject.uvs = Array.prototype.slice.call(this.getUVs()); } + if (this.hasUV2s) { + serializationObject.uv2s = Array.prototype.slice.call(this.getUV2s()); + } // Animations SerializationHelper.AppendSerializedAnimations(this, serializationObject); @@ -302,6 +336,9 @@ export class MorphTarget implements IAnimatable { if (serializationObject.uvs) { result.setUVs(serializationObject.uvs); } + if (serializationObject.uv2s) { + result.setUV2s(serializationObject.uv2s); + } // Animations if (serializationObject.animations) { @@ -352,6 +389,9 @@ export class MorphTarget implements IAnimatable { if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) { result.setUVs(mesh.getVerticesData(VertexBuffer.UVKind)); } + if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) { + result.setUV2s(mesh.getVerticesData(VertexBuffer.UV2Kind)); + } return result; } diff --git a/packages/dev/core/src/Morph/morphTargetManager.ts b/packages/dev/core/src/Morph/morphTargetManager.ts index 60d5cd13e85..08e19a38a80 100644 --- a/packages/dev/core/src/Morph/morphTargetManager.ts +++ b/packages/dev/core/src/Morph/morphTargetManager.ts @@ -30,6 +30,7 @@ export class MorphTargetManager implements IDisposable { private _supportsNormals = false; private _supportsTangents = false; private _supportsUVs = false; + private _supportsUV2s = false; private _vertexCount = 0; private _uniqueId = 0; private _tempInfluences = new Array(); @@ -74,6 +75,11 @@ export class MorphTargetManager implements IDisposable { */ public enableUVMorphing = true; + /** + * Gets or sets a boolean indicating if UV2 must be morphed + */ + public enableUV2Morphing = true; + /** * Sets a boolean indicating that adding new target or updating an existing target will not update the underlying data buffers */ @@ -174,6 +180,13 @@ export class MorphTargetManager implements IDisposable { return this._supportsUVs && this.enableUVMorphing; } + /** + * Gets a boolean indicating if this manager supports morphing of texture coordinates 2 + */ + public get supportsUV2s(): boolean { + return this._supportsUV2s && this.enableUV2Morphing; + } + /** * Gets the number of targets stored in this manager */ @@ -315,6 +328,7 @@ export class MorphTargetManager implements IDisposable { copy.enableNormalMorphing = this.enableNormalMorphing; copy.enableTangentMorphing = this.enableTangentMorphing; copy.enableUVMorphing = this.enableUVMorphing; + copy.enableUV2Morphing = this.enableUV2Morphing; return copy; } @@ -346,6 +360,7 @@ export class MorphTargetManager implements IDisposable { this._supportsNormals = true; this._supportsTangents = true; this._supportsUVs = true; + this._supportsUV2s = true; this._vertexCount = 0; if (this._scene && this._targets.length > this._scene.getEngine().getCaps().texture2DArrayMaxLayerCount) { @@ -374,6 +389,7 @@ export class MorphTargetManager implements IDisposable { this._supportsNormals = this._supportsNormals && target.hasNormals; this._supportsTangents = this._supportsTangents && target.hasTangents; this._supportsUVs = this._supportsUVs && target.hasUVs; + this._supportsUV2s = this._supportsUV2s && target.hasUV2s; const positions = target.getPositions(); if (positions) { @@ -427,6 +443,10 @@ export class MorphTargetManager implements IDisposable { this._textureVertexStride++; } + if (this.supportsUV2s) { + this._textureVertexStride++; + } + this._textureWidth = this._vertexCount * this._textureVertexStride || 1; this._textureHeight = 1; @@ -460,6 +480,7 @@ export class MorphTargetManager implements IDisposable { const normals = target.getNormals(); const uvs = target.getUVs(); const tangents = target.getTangents(); + const uv2s = target.getUV2s(); if (!positions) { if (index === 0) { @@ -495,6 +516,12 @@ export class MorphTargetManager implements IDisposable { data[offset + 2] = tangents[vertex * 3 + 2]; offset += 4; } + + if (this._supportsUV2s && uv2s) { + data[offset] = uv2s[vertex * 2]; + data[offset + 1] = uv2s[vertex * 2 + 1]; + offset += 4; + } } } diff --git a/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertex.fx b/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertex.fx index 15267e5c350..a582222daab 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertex.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertex.fx @@ -20,6 +20,11 @@ #ifdef MORPHTARGETS_TANGENT tangentUpdated.xyz += (readVector3FromRawSampler(i, vertexID) - tangent.xyz) * morphTargetInfluences[i]; + vertexID += 1.0; + #endif + + #ifdef MORPHTARGETS_UV2 + uv2Updated += (readVector3FromRawSampler(i, vertexID).xy - uv2) * morphTargetInfluences[i]; #endif } #endif @@ -37,5 +42,9 @@ #ifdef MORPHTARGETS_UV uvUpdated += (uv_{X} - uv) * morphTargetInfluences[{X}]; #endif + + #ifdef MORPHTARGETS_UV2 + uv2Updated += (uv2_{X} - uv2) * morphTargetInfluences[{X}]; + #endif #endif #endif \ No newline at end of file diff --git a/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertexDeclaration.fx b/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertexDeclaration.fx index d43ac95ebaf..30c747c4e77 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertexDeclaration.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertexDeclaration.fx @@ -13,6 +13,10 @@ #ifdef MORPHTARGETS_UV attribute vec2 uv_{X}; #endif + + #ifdef MORPHTARGETS_UV2 + attribute vec2 uv2_{X}; + #endif #elif {X} == 0 uniform int morphTargetCount; #endif diff --git a/packages/dev/core/src/Shaders/ShadersInclude/samplerVertexImplementation.fx b/packages/dev/core/src/Shaders/ShadersInclude/samplerVertexImplementation.fx index 50a24234757..1b51b7a4479 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/samplerVertexImplementation.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/samplerVertexImplementation.fx @@ -6,7 +6,7 @@ #ifdef UV2 else if (v_INFONAME_ == 1.) { - v_VARYINGNAME_UV = vec2(_MATRIXNAME_Matrix * vec4(uv2, 1.0, 0.0)); + v_VARYINGNAME_UV = vec2(_MATRIXNAME_Matrix * vec4(uv2Updated, 1.0, 0.0)); } #endif #ifdef UV3 diff --git a/packages/dev/core/src/Shaders/default.vertex.fx b/packages/dev/core/src/Shaders/default.vertex.fx index 20d040448d2..98786f6a732 100644 --- a/packages/dev/core/src/Shaders/default.vertex.fx +++ b/packages/dev/core/src/Shaders/default.vertex.fx @@ -86,6 +86,9 @@ void main(void) { #ifdef UV1 vec2 uvUpdated = uv; #endif +#ifdef UV2 + vec2 uv2Updated = uv2; +#endif #include #include[0..maxSimultaneousMorphTargets] @@ -152,8 +155,14 @@ void main(void) { #ifndef UV1 vec2 uvUpdated = vec2(0., 0.); #endif +#ifndef UV2 + vec2 uv2Updated = vec2(0., 0.); +#endif #ifdef MAINUV1 vMainUV1 = uvUpdated; +#endif +#ifdef MAINUV2 + vMainUV2 = uv2Updated; #endif #include[2..7] diff --git a/packages/dev/core/src/Shaders/depth.vertex.fx b/packages/dev/core/src/Shaders/depth.vertex.fx index e38dc935b94..dad4e45b613 100644 --- a/packages/dev/core/src/Shaders/depth.vertex.fx +++ b/packages/dev/core/src/Shaders/depth.vertex.fx @@ -43,6 +43,9 @@ void main(void) #ifdef UV1 vec2 uvUpdated = uv; #endif +#ifdef UV2 + vec2 uv2Updated = uv2; +#endif #include #include[0..maxSimultaneousMorphTargets] @@ -71,7 +74,7 @@ void main(void) vUV = vec2(diffuseMatrix * vec4(uvUpdated, 1.0, 0.0)); #endif #ifdef UV2 - vUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0)); + vUV = vec2(diffuseMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif diff --git a/packages/dev/core/src/Shaders/geometry.vertex.fx b/packages/dev/core/src/Shaders/geometry.vertex.fx index 99c15f13af0..b7e0b829d2e 100644 --- a/packages/dev/core/src/Shaders/geometry.vertex.fx +++ b/packages/dev/core/src/Shaders/geometry.vertex.fx @@ -73,6 +73,9 @@ void main(void) #ifdef UV1 vec2 uvUpdated = uv; #endif +#ifdef UV2 + vec2 uv2Updated = uv2; +#endif #include #include[0..maxSimultaneousMorphTargets] @@ -165,19 +168,19 @@ void main(void) #endif #ifdef UV2 #if defined(ALPHATEST) && defined(ALPHATEST_UV2) - vUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0)); + vUV = vec2(diffuseMatrix * vec4(uv2Updated, 1.0, 0.0)); #else - vUV = uv2; + vUV = uv2Updated; #endif #ifdef BUMP_UV2 - vBumpUV = vec2(bumpMatrix * vec4(uv2, 1.0, 0.0)); + vBumpUV = vec2(bumpMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #ifdef REFLECTIVITY_UV2 - vReflectivityUV = vec2(reflectivityMatrix * vec4(uv2, 1.0, 0.0)); + vReflectivityUV = vec2(reflectivityMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #ifdef ALBEDO_UV2 - vAlbedoUV = vec2(albedoMatrix * vec4(uv2, 1.0, 0.0)); + vAlbedoUV = vec2(albedoMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif #endif diff --git a/packages/dev/core/src/Shaders/glowMapGeneration.vertex.fx b/packages/dev/core/src/Shaders/glowMapGeneration.vertex.fx index 93f128bf56e..bb388482cdc 100644 --- a/packages/dev/core/src/Shaders/glowMapGeneration.vertex.fx +++ b/packages/dev/core/src/Shaders/glowMapGeneration.vertex.fx @@ -53,6 +53,9 @@ void main(void) #ifdef UV1 vec2 uvUpdated = uv; #endif +#ifdef UV2 + vec2 uv2Updated = uv2; +#endif #include #include[0..maxSimultaneousMorphTargets] @@ -76,7 +79,7 @@ vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0); vUVDiffuse = vec2(diffuseMatrix * vec4(uvUpdated, 1.0, 0.0)); #endif #ifdef DIFFUSEUV2 - vUVDiffuse = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0)); + vUVDiffuse = vec2(diffuseMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif @@ -85,7 +88,7 @@ vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0); vUVOpacity = vec2(opacityMatrix * vec4(uvUpdated, 1.0, 0.0)); #endif #ifdef OPACITYUV2 - vUVOpacity = vec2(opacityMatrix * vec4(uv2, 1.0, 0.0)); + vUVOpacity = vec2(opacityMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif @@ -94,7 +97,7 @@ vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0); vUVEmissive = vec2(emissiveMatrix * vec4(uvUpdated, 1.0, 0.0)); #endif #ifdef EMISSIVEUV2 - vUVEmissive = vec2(emissiveMatrix * vec4(uv2, 1.0, 0.0)); + vUVEmissive = vec2(emissiveMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif diff --git a/packages/dev/core/src/Shaders/outline.vertex.fx b/packages/dev/core/src/Shaders/outline.vertex.fx index 3c6c273bb57..a37820320c6 100644 --- a/packages/dev/core/src/Shaders/outline.vertex.fx +++ b/packages/dev/core/src/Shaders/outline.vertex.fx @@ -38,6 +38,9 @@ void main(void) vec3 normalUpdated = normal; #ifdef UV1 vec2 uvUpdated = uv; +#endif +#ifdef UV2 + vec2 uv2Updated = uv2; #endif #include #include[0..maxSimultaneousMorphTargets] @@ -57,7 +60,7 @@ void main(void) vUV = vec2(diffuseMatrix * vec4(uvUpdated, 1.0, 0.0)); #endif #ifdef UV2 - vUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0)); + vUV = vec2(diffuseMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif #include diff --git a/packages/dev/core/src/Shaders/pbr.vertex.fx b/packages/dev/core/src/Shaders/pbr.vertex.fx index f48c5b68a40..fdd0accada9 100644 --- a/packages/dev/core/src/Shaders/pbr.vertex.fx +++ b/packages/dev/core/src/Shaders/pbr.vertex.fx @@ -121,6 +121,9 @@ void main(void) { #ifdef UV1 vec2 uvUpdated = uv; #endif +#ifdef UV2 + vec2 uv2Updated = uv2; +#endif #include #include[0..maxSimultaneousMorphTargets] @@ -198,9 +201,15 @@ void main(void) { #ifndef UV1 vec2 uvUpdated = vec2(0., 0.); #endif +#ifndef UV2 + vec2 uv2Updated = vec2(0., 0.); +#endif #ifdef MAINUV1 vMainUV1 = uvUpdated; #endif +#ifdef MAINUV2 + vMainUV2 = uv2Updated; +#endif #include[2..7] diff --git a/packages/dev/core/src/Shaders/shadowMap.vertex.fx b/packages/dev/core/src/Shaders/shadowMap.vertex.fx index 07bc09fdf27..4f5edf31cfa 100644 --- a/packages/dev/core/src/Shaders/shadowMap.vertex.fx +++ b/packages/dev/core/src/Shaders/shadowMap.vertex.fx @@ -48,6 +48,9 @@ vec3 positionUpdated = position; #ifdef UV1 vec2 uvUpdated = uv; #endif +#ifdef UV2 + vec2 uv2Updated = uv2; +#endif #ifdef NORMAL vec3 normalUpdated = normal; #endif @@ -88,7 +91,7 @@ gl_Position = viewProjection * worldPos; vUV = vec2(diffuseMatrix * vec4(uvUpdated, 1.0, 0.0)); #endif #ifdef UV2 - vUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0)); + vUV = vec2(diffuseMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif diff --git a/packages/dev/core/src/Shaders/volumetricLightScatteringPass.vertex.fx b/packages/dev/core/src/Shaders/volumetricLightScatteringPass.vertex.fx index c9b02dfb154..13db30cd5c2 100644 --- a/packages/dev/core/src/Shaders/volumetricLightScatteringPass.vertex.fx +++ b/packages/dev/core/src/Shaders/volumetricLightScatteringPass.vertex.fx @@ -32,6 +32,9 @@ void main(void) #if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV1) vec2 uvUpdated = uv; #endif +#if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV2) + vec2 uv2Updated = uv2; +#endif #include #include[0..maxSimultaneousMorphTargets] @@ -48,7 +51,7 @@ void main(void) vUV = vec2(diffuseMatrix * vec4(uvUpdated, 1.0, 0.0)); #endif #ifdef UV2 - vUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0)); + vUV = vec2(diffuseMatrix * vec4(uv2Updated, 1.0, 0.0)); #endif #endif } diff --git a/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertex.fx b/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertex.fx index fc600ad03b9..deeec4f6646 100644 --- a/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertex.fx +++ b/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertex.fx @@ -22,6 +22,11 @@ #ifdef MORPHTARGETS_TANGENT tangentUpdated = vec4f(tangentUpdated.xyz + (readVector3FromRawSampler(i, vertexID) - vertexInputs.tangent.xyz) * uniforms.morphTargetInfluences[i], tangentUpdated.a); + vertexID = vertexID + 1.0; + #endif + + #ifdef MORPHTARGETS_UV2 + uv2Updated = uv2Updated + (readVector3FromRawSampler(i, vertexID).xy - vertexInputs.uv2) * uniforms.morphTargetInfluences[i]; #endif } #endif @@ -39,5 +44,9 @@ #ifdef MORPHTARGETS_UV uvUpdated = uvUpdated + (vertexInputs.uv_{X} - vertexInputs.uv) * uniforms.morphTargetInfluences[{X}]; #endif + + #ifdef MORPHTARGETS_UV2 + uv2Updated = uv2Updated + (vertexInputs.uv2_{X} - vertexInputs.uv2) * uniforms.morphTargetInfluences[{X}]; + #endif #endif #endif \ No newline at end of file diff --git a/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertexDeclaration.fx b/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertexDeclaration.fx index e571c05e9c3..ef1ed7863e5 100644 --- a/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertexDeclaration.fx +++ b/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertexDeclaration.fx @@ -13,6 +13,10 @@ #ifdef MORPHTARGETS_UV attribute uv_{X} : vec2; #endif + + #ifdef MORPHTARGETS_UV2 + attribute uv2_{X} : vec2; + #endif #elif {X} == 0 uniform morphTargetCount: i32; #endif diff --git a/packages/dev/loaders/src/glTF/2.0/glTFLoader.ts b/packages/dev/loaders/src/glTF/2.0/glTFLoader.ts index 151685b3420..038c4f537b2 100644 --- a/packages/dev/loaders/src/glTF/2.0/glTFLoader.ts +++ b/packages/dev/loaders/src/glTF/2.0/glTFLoader.ts @@ -1282,6 +1282,24 @@ export class GLTFLoader implements IGLTFLoader { babylonMorphTarget.setTangents(tangents); }); + loadAttribute("TEXCOORD_0", VertexBuffer.UVKind, (babylonVertexBuffer, data) => { + const uvs = new Float32Array(data.length); + babylonVertexBuffer.forEach(data.length, (value, index) => { + uvs[index] = data[index] + value; + }); + + babylonMorphTarget.setUVs(uvs); + }); + + loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind, (babylonVertexBuffer, data) => { + const uvs = new Float32Array(data.length); + babylonVertexBuffer.forEach(data.length, (value, index) => { + uvs[index] = data[index] + value; + }); + + babylonMorphTarget.setUV2s(uvs); + }); + return Promise.all(promises).then(() => {}); }