Browse Source

First round of modifications to support shaders includes

David Catuhe 9 years ago
parent
commit
713d2425c1
33 changed files with 669 additions and 770 deletions
  1. 6 0
      Tools/Gulp/config.json
  2. 21 4
      Tools/Gulp/gulpfile.js
  3. 17 17
      dist/preview release/babylon.core.js
  4. 160 160
      dist/preview release/babylon.d.ts
  5. 24 24
      dist/preview release/babylon.js
  6. 33 10
      dist/preview release/babylon.max.js
  7. 19 19
      dist/preview release/babylon.noworker.js
  8. 1 0
      dist/preview release/what's new.md
  9. 1 1
      materialsLibrary/dist/babylon.fireMaterial.js
  10. 1 1
      materialsLibrary/dist/babylon.fireMaterial.min.js
  11. 2 2
      materialsLibrary/dist/babylon.pbrMaterial.js
  12. 3 3
      materialsLibrary/dist/babylon.pbrMaterial.min.js
  13. 10 8
      materialsLibrary/dist/babylon.simpleMaterial.js
  14. 1 1
      materialsLibrary/dist/babylon.simpleMaterial.min.js
  15. 2 36
      materialsLibrary/materials/pbr/legacypbr.vertex.fx
  16. 4 54
      materialsLibrary/materials/pbr/pbr.vertex.fx
  17. 10 8
      materialsLibrary/materials/simple/babylon.simpleMaterial.ts
  18. 142 173
      materialsLibrary/materials/simple/simple.vertex.fx
  19. 71 13
      materialsLibrary/test/refs/babylon.max.js
  20. 30 2
      src/Materials/babylon.effect.js
  21. 35 2
      src/Materials/babylon.effect.ts
  22. 0 6
      src/Particles/babylon.solidParticleSystem.js
  23. 4 9
      src/Particles/babylon.solidParticleSystem.ts
  24. 10 0
      src/Shaders/ShadersInclude/bonesDeclaration.fx
  25. 29 0
      src/Shaders/ShadersInclude/bonesVertex.fx
  26. 8 0
      src/Shaders/ShadersInclude/instancesDeclaration.fx
  27. 5 0
      src/Shaders/ShadersInclude/instancesVertex.fx
  28. 5 54
      src/Shaders/default.vertex.fx
  29. 4 53
      src/Shaders/depth.vertex.fx
  30. 4 52
      src/Shaders/outline.vertex.fx
  31. 5 55
      src/Shaders/shadowMap.vertex.fx
  32. 1 1
      src/Tools/babylon.tools.js
  33. 1 2
      src/Tools/babylon.tools.ts

+ 6 - 0
Tools/Gulp/config.json

@@ -111,6 +111,12 @@
       "files": "../../src/Shaders/*.fx"
     }
   ],
+  "includeShadersDirectories": [
+    {
+      "variable": "BABYLON.Effect.IncludesShadersStore",
+      "files": "../../src/Shaders/ShadersInclude/*.fx"
+    }
+  ],
   "workers": [
     {
       "variable": "BABYLON.CollisionWorker",

+ 21 - 4
Tools/Gulp/gulpfile.js

@@ -14,6 +14,7 @@ var replace = require("gulp-replace");
 
 var config = require("./config.json");
 
+var includeShadersStream;
 var shadersStream;
 var workersStream;
 
@@ -26,7 +27,20 @@ function shadersName(filename) {
         .replace('.fx', 'Shader');
 }
 
-gulp.task("shaders", function (cb) {
+function includeShadersName(filename) {
+    return filename.replace('.fx', '');
+}
+
+gulp.task("includeShaders", function (cb) {
+    includeShadersStream = config.includeShadersDirectories.map(function (shadersDef) {
+        return gulp.src(shadersDef.files).pipe(srcToVariable({
+            variableName: shadersDef.variable, asMap: true, namingCallback: includeShadersName
+        }));
+    });
+    cb();
+});
+
+gulp.task("shaders", ["includeShaders"], function (cb) {
     shadersStream = config.shadersDirectories.map(function (shadersDef) {
         return gulp.src(shadersDef.files).pipe(srcToVariable({
             variableName: shadersDef.variable, asMap: true, namingCallback: shadersName
@@ -81,7 +95,8 @@ gulp.task('typescript-sourcemaps', function () {
 gulp.task("buildCore", ["shaders"], function () {
     return merge2(
         gulp.src(config.core.files),
-        shadersStream
+        shadersStream, 
+        includeShadersStream
         )
         .pipe(concat(config.build.minCoreFilename))
         .pipe(cleants())
@@ -95,7 +110,8 @@ gulp.task("buildNoWorker", ["shaders"], function () {
     return merge2(
         gulp.src(config.core.files),
         gulp.src(config.extras.files),
-        shadersStream
+        shadersStream, 
+        includeShadersStream
         )
         .pipe(concat(config.build.minNoWorkerFilename))
         .pipe(cleants())
@@ -110,7 +126,8 @@ gulp.task("build", ["workers", "shaders"], function () {
         gulp.src(config.core.files),
         gulp.src(config.extras.files),
         shadersStream,
-        workersStream
+        workersStream, 
+        includeShadersStream
         )
         .pipe(concat(config.build.filename))
         .pipe(cleants())

File diff suppressed because it is too large
+ 17 - 17
dist/preview release/babylon.core.js


+ 160 - 160
dist/preview release/babylon.d.ts

@@ -2537,6 +2537,39 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    interface ISceneLoaderPlugin {
+        extensions: string;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        private static _registeredPlugins;
+        private static _getPluginForFilename(sceneFilename);
+        static GetPluginForExtension(extension: string): ISceneLoaderPlugin;
+        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
         direction: Vector3;
         position: Vector3;
@@ -3230,39 +3263,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    interface ISceneLoaderPlugin {
-        extensions: string;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        private static _registeredPlugins;
-        private static _getPluginForFilename(sceneFilename);
-        static GetPluginForExtension(extension: string): ISceneLoaderPlugin;
-        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-    }
-}
-
-declare module BABYLON {
     class EffectFallbacks {
         private _defines;
         private _currentRank;
@@ -3305,6 +3305,7 @@ declare module BABYLON {
         _loadVertexShader(vertex: any, callback: (data: any) => void): void;
         _loadFragmentShader(fragment: any, callback: (data: any) => void): void;
         private _dumpShadersName();
+        private _processIncludes(sourceCode, callback);
         private _prepareEffect(vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks?);
         isSupported: boolean;
         _bindTexture(channel: string, texture: WebGLTexture): void;
@@ -3333,6 +3334,7 @@ declare module BABYLON {
         setColor3(uniformName: string, color3: Color3): Effect;
         setColor4(uniformName: string, color3: Color3, alpha: number): Effect;
         static ShadersStore: {};
+        static IncludesShadersStore: {};
     }
 }
 
@@ -3543,6 +3545,66 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    interface IPhysicsEnginePlugin {
+        name: string;
+        initialize(iterations?: number): any;
+        setGravity(gravity: Vector3): void;
+        getGravity(): Vector3;
+        runOneStep(delta: number): void;
+        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
+        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        unregisterMesh(mesh: AbstractMesh): any;
+        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
+        dispose(): void;
+        isSupported(): boolean;
+        updateBodyPosition(mesh: AbstractMesh): void;
+        getWorldObject(): any;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+    }
+    interface PhysicsBodyCreationOptions {
+        mass: number;
+        friction: number;
+        restitution: number;
+    }
+    interface PhysicsCompoundBodyPart {
+        mesh: Mesh;
+        impostor: number;
+    }
+    class PhysicsEngine {
+        gravity: Vector3;
+        private _currentPlugin;
+        constructor(plugin?: IPhysicsEnginePlugin);
+        _initialize(gravity?: Vector3): void;
+        _runOneStep(delta: number): void;
+        _setGravity(gravity: Vector3): void;
+        _getGravity(): Vector3;
+        _registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
+        _registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        _unregisterMesh(mesh: AbstractMesh): void;
+        _applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        _createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
+        _updateBodyPosition(mesh: AbstractMesh): void;
+        dispose(): void;
+        isSupported(): boolean;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+        getPhysicsPluginName(): string;
+        getWorldObject(): any;
+        static NoImpostor: number;
+        static SphereImpostor: number;
+        static BoxImpostor: number;
+        static PlaneImpostor: number;
+        static MeshImpostor: number;
+        static CapsuleImpostor: number;
+        static ConeImpostor: number;
+        static CylinderImpostor: number;
+        static ConvexHullImpostor: number;
+        static HeightmapImpostor: number;
+        static Epsilon: number;
+    }
+}
+
+declare module BABYLON {
     class AbstractMesh extends Node implements IDisposable {
         private static _BILLBOARDMODE_NONE;
         private static _BILLBOARDMODE_X;
@@ -5135,13 +5197,11 @@ declare module BABYLON {
         * Thus the particles generated from digest() have their property "positiion" yet set.
         * @param mesh the mesh to be digested
         * @param facetNb the number of mesh facets per particle (optional, default 1), this parameter is overriden by the parameter "number" if any
-        * @param delta the random extra number of facets per partical (optional, default 0), each particle will have between facetNb and facetNb + delta facets
         * @param number the wanted number of particles : each particle is built with mesh_total_facets / number facets (optional)
         */
         digest(mesh: Mesh, options?: {
             facetNb?: number;
             number?: number;
-            delta?: number;
         }): void;
         private _resetCopy();
         private _meshBuilder(p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, idx, idxInShape, options);
@@ -5284,66 +5344,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    interface IPhysicsEnginePlugin {
-        name: string;
-        initialize(iterations?: number): any;
-        setGravity(gravity: Vector3): void;
-        getGravity(): Vector3;
-        runOneStep(delta: number): void;
-        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
-        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        unregisterMesh(mesh: AbstractMesh): any;
-        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
-        dispose(): void;
-        isSupported(): boolean;
-        updateBodyPosition(mesh: AbstractMesh): void;
-        getWorldObject(): any;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-    }
-    interface PhysicsBodyCreationOptions {
-        mass: number;
-        friction: number;
-        restitution: number;
-    }
-    interface PhysicsCompoundBodyPart {
-        mesh: Mesh;
-        impostor: number;
-    }
-    class PhysicsEngine {
-        gravity: Vector3;
-        private _currentPlugin;
-        constructor(plugin?: IPhysicsEnginePlugin);
-        _initialize(gravity?: Vector3): void;
-        _runOneStep(delta: number): void;
-        _setGravity(gravity: Vector3): void;
-        _getGravity(): Vector3;
-        _registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
-        _registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        _unregisterMesh(mesh: AbstractMesh): void;
-        _applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        _createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
-        _updateBodyPosition(mesh: AbstractMesh): void;
-        dispose(): void;
-        isSupported(): boolean;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-        getPhysicsPluginName(): string;
-        getWorldObject(): any;
-        static NoImpostor: number;
-        static SphereImpostor: number;
-        static BoxImpostor: number;
-        static PlaneImpostor: number;
-        static MeshImpostor: number;
-        static CapsuleImpostor: number;
-        static ConeImpostor: number;
-        static CylinderImpostor: number;
-        static ConvexHullImpostor: number;
-        static HeightmapImpostor: number;
-        static Epsilon: number;
-    }
-}
-
-declare module BABYLON {
     class ReflectionProbe {
         name: string;
         private _scene;
@@ -5365,68 +5365,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class Sprite {
-        name: string;
-        position: Vector3;
-        color: Color4;
-        width: number;
-        height: number;
-        angle: number;
-        cellIndex: number;
-        invertU: number;
-        invertV: number;
-        disposeWhenFinishedAnimating: boolean;
-        animations: Animation[];
-        isPickable: boolean;
-        actionManager: ActionManager;
-        private _animationStarted;
-        private _loopAnimation;
-        private _fromIndex;
-        private _toIndex;
-        private _delay;
-        private _direction;
-        private _frameCount;
-        private _manager;
-        private _time;
-        size: number;
-        constructor(name: string, manager: SpriteManager);
-        playAnimation(from: number, to: number, loop: boolean, delay: number): void;
-        stopAnimation(): void;
-        _animate(deltaTime: number): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class SpriteManager {
-        name: string;
-        cellSize: number;
-        sprites: Sprite[];
-        renderingGroupId: number;
-        layerMask: number;
-        onDispose: () => void;
-        fogEnabled: boolean;
-        isPickable: boolean;
-        private _capacity;
-        private _spriteTexture;
-        private _epsilon;
-        private _scene;
-        private _vertexDeclaration;
-        private _vertexStrideSize;
-        private _vertexBuffer;
-        private _indexBuffer;
-        private _vertices;
-        private _effectBase;
-        private _effectFog;
-        constructor(name: string, imgUrl: string, capacity: number, cellSize: number, scene: Scene, epsilon?: number, samplingMode?: number);
-        private _appendSpriteVertex(index, sprite, offsetX, offsetY, rowSize);
-        intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): PickingInfo;
-        render(): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
     class AnaglyphPostProcess extends PostProcess {
         constructor(name: string, ratio: number, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean);
     }
@@ -5996,6 +5934,68 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class Sprite {
+        name: string;
+        position: Vector3;
+        color: Color4;
+        width: number;
+        height: number;
+        angle: number;
+        cellIndex: number;
+        invertU: number;
+        invertV: number;
+        disposeWhenFinishedAnimating: boolean;
+        animations: Animation[];
+        isPickable: boolean;
+        actionManager: ActionManager;
+        private _animationStarted;
+        private _loopAnimation;
+        private _fromIndex;
+        private _toIndex;
+        private _delay;
+        private _direction;
+        private _frameCount;
+        private _manager;
+        private _time;
+        size: number;
+        constructor(name: string, manager: SpriteManager);
+        playAnimation(from: number, to: number, loop: boolean, delay: number): void;
+        stopAnimation(): void;
+        _animate(deltaTime: number): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class SpriteManager {
+        name: string;
+        cellSize: number;
+        sprites: Sprite[];
+        renderingGroupId: number;
+        layerMask: number;
+        onDispose: () => void;
+        fogEnabled: boolean;
+        isPickable: boolean;
+        private _capacity;
+        private _spriteTexture;
+        private _epsilon;
+        private _scene;
+        private _vertexDeclaration;
+        private _vertexStrideSize;
+        private _vertexBuffer;
+        private _indexBuffer;
+        private _vertices;
+        private _effectBase;
+        private _effectFog;
+        constructor(name: string, imgUrl: string, capacity: number, cellSize: number, scene: Scene, epsilon?: number, samplingMode?: number);
+        private _appendSpriteVertex(index, sprite, offsetX, offsetY, rowSize);
+        intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): PickingInfo;
+        render(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
     class BoundingBoxRenderer {
         frontColor: Color3;
         backColor: Color3;
@@ -6848,6 +6848,9 @@ declare module BABYLON {
     }
 }
 
+declare module BABYLON.Internals {
+}
+
 declare module BABYLON {
     class ShadowGenerator {
         private static _FILTER_NONE;
@@ -6906,9 +6909,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
     class BaseTexture {
         name: string;

File diff suppressed because it is too large
+ 24 - 24
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 33 - 10
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 19 - 19
dist/preview release/babylon.noworker.js


+ 1 - 0
dist/preview release/what's new.md

@@ -2,6 +2,7 @@
   - **Major updates**
     - New refraction channel for Standard material (including fresnel support). Refraction texture can be provided by a reflection probe or a refraction texture. [See demo here](http://www.babylonjs.com/Demos/refraction/) ([deltakosh](https://github.com/deltakosh))
     - Added support for HDR cubemaps ([sebavan](https://github.com/sebavan))
+    - Support for shaders includes ([deltakosh](https://github.com/deltakosh))
   - **Updates**
     - New OnPickTrigger support for spritesManager ([deltakosh](https://github.com/deltakosh))
     - New SPS method `digest()` ([jerome](https://github.com/jbousquie))    

File diff suppressed because it is too large
+ 1 - 1
materialsLibrary/dist/babylon.fireMaterial.js


File diff suppressed because it is too large
+ 1 - 1
materialsLibrary/dist/babylon.fireMaterial.min.js


File diff suppressed because it is too large
+ 2 - 2
materialsLibrary/dist/babylon.pbrMaterial.js


File diff suppressed because it is too large
+ 3 - 3
materialsLibrary/dist/babylon.pbrMaterial.min.js


File diff suppressed because it is too large
+ 10 - 8
materialsLibrary/dist/babylon.simpleMaterial.js


File diff suppressed because it is too large
+ 1 - 1
materialsLibrary/dist/babylon.simpleMaterial.min.js


+ 2 - 36
materialsLibrary/materials/pbr/legacypbr.vertex.fx

@@ -13,16 +13,7 @@ attribute vec2 uv2;
 attribute vec4 color;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-uniform mat4 mBones[BonesPerMesh];
-
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#if NUM_BONE_INFLUENCERS > 4
-attribute vec4 matricesIndicesExtra;
-attribute vec4 matricesWeightsExtra;
-#endif
-#endif
+#include<bonesDeclaration>
 
 // Uniforms
 uniform mat4 world;
@@ -75,32 +66,7 @@ varying float fClipDistance;
 void main(void) {
     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	
+#include<bonesVertex>
 
     finalWorld = finalWorld * influence;
 #endif

+ 4 - 54
materialsLibrary/materials/pbr/pbr.vertex.fx

@@ -15,27 +15,10 @@ attribute vec2 uv2;
 attribute vec4 color;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-    uniform mat4 mBones[BonesPerMesh];
-
-    attribute vec4 matricesIndices;
-    attribute vec4 matricesWeights;
-    #if NUM_BONE_INFLUENCERS > 4
-        attribute vec4 matricesIndicesExtra;
-        attribute vec4 matricesWeightsExtra;
-    #endif
-#endif
+#include<bonesDeclaration>
 
 // Uniforms
-
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+#include<instancesDeclaration>
 
 uniform mat4 view;
 uniform mat4 viewProjection;
@@ -142,41 +125,8 @@ void main(void) {
     vPositionUVW = position;
 #endif 
 
-#ifdef INSTANCES
-    mat4 finalWorld = mat4(world0, world1, world2, world3);
-#else
-    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
+#include<instancesVertex>
+#include<bonesVertex>
 
     gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 

+ 10 - 8
materialsLibrary/materials/simple/babylon.simpleMaterial.ts

@@ -47,8 +47,7 @@ module BABYLON {
         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;
 
@@ -259,9 +258,8 @@ module BABYLON {
                     }
                 }
                 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
@@ -303,9 +301,9 @@ module BABYLON {
                         fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
                     }
                 }
-             
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -327,9 +325,13 @@ module BABYLON {
                     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) {

+ 142 - 173
materialsLibrary/materials/simple/simple.vertex.fx

@@ -1,173 +1,142 @@
-precision highp float;
-
-// Attributes
-attribute vec3 position;
-#ifdef NORMAL
-attribute vec3 normal;
-#endif
-#ifdef UV1
-attribute vec2 uv;
-#endif
-#ifdef UV2
-attribute vec2 uv2;
-#endif
-#ifdef VERTEXCOLOR
-attribute vec4 color;
-#endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#endif
-
-// Uniforms
-
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
-
-uniform mat4 view;
-uniform mat4 viewProjection;
-
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform mat4 diffuseMatrix;
-uniform vec2 vDiffuseInfos;
-#endif
-
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
-#ifdef POINTSIZE
-uniform float pointSize;
-#endif
-
-// Output
-varying vec3 vPositionW;
-#ifdef NORMAL
-varying vec3 vNormalW;
-#endif
-
-#ifdef VERTEXCOLOR
-varying vec4 vColor;
-#endif
-
-#ifdef CLIPPLANE
-uniform vec4 vClipPlane;
-varying float fClipDistance;
-#endif
-
-#ifdef FOG
-varying float fFogDistance;
-#endif
-
-#ifdef SHADOWS
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-uniform mat4 lightMatrix0;
-varying vec4 vPositionFromLight0;
-#endif
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-uniform mat4 lightMatrix1;
-varying vec4 vPositionFromLight1;
-#endif
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-uniform mat4 lightMatrix2;
-varying vec4 vPositionFromLight2;
-#endif
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-uniform mat4 lightMatrix3;
-varying vec4 vPositionFromLight3;
-#endif
-#endif
-
-void main(void) {
-	mat4 finalWorld;
-
-#ifdef INSTANCES
-	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 
-
-#endif
-	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
-
-	vec4 worldPos = finalWorld * vec4(position, 1.0);
-	vPositionW = vec3(worldPos);
-
-#ifdef NORMAL
-	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
-#endif
-
-	// Texture coordinates
-#ifndef UV1
-	vec2 uv = vec2(0., 0.);
-#endif
-#ifndef UV2
-	vec2 uv2 = vec2(0., 0.);
-#endif
-
-#ifdef DIFFUSE
-	if (vDiffuseInfos.x == 0.)
-	{
-		vDiffuseUV = vec2(diffuseMatrix * vec4(uv, 1.0, 0.0));
-	}
-	else
-	{
-		vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
-	}
-#endif
-
-	// Clip plane
-#ifdef CLIPPLANE
-	fClipDistance = dot(worldPos, vClipPlane);
-#endif
-
-	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
-
-	// Shadows
-#ifdef SHADOWS
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-	vPositionFromLight0 = lightMatrix0 * worldPos;
-#endif
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-	vPositionFromLight1 = lightMatrix1 * worldPos;
-#endif
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-	vPositionFromLight2 = lightMatrix2 * worldPos;
-#endif
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-	vPositionFromLight3 = lightMatrix3 * worldPos;
-#endif
-#endif
-
-	// Vertex color
-#ifdef VERTEXCOLOR
-	vColor = color;
-#endif
-
-	// Point size
-#ifdef POINTSIZE
-	gl_PointSize = pointSize;
-#endif
-}
+precision highp float;
+
+// Attributes
+attribute vec3 position;
+#ifdef NORMAL
+attribute vec3 normal;
+#endif
+#ifdef UV1
+attribute vec2 uv;
+#endif
+#ifdef UV2
+attribute vec2 uv2;
+#endif
+#ifdef VERTEXCOLOR
+attribute vec4 color;
+#endif
+
+#include<bonesDeclaration>
+
+// Uniforms
+#include<instancesDeclaration>
+
+uniform mat4 view;
+uniform mat4 viewProjection;
+
+#ifdef DIFFUSE
+varying vec2 vDiffuseUV;
+uniform mat4 diffuseMatrix;
+uniform vec2 vDiffuseInfos;
+#endif
+
+#ifdef POINTSIZE
+uniform float pointSize;
+#endif
+
+// Output
+varying vec3 vPositionW;
+#ifdef NORMAL
+varying vec3 vNormalW;
+#endif
+
+#ifdef VERTEXCOLOR
+varying vec4 vColor;
+#endif
+
+#ifdef CLIPPLANE
+uniform vec4 vClipPlane;
+varying float fClipDistance;
+#endif
+
+#ifdef FOG
+varying float fFogDistance;
+#endif
+
+#ifdef SHADOWS
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
+uniform mat4 lightMatrix0;
+varying vec4 vPositionFromLight0;
+#endif
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
+uniform mat4 lightMatrix1;
+varying vec4 vPositionFromLight1;
+#endif
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
+uniform mat4 lightMatrix2;
+varying vec4 vPositionFromLight2;
+#endif
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
+uniform mat4 lightMatrix3;
+varying vec4 vPositionFromLight3;
+#endif
+#endif
+
+void main(void) {
+
+#include<instancesVertex>
+#include<bonesVertex>
+
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
+
+	vec4 worldPos = finalWorld * vec4(position, 1.0);
+	vPositionW = vec3(worldPos);
+
+#ifdef NORMAL
+	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
+#endif
+
+	// Texture coordinates
+#ifndef UV1
+	vec2 uv = vec2(0., 0.);
+#endif
+#ifndef UV2
+	vec2 uv2 = vec2(0., 0.);
+#endif
+
+#ifdef DIFFUSE
+	if (vDiffuseInfos.x == 0.)
+	{
+		vDiffuseUV = vec2(diffuseMatrix * vec4(uv, 1.0, 0.0));
+	}
+	else
+	{
+		vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
+	}
+#endif
+
+	// Clip plane
+#ifdef CLIPPLANE
+	fClipDistance = dot(worldPos, vClipPlane);
+#endif
+
+	// Fog
+#ifdef FOG
+	fFogDistance = (view * worldPos).z;
+#endif
+
+	// Shadows
+#ifdef SHADOWS
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
+	vPositionFromLight0 = lightMatrix0 * worldPos;
+#endif
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
+	vPositionFromLight1 = lightMatrix1 * worldPos;
+#endif
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
+	vPositionFromLight2 = lightMatrix2 * worldPos;
+#endif
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
+	vPositionFromLight3 = lightMatrix3 * worldPos;
+#endif
+#endif
+
+	// Vertex color
+#ifdef VERTEXCOLOR
+	vColor = color;
+#endif
+
+	// Point size
+#ifdef POINTSIZE
+	gl_PointSize = pointSize;
+#endif
+}

File diff suppressed because it is too large
+ 71 - 13
materialsLibrary/test/refs/babylon.max.js


+ 30 - 2
src/Materials/babylon.effect.js

@@ -83,8 +83,12 @@ var BABYLON;
                 fragmentSource = baseName.fragment || baseName;
             }
             this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                    _this._prepareEffect(vertexCode, fragmentCode, attributesNames, defines, fallbacks);
+                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
+                    _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
+                        _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
+                            _this._prepareEffect(vertexCodeWithIncludes, fragmentCodeWithIncludes, attributesNames, defines, fallbacks);
+                        });
+                    });
                 });
             });
         }
@@ -183,9 +187,32 @@ var BABYLON;
                 BABYLON.Tools.Error("Fragment shader:" + this.name);
             }
         };
+        Effect.prototype._processIncludes = function (sourceCode, callback) {
+            var _this = this;
+            var regex = /#include<(.+)>/g;
+            var match = regex.exec(sourceCode);
+            var returnValue = new String(sourceCode);
+            while (match != null) {
+                var includeFile = match[1];
+                if (Effect.IncludesShadersStore[includeFile]) {
+                    returnValue = returnValue.replace(match[0], Effect.IncludesShadersStore[includeFile]);
+                }
+                else {
+                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                    BABYLON.Tools.LoadFile(includeShaderUrl, function (fileContent) {
+                        Effect.IncludesShadersStore[includeFile] = fileContent;
+                        _this._processIncludes(returnValue, callback);
+                    });
+                    return;
+                }
+                match = regex.exec(sourceCode);
+            }
+            callback(returnValue);
+        };
         Effect.prototype._prepareEffect = function (vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks) {
             try {
                 var engine = this._engine;
+                // Precision
                 if (!engine.getCaps().highPrecisionShaderSupported) {
                     vertexSourceCode = vertexSourceCode.replace("precision highp float", "precision mediump float");
                     fragmentSourceCode = fragmentSourceCode.replace("precision highp float", "precision mediump float");
@@ -391,6 +418,7 @@ var BABYLON;
         };
         // Statics
         Effect.ShadersStore = {};
+        Effect.IncludesShadersStore = {};
         return Effect;
     })();
     BABYLON.Effect = Effect;

+ 35 - 2
src/Materials/babylon.effect.ts

@@ -112,8 +112,12 @@
             }
 
             this._loadVertexShader(vertexSource, vertexCode => {
-                this._loadFragmentShader(fragmentSource, (fragmentCode) => {
-                    this._prepareEffect(vertexCode, fragmentCode, attributesNames, defines, fallbacks);
+                this._processIncludes(vertexCode, vertexCodeWithIncludes => {
+                    this._loadFragmentShader(fragmentSource, (fragmentCode) => {
+                        this._processIncludes(fragmentCode, fragmentCodeWithIncludes => {
+                            this._prepareEffect(vertexCodeWithIncludes, fragmentCodeWithIncludes, attributesNames, defines, fallbacks);
+                        });
+                    });
                 });
             });
         }
@@ -232,10 +236,38 @@
             }
         }
 
+        private _processIncludes(sourceCode: string, callback: (data: any) => void): void {
+            var regex = /#include<(.+)>/g;
+            var match = regex.exec(sourceCode);
+
+            var returnValue = new String(sourceCode);
+
+            while (match != null) {
+                var includeFile = match[1];
+
+                if (Effect.IncludesShadersStore[includeFile]) {
+                    returnValue = returnValue.replace(match[0], Effect.IncludesShadersStore[includeFile]);
+                } else {
+                    var includeShaderUrl = Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+
+                    Tools.LoadFile(includeShaderUrl, (fileContent) => {
+                        Effect.IncludesShadersStore[includeFile] = fileContent;
+                        this._processIncludes(<string>returnValue, callback)
+                    });
+                    return;
+                }
+
+                match = regex.exec(sourceCode);
+            }
+
+            callback(returnValue);
+        }
+
         private _prepareEffect(vertexSourceCode: string, fragmentSourceCode: string, attributesNames: string[], defines: string, fallbacks?: EffectFallbacks): void {
             try {
                 var engine = this._engine;
 
+                // Precision
                 if (!engine.getCaps().highPrecisionShaderSupported) { // Moving highp to mediump
                     vertexSourceCode = vertexSourceCode.replace("precision highp float", "precision mediump float");
                     fragmentSourceCode = fragmentSourceCode.replace("precision highp float", "precision mediump float");
@@ -507,5 +539,6 @@
 
         // Statics
         public static ShadersStore = {};
+        public static IncludesShadersStore = {};
     }
 } 

+ 0 - 6
src/Particles/babylon.solidParticleSystem.js

@@ -141,13 +141,11 @@ var BABYLON;
         * Thus the particles generated from digest() have their property "positiion" yet set.
         * @param mesh the mesh to be digested
         * @param facetNb the number of mesh facets per particle (optional, default 1), this parameter is overriden by the parameter "number" if any
-        * @param delta the random extra number of facets per partical (optional, default 0), each particle will have between facetNb and facetNb + delta facets
         * @param number the wanted number of particles : each particle is built with mesh_total_facets / number facets (optional)
         */
         SolidParticleSystem.prototype.digest = function (mesh, options) {
             var size = (options && options.facetNb) || 1;
             var number = (options && options.number);
-            var delta = (options && options.delta) || 0;
             var meshPos = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             var meshInd = mesh.getIndices();
             var meshUV = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
@@ -158,7 +156,6 @@ var BABYLON;
             if (number) {
                 number = (number > totalFacets) ? totalFacets : number;
                 size = Math.round(totalFacets / number);
-                delta = 0;
             }
             else {
                 size = (size > totalFacets) ? totalFacets : size;
@@ -168,10 +165,7 @@ var BABYLON;
             var facetUV = []; // submesh UV
             var facetCol = []; // submesh colors
             var barycenter = BABYLON.Tmp.Vector3[0];
-            var rand;
-            var sizeO = size;
             while (f < totalFacets) {
-                size = sizeO + Math.floor((1 + delta) * Math.random());
                 if (f > totalFacets - size) {
                     size = totalFacets - f;
                 }

+ 4 - 9
src/Particles/babylon.solidParticleSystem.ts

@@ -103,7 +103,7 @@ module BABYLON {
         private _minimum: Vector3 = Tmp.Vector3[0];
         private _maximum: Vector3 = Tmp.Vector3[1];
 
-
+        
         /**
         * Creates a SPS (Solid Particle System) object.
         * @param name the SPS name, this will be the underlying mesh name
@@ -175,13 +175,11 @@ module BABYLON {
         * Thus the particles generated from digest() have their property "positiion" yet set.
         * @param mesh the mesh to be digested
         * @param facetNb the number of mesh facets per particle (optional, default 1), this parameter is overriden by the parameter "number" if any
-        * @param delta the random extra number of facets per partical (optional, default 0), each particle will have between facetNb and facetNb + delta facets
         * @param number the wanted number of particles : each particle is built with mesh_total_facets / number facets (optional)
         */
-        public digest(mesh: Mesh, options?: { facetNb?: number; number?: number; delta?: number }): void {
+        public digest(mesh: Mesh, options?: { facetNb?: number; number?: number }): void {
             var size: number = (options && options.facetNb) || 1;
             var number: number = (options && options.number);
-            var delta: number = (options && options.delta) || 0;
             var meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
             var meshInd = mesh.getIndices();
             var meshUV = mesh.getVerticesData(VertexBuffer.UVKind);
@@ -193,7 +191,6 @@ module BABYLON {
             if (number) {
                 number = (number > totalFacets) ? totalFacets : number;
                 size = Math.round(totalFacets / number);
-                delta = 0;
             } else {
                 size = (size > totalFacets) ? totalFacets : size;
             }
@@ -203,11 +200,8 @@ module BABYLON {
             var facetUV: number[] = [];       // submesh UV
             var facetCol: number[] = [];      // submesh colors
             var barycenter: Vector3 = Tmp.Vector3[0];
-            var rand: number;
-            var sizeO: number = size;
 
             while (f < totalFacets) {
-                size = sizeO + Math.floor((1 + delta) * Math.random());
                 if (f > totalFacets - size) {
                     size = totalFacets - f;
                 }
@@ -913,4 +907,5 @@ module BABYLON {
         public afterUpdateParticles(start?: number, stop?: number, update?: boolean): void {
         }
     }
-}
+}
+

+ 10 - 0
src/Shaders/ShadersInclude/bonesDeclaration.fx

@@ -0,0 +1,10 @@
+#if NUM_BONE_INFLUENCERS > 0
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
+#endif

+ 29 - 0
src/Shaders/ShadersInclude/bonesVertex.fx

@@ -0,0 +1,29 @@
+#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

+ 8 - 0
src/Shaders/ShadersInclude/instancesDeclaration.fx

@@ -0,0 +1,8 @@
+#ifdef INSTANCES
+	attribute vec4 world0;
+	attribute vec4 world1;
+	attribute vec4 world2;
+	attribute vec4 world3;
+#else
+	uniform mat4 world;
+#endif

+ 5 - 0
src/Shaders/ShadersInclude/instancesVertex.fx

@@ -0,0 +1,5 @@
+#ifdef INSTANCES
+	mat4 finalWorld = mat4(world0, world1, world2, world3);
+#else
+	mat4 finalWorld = world;
+#endif

+ 5 - 54
src/Shaders/default.vertex.fx

@@ -15,27 +15,10 @@ attribute vec2 uv2;
 attribute vec4 color;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
-#endif
+#include<bonesDeclaration>
 
 // Uniforms
-
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+#include<instancesDeclaration>
 
 uniform mat4 view;
 uniform mat4 viewProjection;
@@ -142,41 +125,9 @@ void main(void) {
 	vPositionUVW = position;
 #endif 
 
-#ifdef INSTANCES
-	mat4 finalWorld = mat4(world0, world1, world2, world3);
-#else
-	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
+#include<instancesVertex>
+#include<bonesVertex>
+
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);

+ 4 - 53
src/Shaders/depth.vertex.fx

@@ -2,28 +2,10 @@
 
 // Attribute
 attribute vec3 position;
-#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
+#include<bonesDeclaration>
 
 // Uniform
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+#include<instancesDeclaration>
 
 uniform mat4 viewProjection;
 
@@ -40,41 +22,10 @@ attribute vec2 uv2;
 
 void main(void)
 {
-#ifdef INSTANCES
-	mat4 finalWorld = mat4(world0, world1, world2, world3);
-#else
-	mat4 finalWorld = world;
-#endif
-
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+#include<instancesVertex>
 
-	#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	
+#include<bonesVertex>
 
-	finalWorld = finalWorld * influence;
-#endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 #if defined(ALPHATEST) || defined(BASIC_RENDER)

+ 4 - 52
src/Shaders/outline.vertex.fx

@@ -4,28 +4,12 @@
 attribute vec3 position;
 attribute vec3 normal;
 
-#if NUM_BONE_INFLUENCERS > 0
-uniform mat4 mBones[BonesPerMesh];
-
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#if NUM_BONE_INFLUENCERS > 4
-attribute vec4 matricesIndicesExtra;
-attribute vec4 matricesWeightsExtra;
-#endif
-#endif
+#include<bonesDeclaration>
 
 // Uniform
 uniform float offset;
 
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+#include<instancesDeclaration>
 
 uniform mat4 viewProjection;
 
@@ -44,41 +28,9 @@ void main(void)
 {
 	vec3 offsetPosition = position + normal * offset;
 
-#ifdef INSTANCES
-	mat4 finalWorld = mat4(world0, world1, world2, world3);
-#else
-	mat4 finalWorld = world;
-#endif
+#include<instancesVertex>
+#include<bonesVertex>
 
-#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(offsetPosition, 1.0);
 
 #ifdef ALPHATEST

+ 5 - 55
src/Shaders/shadowMap.vertex.fx

@@ -2,28 +2,11 @@
 
 // Attribute
 attribute vec3 position;
-#if NUM_BONE_INFLUENCERS > 0
 
-// having bone influencers implies you have bones
-uniform mat4 mBones[BonesPerMesh];
+#include<bonesDeclaration>
 
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#if NUM_BONE_INFLUENCERS > 4
-attribute vec4 matricesIndicesExtra;
-attribute vec4 matricesWeightsExtra;
-#endif
-#endif
-
-// Uniform
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+// Uniforms
+#include<instancesDeclaration>
 
 uniform mat4 viewProjection;
 
@@ -42,41 +25,8 @@ attribute vec2 uv2;
 
 void main(void)
 {
-#ifdef INSTANCES
-	mat4 finalWorld = mat4(world0, world1, world2, world3);
-#else
-	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
+#include<instancesVertex>
+#include<bonesVertex>
 
 #ifdef CUBEMAP
 	vPosition = finalWorld * vec4(position, 1.0);

+ 1 - 1
src/Tools/babylon.tools.js

@@ -496,7 +496,7 @@ var BABYLON;
                     var a = window.document.createElement("a");
                     a.href = base64Image;
                     var date = new Date();
-                    var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(-2) + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
+                    var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
                     a.setAttribute("download", "screenshot_" + stringDate + ".png");
                     window.document.body.appendChild(a);
                     a.addEventListener("click", function () {

+ 1 - 2
src/Tools/babylon.tools.ts

@@ -592,7 +592,7 @@
                     var a = window.document.createElement("a");
                     a.href = base64Image;
                     var date = new Date();
-                    var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(-2) + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
+                    var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
                     a.setAttribute("download", "screenshot_" + stringDate + ".png");
 
                     window.document.body.appendChild(a);
@@ -1013,4 +1013,3 @@
 } 
 
 
-