Browse Source

Fix morph targets

David Catuhe 4 years ago
parent
commit
15f540c4d4

+ 1 - 1
src/Layers/effectLayer.ts

@@ -560,7 +560,7 @@ export abstract class EffectLayer {
                 ["world", "mBones", "viewProjection",
                     "glowColor", "morphTargetInfluences", "boneTextureWidth",
                     "diffuseMatrix", "emissiveMatrix", "opacityMatrix", "opacityIntensity",
-                    "morphTargetTextureInfo"],
+                    "morphTargetTextureInfo", "morphTargetTextureIndices"],
                 ["diffuseSampler", "emissiveSampler", "opacitySampler", "boneSampler", "morphTargets"], join,
                 fallbacks, undefined, undefined, { maxSimultaneousMorphTargets: morphInfluencers });
         }

+ 1 - 1
src/Lights/Shadows/shadowGenerator.ts

@@ -1473,7 +1473,7 @@ export class ShadowGenerator implements IShadowGenerator {
                 let shaderName = "shadowMap";
                 let uniforms = ["world", "mBones", "viewProjection", "diffuseMatrix", "lightDataSM", "depthValuesSM", "biasAndScaleSM", "morphTargetInfluences", "boneTextureWidth",
                                 "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "vClipPlane5", "vClipPlane6", "softTransparentShadowSM",
-                                "morphTargetTextureInfo"];
+                                "morphTargetTextureInfo", "morphTargetTextureIndices"];
                 let samplers = ["diffuseSampler", "boneSampler", "morphTargets"];
 
                 // Custom shader?

+ 7 - 9
src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts

@@ -182,13 +182,14 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
         let injectionCode = "";
 
         if (manager?.isUsingTextureForTargets && repeatCount > 0) {
-            injectionCode += `float vertexID = float(gl_VertexID) * morphTargetTextureInfo.x;\r\n`;
+            injectionCode += `float vertexID;\r\n`;
         }
 
         for (var index = 0; index < repeatCount; index++) {
             injectionCode += `#ifdef MORPHTARGETS\r\n`;
             if (manager?.isUsingTextureForTargets) {
-                injectionCode += `${positionOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID) - ${position.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                injectionCode += `vertexID = float(gl_VertexID) * morphTargetTextureInfo.x;\r\n`;
+                injectionCode += `${positionOutput.associatedVariableName} += (readVector3FromRawSampler(${index}, vertexID) - ${position.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                 injectionCode += `vertexID += 1.0;\r\n`;
             } else {
                 injectionCode += `${positionOutput.associatedVariableName} += (position${index} - ${position.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
@@ -197,7 +198,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
             if (hasNormals) {
                 injectionCode += `#ifdef MORPHTARGETS_NORMAL\r\n`;
                 if (manager?.isUsingTextureForTargets) {
-                    injectionCode += `${normalOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID) - ${normal.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                    injectionCode += `${normalOutput.associatedVariableName} += (readVector3FromRawSampler(${index}, vertexID) - ${normal.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                     injectionCode += `vertexID += 1.0;\r\n`;
                 } else {
                     injectionCode += `${normalOutput.associatedVariableName} += (normal${index} - ${normal.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
@@ -208,7 +209,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
             if (hasUVs) {
                 injectionCode += `#ifdef MORPHTARGETS_UV\r\n`;
                 if (manager?.isUsingTextureForTargets) {
-                    injectionCode += `${uvOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID).xy - ${uv.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                    injectionCode += `${uvOutput.associatedVariableName} += (readVector3FromRawSampler(${index}, vertexID).xy - ${uv.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                     injectionCode += `vertexID += 1.0;\r\n`;
                 } else {
                     injectionCode += `${uvOutput.associatedVariableName}.xy += (uv_${index} - ${uv.associatedVariableName}.xy) * morphTargetInfluences[${index}];\r\n`;
@@ -219,17 +220,13 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
             if (hasTangents) {
                 injectionCode += `#ifdef MORPHTARGETS_TANGENT\r\n`;
                 if (manager?.isUsingTextureForTargets) {
-                    injectionCode += `${tangentOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID) - ${tangent.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                    injectionCode += `${tangentOutput.associatedVariableName} += (readVector3FromRawSampler(${index}, vertexID) - ${tangent.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                 } else {
                     injectionCode += `${tangentOutput.associatedVariableName}.xyz += (tangent${index} - ${tangent.associatedVariableName}.xyz) * morphTargetInfluences[${index}];\r\n`;
                 }
                 injectionCode += `#endif\r\n`;
             }
 
-            if (manager?.isUsingTextureForTargets) {
-                injectionCode += `vertexID = float(gl_VertexID) * morphTargetTextureInfo.x;\r\n`;
-            }
-
             injectionCode += `#endif\r\n`;
         }
 
@@ -279,6 +276,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
 
         state.uniforms.push("morphTargetInfluences");
         state.uniforms.push("morphTargetTextureInfo");
+        state.uniforms.push("morphTargetTextureIndices");
         state.samplers.push("morphTargets");
 
         state._emitFunctionFromInclude("morphTargetsVertexGlobalDeclaration", comments);

+ 1 - 1
src/Materials/PBR/pbrBaseMaterial.ts

@@ -1296,7 +1296,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             "vSphericalL2_2", "vSphericalL2_1", "vSphericalL20", "vSphericalL21", "vSphericalL22",
             "vReflectionMicrosurfaceInfos",
             "vTangentSpaceParams", "boneTextureWidth",
-            "vDebugMode", "morphTargetTextureInfo"
+            "vDebugMode", "morphTargetTextureInfo", "morphTargetTextureIndices"
         ];
 
         var samplers = ["albedoSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",

+ 1 - 1
src/Materials/standardMaterial.ts

@@ -1216,7 +1216,7 @@ export class StandardMaterial extends PushMaterial {
                 "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
                 "vReflectionPosition", "vReflectionSize",
                 "logarithmicDepthConstant", "vTangentSpaceParams", "alphaCutOff", "boneTextureWidth",
-                "morphTargetTextureInfo"
+                "morphTargetTextureInfo", "morphTargetTextureIndices"
             ];
 
             var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler",

+ 10 - 0
src/Morph/morphTargetManager.ts

@@ -20,6 +20,7 @@ export class MorphTargetManager implements IDisposable {
     private _activeTargets = new SmartArray<MorphTarget>(16);
     private _scene: Nullable<Scene>;
     private _influences: Float32Array;
+    private _morphTargetTextureIndices: Float32Array;
     private _supportsNormals = false;
     private _supportsTangents = false;
     private _supportsUVs = false;
@@ -197,6 +198,7 @@ export class MorphTargetManager implements IDisposable {
     /** @hidden */
     public _bind(effect: Effect) {
         effect.setFloat3("morphTargetTextureInfo", this._textureVertexStride, this._textureWidth, this._textureHeight);
+        effect.setFloatArray("morphTargetTextureIndices", this._morphTargetTextureIndices);
         effect.setTexture("morphTargets", this._targetStoreTexture);
     }
 
@@ -242,12 +244,20 @@ export class MorphTargetManager implements IDisposable {
         this._supportsTangents = true;
         this._supportsUVs = true;
         this._vertexCount = 0;
+
+        if (!this._morphTargetTextureIndices || this._morphTargetTextureIndices.length !== this._targets.length) {
+            this._morphTargetTextureIndices = new Float32Array(this._targets.length);
+        }
+
+        var targetIndex = -1;
         for (var target of this._targets) {
+            targetIndex++;
             if (target.influence === 0) {
                 continue;
             }
 
             this._activeTargets.push(target);
+            this._morphTargetTextureIndices[influenceCount] = targetIndex;
             this._tempInfluences[influenceCount++] = target.influence;
 
             this._supportsNormals = this._supportsNormals && target.hasNormals;

+ 1 - 1
src/Rendering/depthRenderer.ts

@@ -273,7 +273,7 @@ export class DepthRenderer {
             this._cachedDefines = join;
             this._effect = this._scene.getEngine().createEffect("depth",
                 attribs,
-                ["world", "mBones", "viewProjection", "diffuseMatrix", "depthValues", "morphTargetInfluences", "morphTargetTextureInfo"],
+                ["world", "mBones", "viewProjection", "diffuseMatrix", "depthValues", "morphTargetInfluences", "morphTargetTextureInfo", "morphTargetTextureIndices"],
                 ["diffuseSampler", "morphTargets"], join,
                 undefined, undefined, undefined, { maxSimultaneousMorphTargets: numMorphInfluencers });
         }

+ 1 - 1
src/Rendering/geometryBufferRenderer.ts

@@ -461,7 +461,7 @@ export class GeometryBufferRenderer {
                     uniformsNames: [
                         "world", "mBones", "viewProjection", "diffuseMatrix", "view", "previousWorld", "previousViewProjection", "mPreviousBones",
                         "bumpMatrix", "reflectivityMatrix", "vTangentSpaceParams", "vBumpInfos",
-                        "morphTargetInfluences", "morphTargetTextureInfo"
+                        "morphTargetInfluences", "morphTargetTextureInfo", "morphTargetTextureIndices"
                     ],
                     samplers: ["diffuseSampler", "bumpSampler", "reflectivitySampler", "morphTargets"],
                     defines: join,

+ 1 - 1
src/Rendering/outlineRenderer.ts

@@ -295,7 +295,7 @@ export class OutlineRenderer implements ISceneComponent {
             this._effect = this.scene.getEngine().createEffect("outline",
                 attribs,
                 ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant",
-                "morphTargetInfluences", "morphTargetTextureInfo"],
+                "morphTargetInfluences", "morphTargetTextureInfo", "morphTargetTextureIndices"],
                 ["diffuseSampler", "morphTargets"], join,
                 undefined, undefined, undefined,
                 { maxSimultaneousMorphTargets: numMorphInfluencers });

+ 4 - 4
src/Shaders/ShadersInclude/morphTargetsVertex.fx

@@ -1,21 +1,21 @@
 #ifdef MORPHTARGETS
 	#ifdef MORPHTARGETS_TEXTURE	
 		vertexID = float(gl_VertexID) * morphTargetTextureInfo.x;
-		positionUpdated += (readVector3FromRawSampler({X}., vertexID) - position) * morphTargetInfluences[{X}];
+		positionUpdated += (readVector3FromRawSampler({X}, vertexID) - position) * morphTargetInfluences[{X}];
 		vertexID += 1.0;
 	
 		#ifdef MORPHTARGETS_NORMAL
-			normalUpdated += (readVector3FromRawSampler({X}., vertexID)  - normal) * morphTargetInfluences[{X}];
+			normalUpdated += (readVector3FromRawSampler({X}, vertexID)  - normal) * morphTargetInfluences[{X}];
 			vertexID += 1.0;
 		#endif
 
 		#ifdef MORPHTARGETS_UV
-			uvUpdated += (readVector3FromRawSampler({X}., vertexID).xy - uv) * morphTargetInfluences[{X}];
+			uvUpdated += (readVector3FromRawSampler({X}, vertexID).xy - uv) * morphTargetInfluences[{X}];
 			vertexID += 1.0;
 		#endif
 
 		#ifdef MORPHTARGETS_TANGENT
-			tangentUpdated.xyz += (readVector3FromRawSampler({X}., vertexID)  - tangent.xyz) * morphTargetInfluences[{X}];
+			tangentUpdated.xyz += (readVector3FromRawSampler({X}, vertexID)  - tangent.xyz) * morphTargetInfluences[{X}];
 		#endif
 	#else
 		positionUpdated += (position{X} - position) * morphTargetInfluences[{X}];

+ 4 - 3
src/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.fx

@@ -2,15 +2,16 @@
 	uniform float morphTargetInfluences[NUM_MORPH_INFLUENCERS];
 
 	#ifdef MORPHTARGETS_TEXTURE	
-		precision mediump sampler2DArray;
+		precision mediump sampler2DArray;		
+		uniform float morphTargetTextureIndices[NUM_MORPH_INFLUENCERS];
 		uniform vec3 morphTargetTextureInfo;
 		uniform sampler2DArray morphTargets;
 
-		vec3 readVector3FromRawSampler(float targetIndex, float vertexIndex)
+		vec3 readVector3FromRawSampler(int targetIndex, float vertexIndex)
 		{			
 			float y = floor(vertexIndex / morphTargetTextureInfo.y);
 			float x = vertexIndex - y * morphTargetTextureInfo.y;
-			vec3 textureUV = vec3((x + 0.5) / morphTargetTextureInfo.y, (y + 0.5) / morphTargetTextureInfo.z, targetIndex);
+			vec3 textureUV = vec3((x + 0.5) / morphTargetTextureInfo.y, (y + 0.5) / morphTargetTextureInfo.z, morphTargetTextureIndices[targetIndex]);
 			return texture(morphTargets, textureUV).xyz;
 		}
 	#endif