浏览代码

Merge pull request #799 from Palmer-JC/master

Variable Bone Influencers
David Catuhe 9 年之前
父节点
当前提交
4f698c5c31

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

@@ -268,7 +268,11 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
 

+ 24 - 0
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -1338,10 +1338,34 @@
                 }
             }
 
+            if (parsedGeometry.matricesIndicesExtra) {
+                if (!parsedGeometry.matricesIndicesExtra._isExpanded) {
+                    var floatIndices = [];
+
+                    for (var i = 0; i < parsedGeometry.matricesIndicesExtra.length; i++) {
+                        var matricesIndex = parsedGeometry.matricesIndicesExtra[i];
+
+                        floatIndices.push(matricesIndex & 0x000000FF);
+                        floatIndices.push((matricesIndex & 0x0000FF00) >> 8);
+                        floatIndices.push((matricesIndex & 0x00FF0000) >> 16);
+                        floatIndices.push(matricesIndex >> 24);
+                    }
+
+                    mesh.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, floatIndices, false);
+                } else {
+                    delete parsedGeometry.matricesIndices._isExpanded;
+                    mesh.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, parsedGeometry.matricesIndicesExtra, false);
+                }
+            }
+
             if (parsedGeometry.matricesWeights) {
                 mesh.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, parsedGeometry.matricesWeights, false);
             }
 
+            if (parsedGeometry.matricesWeightsExtra) {
+                mesh.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, false);
+            }
+
             mesh.setIndices(parsedGeometry.indices);
         }
 

+ 18 - 0
src/Materials/babylon.effect.ts

@@ -5,6 +5,9 @@
         private _currentRank = 32;
         private _maxRank = -1;
 
+        private _mesh : AbstractMesh;
+        private _meshRank : number;
+
         public addFallback(rank: number, define: string): void {
             if (!this._defines[rank]) {
                 if (rank < this._currentRank) {
@@ -21,6 +24,15 @@
             this._defines[rank].push(define);
         }
 
+            public addCPUSkinningFallback(rank: number, mesh : BABYLON.AbstractMesh){
+                this._meshRank = rank;
+                this._mesh = mesh;
+    
+                if (rank > this._maxRank) {
+                    this._maxRank = rank;
+                }
+            }
+
         public get isMoreFallbacks(): boolean {
             return this._currentRank <= this._maxRank;
         }
@@ -33,6 +45,12 @@
                 currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
             }
 
+            if (this._mesh && this._currentRank === this._meshRank){
+                this._mesh.computeBonesUsingShaders = false;
+                currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
+                Tools.Log("Falling back to CPU skinning for " + this._mesh.name);
+            }
+
             this._currentRank++;
 
             return currentDefines;

+ 8 - 10
src/Materials/babylon.material.ts

@@ -26,12 +26,12 @@
             for (var index = 0; index < this._keys.length; index++) {
                 var prop = this._keys[index];
 
-                if (prop === "BonesPerMesh") {
+                if (typeof(this[prop]) === "number") {
                     this[prop] = 0;
-                    continue;
+                
+                }else { 
+                    this[prop] = false; 
                 }
-
-                this[prop] = false;
             }
         }
 
@@ -40,12 +40,10 @@
             for (var index = 0; index < this._keys.length; index++) {
                 var prop = this._keys[index];
 
-                if (prop === "BonesPerMesh" && this[prop] > 0) {
-                    result += "#define BonesPerMesh " + this[prop] + "\n";
-                    continue;
-                }
-
-                if (this[prop]) {
+                if (typeof(this[prop]) === "number") {
+                    result += "#define "  + prop + " " + this[prop] + "\n";
+                
+                }else if (this[prop]) {
                     result += "#define " + prop + "\n";
                 }
             }

+ 7 - 8
src/Materials/babylon.pbrMaterial.ts

@@ -11,8 +11,7 @@
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public BONES = false;
-        public BONES4 = false;
+        public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
         public POINTSIZE = false;
@@ -121,9 +120,8 @@
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.BONES = true;
+                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -144,9 +142,6 @@
                     fallbacks.addFallback(1, "FOG");
                 }             
 
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
-                }
 
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
@@ -167,9 +162,13 @@
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
+                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
+                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 2 - 3
src/Materials/babylon.shaderMaterial.ts

@@ -146,10 +146,9 @@
 
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                defines.push("#define BONES");
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
-                defines.push("#define BONES4");
-                fallbacks.addFallback(0, "BONES4");
+                fallbacks.addCPUSkinningFallback(0, mesh);
             }
 
             // Alpha test

+ 9 - 7
src/Materials/babylon.standardMaterial.ts

@@ -76,8 +76,7 @@
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public BONES = false;
-        public BONES4 = false;
+        public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
         public GLOSSINESS = false;
@@ -565,9 +564,8 @@
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.BONES = true;
+                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -650,8 +648,8 @@
                     fallbacks.addFallback(4, "FRESNEL");
                 }
 
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0){
+                    fallbacks.addCPUSkinningFallback(0, mesh);    
                 }
 
                 //Attributes
@@ -673,9 +671,13 @@
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
+                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
+                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 18 - 4
src/Mesh/babylon.mesh.ts

@@ -1560,6 +1560,10 @@
             var matricesIndicesData = this.getVerticesData(VertexBuffer.MatricesIndicesKind);
             var matricesWeightsData = this.getVerticesData(VertexBuffer.MatricesWeightsKind);
 
+            var needExtras = this.numBoneInfluencers > 4;
+            var matricesIndicesExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;
+            var matricesWeightsExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;
+
             var skeletonMatrices = skeleton.getTransformMatrices();
 
             var tempVector3 = Vector3.Zero();
@@ -1567,8 +1571,9 @@
             var tempMatrix = new Matrix();
 
             var matWeightIdx = 0;
-            for (var index = 0; index < positionsData.length; index += 3) {
-                for (var inf = 0; inf < this.numBoneInfluencers; inf++) {
+            var inf : number;
+            for (var index = 0; index < positionsData.length; index += 3, matWeightIdx += 4) {
+                for (inf = 0; inf < 4; inf++) {
                     var weight = matricesWeightsData[matWeightIdx + inf];
                     if (weight > 0) {
                         Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesData[matWeightIdx + inf] * 16, weight, tempMatrix);
@@ -1576,8 +1581,17 @@
 
                     } else break;
                 }
-                matWeightIdx += this.numBoneInfluencers;
-
+                if (needExtras) {
+                    for (inf = 0; inf < 4; inf++) {
+                        var weight = matricesWeightsExtraData[matWeightIdx + inf];
+                        if (weight > 0) {
+                            Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesExtraData[matWeightIdx + inf] * 16, weight, tempMatrix);
+                            finalMatrix.addToSelf(tempMatrix);
+
+                        } else break;           
+                    }
+                }
+                
                 Vector3.TransformCoordinatesFromFloatsToRef(this._sourcePositions[index], this._sourcePositions[index + 1], this._sourcePositions[index + 2], finalMatrix, tempVector3);
                 tempVector3.toArray(positionsData, index);
 

+ 50 - 0
src/Mesh/babylon.mesh.vertexData.ts

@@ -20,6 +20,8 @@
         public colors: number[] | Float32Array;
         public matricesIndices: number[] | Float32Array;
         public matricesWeights: number[] | Float32Array;
+        public matricesIndicesExtra: number[] | Float32Array;
+        public matricesWeightsExtra: number[] | Float32Array;
         public indices: number[];
 
         public set(data: number[] | Float32Array, kind: string) {
@@ -57,6 +59,12 @@
                 case VertexBuffer.MatricesWeightsKind:
                     this.matricesWeights = data;
                     break;
+                case VertexBuffer.MatricesIndicesExtraKind:
+                    this.matricesIndicesExtra = data;
+                    break;
+                case VertexBuffer.MatricesWeightsExtraKind:
+                    this.matricesWeightsExtra = data;
+                    break;
             }
         }
 
@@ -121,6 +129,14 @@
                 meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updatable);
             }
 
+            if (this.matricesIndicesExtra) {
+                meshOrGeometry.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updatable);
+            }
+
+            if (this.matricesWeightsExtra) {
+                meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updatable);
+            }
+
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices);
             }
@@ -171,6 +187,14 @@
                 meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);
             }
 
+            if (this.matricesIndicesExtra) {
+                meshOrGeometry.updateVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updateExtends, makeItUnique);
+            }
+
+            if (this.matricesWeightsExtra) {
+                meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updateExtends, makeItUnique);
+            }
+
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices);
             }
@@ -310,6 +334,24 @@
                 }
             }
 
+            if (other.matricesIndicesExtra) {
+                if (!this.matricesIndicesExtra) {
+                    this.matricesIndicesExtra = [];
+                }
+                for (index = 0; index < other.matricesIndicesExtra.length; index++) {
+                    (<number[]>this.matricesIndicesExtra).push(other.matricesIndicesExtra[index]);
+                }
+            }
+
+            if (other.matricesWeightsExtra) {
+                if (!this.matricesWeightsExtra) {
+                    this.matricesWeightsExtra = [];
+                }
+                for (index = 0; index < other.matricesWeightsExtra.length; index++) {
+                    (<number[]>this.matricesWeightsExtra).push(other.matricesWeightsExtra[index]);
+                }
+            }
+
             if (other.colors) {
                 if (!this.colors) {
                     this.colors = [];
@@ -376,6 +418,14 @@
                 result.matricesWeights = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsKind, copyWhenShared);
             }
 
+            if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesIndicesExtraKind)) {
+                result.matricesIndicesExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesIndicesExtraKind, copyWhenShared);
+            }
+
+            if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesWeightsExtraKind)) {
+                result.matricesWeightsExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsExtraKind, copyWhenShared);
+            }
+
             result.indices = meshOrGeometry.getIndices(copyWhenShared);
 
             return result;

+ 12 - 0
src/Mesh/babylon.vertexBuffer.ts

@@ -51,9 +51,11 @@
                     this._strideSize = 4;
                     break;
                 case VertexBuffer.MatricesIndicesKind:
+                case VertexBuffer.MatricesIndicesExtraKind:
                     this._strideSize = 4;
                     break;
                 case VertexBuffer.MatricesWeightsKind:
+                case VertexBuffer.MatricesWeightsExtraKind:
                     this._strideSize = 4;
                     break;
             }
@@ -134,6 +136,8 @@
         private static _ColorKind = "color";
         private static _MatricesIndicesKind = "matricesIndices";
         private static _MatricesWeightsKind = "matricesWeights";
+        private static _MatricesIndicesExtraKind = "matricesIndicesExtra";
+        private static _MatricesWeightsExtraKind = "matricesWeightsExtra";
 
         public static get PositionKind(): string {
             return VertexBuffer._PositionKind;
@@ -178,5 +182,13 @@
         public static get MatricesWeightsKind(): string {
             return VertexBuffer._MatricesWeightsKind;
         }
+
+        public static get MatricesIndicesExtraKind(): string {
+            return VertexBuffer._MatricesIndicesExtraKind;
+        }
+
+        public static get MatricesWeightsExtraKind(): string {
+            return VertexBuffer._MatricesWeightsExtraKind;
+        }
     }
 } 

+ 1 - 1
src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -146,7 +146,7 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
 

+ 5 - 1
src/Rendering/babylon.depthRenderer.ts

@@ -112,7 +112,11 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
 

+ 5 - 1
src/Rendering/babylon.outlineRenderer.ts

@@ -68,7 +68,11 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
 

+ 43 - 21
src/Shaders/default.vertex.fx

@@ -14,9 +14,17 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniforms
@@ -130,30 +138,44 @@ varying vec3 vDirectionW;
 #endif
 
 void main(void) {
-	mat4 finalWorld;
-
 #ifdef REFLECTIONMAP_SKYBOX
 	vPositionUVW = position;
 #endif 
 
 #ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
+	mat4 finalWorld = mat4(world0, world1, world2, world3);
 #else
-	finalWorld = world;
-#endif
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = finalWorld * (m0 + m1 + m2);
-#endif 
-
+	mat4 finalWorld = world;
+#endif
+
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif 
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 

+ 40 - 15
src/Shaders/depth.vertex.fx

@@ -2,9 +2,17 @@
 
 // Attribute
 attribute vec3 position;
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniform
@@ -18,9 +26,6 @@ uniform mat4 world;
 #endif
 
 uniform mat4 viewProjection;
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
 
 #if defined(ALPHATEST) || defined(NEED_UV)
 varying vec2 vUV;
@@ -41,16 +46,36 @@ void main(void)
 	mat4 finalWorld = world;
 #endif
 
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
-#else
-	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+	
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 #if defined(ALPHATEST) || defined(BASIC_RENDER)
 #ifdef UV1

+ 41 - 24
src/Shaders/legacydefault.vertex.fx

@@ -12,9 +12,17 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniforms
@@ -58,10 +66,6 @@ uniform vec2 vBumpInfos;
 uniform mat4 bumpMatrix;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 // Output
 varying vec3 vPositionW;
 varying vec3 vNormalW;
@@ -142,24 +146,37 @@ vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 #endif
 
 void main(void) {
-	mat4 finalWorld;
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = world * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = world * (m0 + m1 + m2);
-#endif 
-
-#else
-	finalWorld = world;
+	mat4 finalWorld = world;
+
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif 
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
-
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);

+ 39 - 16
src/Shaders/outline.vertex.fx

@@ -4,9 +4,17 @@
 attribute vec3 position;
 attribute vec3 normal;
 
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniform
@@ -22,9 +30,6 @@ uniform mat4 world;
 #endif
 
 uniform mat4 viewProjection;
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
 
 #ifdef ALPHATEST
 varying vec2 vUV;
@@ -45,18 +50,36 @@ void main(void)
 	mat4 finalWorld = world;
 #endif
 
-	vec3 offsetPosition = position + normal * offset;
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
 
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-	gl_Position = viewProjection * finalWorld * vec4(offsetPosition, 1.0);
-#else
-	gl_Position = viewProjection * finalWorld * vec4(offsetPosition, 1.0);
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+	
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 #ifdef ALPHATEST
 #ifdef UV1

+ 43 - 25
src/Shaders/pbr.vertex.fx

@@ -14,9 +14,17 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniforms
@@ -32,10 +40,6 @@ uniform mat4 world;
 uniform mat4 view;
 uniform mat4 viewProjection;
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -60,26 +64,40 @@ varying float fFogDistance;
 #endif
 
 void main(void) {
-	mat4 finalWorld;
-
 #ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
+	mat4 finalWorld = mat4(world0, world1, world2, world3);
 #else
-	finalWorld = world;
-#endif
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = finalWorld * (m0 + m1 + m2);
-#endif 
-
+	mat4 finalWorld = world;
+#endif
+
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+	
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 

+ 40 - 15
src/Shaders/shadowMap.vertex.fx

@@ -2,9 +2,17 @@
 
 // Attribute
 attribute vec3 position;
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniform
@@ -18,9 +26,6 @@ uniform mat4 world;
 #endif
 
 uniform mat4 viewProjection;
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
 
 varying vec4 vPosition;
 
@@ -43,16 +48,36 @@ void main(void)
 	mat4 finalWorld = world;
 #endif
 
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#endif
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+	
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
 
-	vPosition = viewProjection * finalWorld * vec4(position, 1.0);
-	gl_Position = vPosition;
+	finalWorld = finalWorld * influence;
+#endif
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 #ifdef ALPHATEST
 #ifdef UV1