Przeglądaj źródła

Merge remote-tracking branch 'upstream/master' into ColorGrading

= 9 lat temu
rodzic
commit
a9c26b9adb
100 zmienionych plików z 3240 dodań i 6709 usunięć
  1. 24 25
      dist/preview release/babylon.core.js
  2. 1731 1644
      dist/preview release/babylon.d.ts
  3. 33 33
      dist/preview release/babylon.js
  4. 676 486
      dist/preview release/babylon.max.js
  5. 33 33
      dist/preview release/babylon.noworker.js
  6. 84 200
      materialsLibrary/dist/babylon.furMaterial.js
  7. 1 1
      materialsLibrary/dist/babylon.furMaterial.min.js
  8. 3 5
      materialsLibrary/dist/babylon.simpleMaterial.js
  9. 1 1
      materialsLibrary/dist/babylon.simpleMaterial.min.js
  10. 41 217
      materialsLibrary/dist/babylon.terrainMaterial.js
  11. 1 1
      materialsLibrary/dist/babylon.terrainMaterial.min.js
  12. 28 204
      materialsLibrary/dist/babylon.triPlanarMaterial.js
  13. 1 1
      materialsLibrary/dist/babylon.triPlanarMaterial.min.js
  14. 39 204
      materialsLibrary/dist/babylon.waterMaterial.js
  15. 1 1
      materialsLibrary/dist/babylon.waterMaterial.min.js
  16. 3 1
      materialsLibrary/dist/dts/babylon.furMaterial.d.ts
  17. 1 2
      materialsLibrary/dist/dts/babylon.terrainMaterial.d.ts
  18. 1 2
      materialsLibrary/dist/dts/babylon.triPlanarMaterial.d.ts
  19. 3 2
      materialsLibrary/dist/dts/babylon.waterMaterial.d.ts
  20. 100 226
      materialsLibrary/materials/fur/babylon.furMaterial.ts
  21. 11 479
      materialsLibrary/materials/fur/fur.fragment.fx
  22. 10 83
      materialsLibrary/materials/fur/fur.vertex.fx
  23. 8 10
      materialsLibrary/materials/simple/babylon.simpleMaterial.ts
  24. 48 248
      materialsLibrary/materials/terrain/babylon.terrainMaterial.ts
  25. 10 542
      materialsLibrary/materials/terrain/terrain.fragment.fx
  26. 12 83
      materialsLibrary/materials/terrain/terrain.vertex.fx
  27. 33 232
      materialsLibrary/materials/triPlanar/babylon.triPlanarMaterial.ts
  28. 14 555
      materialsLibrary/materials/triPlanar/triplanar.fragment.fx
  29. 14 84
      materialsLibrary/materials/triPlanar/triplanar.vertex.fx
  30. 48 240
      materialsLibrary/materials/water/babylon.waterMaterial.ts
  31. 15 561
      materialsLibrary/materials/water/water.fragment.fx
  32. 13 85
      materialsLibrary/materials/water/water.vertex.fx
  33. 1 1
      src/Actions/babylon.action.js
  34. 2 2
      src/Actions/babylon.actionManager.js
  35. 4 4
      src/Actions/babylon.condition.js
  36. 12 12
      src/Actions/babylon.directActions.js
  37. 1 1
      src/Actions/babylon.interpolateValueAction.js
  38. 1 1
      src/Animations/babylon.animatable.js
  39. 4 4
      src/Animations/babylon.animation.js
  40. 13 13
      src/Animations/babylon.easing.js
  41. 1 1
      src/Audio/babylon.analyser.js
  42. 1 1
      src/Audio/babylon.audioEngine.js
  43. 1 1
      src/Audio/babylon.sound.js
  44. 1 1
      src/Audio/babylon.soundtrack.js
  45. 1 1
      src/Bones/babylon.bone.js
  46. 1 1
      src/Bones/babylon.skeleton.js
  47. 1 1
      src/Cameras/Inputs/babylon.arcrotatecamera.input.gamepad.js
  48. 1 1
      src/Cameras/Inputs/babylon.arcrotatecamera.input.keyboard.js
  49. 1 1
      src/Cameras/Inputs/babylon.arcrotatecamera.input.mousewheel.js
  50. 1 1
      src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.js
  51. 1 1
      src/Cameras/Inputs/babylon.arcrotatecamera.input.vrdeviceorientation.js
  52. 1 1
      src/Cameras/Inputs/babylon.freecamera.input.deviceorientation.js
  53. 1 1
      src/Cameras/Inputs/babylon.freecamera.input.gamepad.js
  54. 1 1
      src/Cameras/Inputs/babylon.freecamera.input.keyboard.js
  55. 1 1
      src/Cameras/Inputs/babylon.freecamera.input.mouse.js
  56. 1 1
      src/Cameras/Inputs/babylon.freecamera.input.touch.js
  57. 1 1
      src/Cameras/Inputs/babylon.freecamera.input.virtualjoystick.js
  58. 1 1
      src/Cameras/Inputs/babylon.freecamera.input.vrdeviceorientation.js
  59. 1 1
      src/Cameras/VR/babylon.vrCameraMetrics.js
  60. 2 2
      src/Cameras/VR/babylon.vrDeviceOrientationCamera.js
  61. 1 1
      src/Cameras/VR/babylon.webVRCamera.js
  62. 18 12
      src/Cameras/babylon.arcRotateCamera.js
  63. 1 1
      src/Cameras/babylon.arcRotateCameraInputsManager.js
  64. 58 82
      src/Cameras/babylon.camera.js
  65. 1 1
      src/Cameras/babylon.cameraInputsManager.js
  66. 1 1
      src/Cameras/babylon.deviceOrientationCamera.js
  67. 2 2
      src/Cameras/babylon.followCamera.js
  68. 1 1
      src/Cameras/babylon.freeCamera.js
  69. 1 1
      src/Cameras/babylon.freeCameraInputsManager.js
  70. 1 1
      src/Cameras/babylon.gamepadCamera.js
  71. 8 8
      src/Cameras/babylon.stereoscopicCameras.js
  72. 16 17
      src/Cameras/babylon.targetCamera.js
  73. 1 1
      src/Cameras/babylon.touchCamera.js
  74. 1 1
      src/Cameras/babylon.universalCamera.js
  75. 1 1
      src/Cameras/babylon.virtualJoysticksCamera.js
  76. 1 1
      src/Collisions/babylon.collider.js
  77. 2 2
      src/Collisions/babylon.collisionCoordinator.js
  78. 3 3
      src/Collisions/babylon.collisionWorker.js
  79. 2 2
      src/Collisions/babylon.pickingInfo.js
  80. 1 1
      src/Culling/Octrees/babylon.octree.js
  81. 1 1
      src/Culling/Octrees/babylon.octreeBlock.js
  82. 1 1
      src/Culling/babylon.boundingBox.js
  83. 1 1
      src/Culling/babylon.boundingInfo.js
  84. 1 1
      src/Culling/babylon.boundingSphere.js
  85. 1 1
      src/Culling/babylon.ray.js
  86. 1 1
      src/Debug/babylon.debugLayer.js
  87. 1 1
      src/Debug/babylon.skeletonViewer.js
  88. 1 1
      src/Layer/babylon.layer.js
  89. 1 1
      src/LensFlare/babylon.lensFlare.js
  90. 1 1
      src/LensFlare/babylon.lensFlareSystem.js
  91. 1 1
      src/Lights/Shadows/babylon.shadowGenerator.js
  92. 1 1
      src/Lights/babylon.directionalLight.js
  93. 1 1
      src/Lights/babylon.hemisphericLight.js
  94. 1 1
      src/Lights/babylon.light.js
  95. 1 1
      src/Lights/babylon.pointLight.js
  96. 1 1
      src/Lights/babylon.spotLight.js
  97. 1 1
      src/Loading/babylon.sceneLoader.js
  98. 1 1
      src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js
  99. 1 1
      src/Materials/Textures/Procedurals/babylon.proceduralTexture.js
  100. 0 0
      src/Materials/Textures/babylon.baseTexture.js

Plik diff jest za duży
+ 24 - 25
dist/preview release/babylon.core.js


Plik diff jest za duży
+ 1731 - 1644
dist/preview release/babylon.d.ts


Plik diff jest za duży
+ 33 - 33
dist/preview release/babylon.js


Plik diff jest za duży
+ 676 - 486
dist/preview release/babylon.max.js


Plik diff jest za duży
+ 33 - 33
dist/preview release/babylon.noworker.js


Plik diff jest za duży
+ 84 - 200
materialsLibrary/dist/babylon.furMaterial.js


Plik diff jest za duży
+ 1 - 1
materialsLibrary/dist/babylon.furMaterial.min.js


+ 3 - 5
materialsLibrary/dist/babylon.simpleMaterial.js

@@ -112,7 +112,6 @@ var BABYLON;
             if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
                 this._defines.FOG = true;
             }
-            var lightIndex = 0;
             if (scene.lightsEnabled && !this.disableLighting) {
                 needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
             }
@@ -181,10 +180,9 @@ var BABYLON;
                     "mBones",
                     "vClipPlane", "diffuseMatrix", "depthValues"
                 ];
-                BABYLON.MaterialHelper.PrepareUniformsListForList(uniforms, this._defines, this.maxSimultaneousLights);
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, ["diffuseSampler",
-                    "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
-                ], join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                var samplers = ["diffuseSampler"];
+                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
             }
             if (!this._effect.isReady()) {
                 return false;

Plik diff jest za duży
+ 1 - 1
materialsLibrary/dist/babylon.simpleMaterial.min.js


Plik diff jest za duży
+ 41 - 217
materialsLibrary/dist/babylon.terrainMaterial.js


Plik diff jest za duży
+ 1 - 1
materialsLibrary/dist/babylon.terrainMaterial.min.js


Plik diff jest za duży
+ 28 - 204
materialsLibrary/dist/babylon.triPlanarMaterial.js


Plik diff jest za duży
+ 1 - 1
materialsLibrary/dist/babylon.triPlanarMaterial.min.js


Plik diff jest za duży
+ 39 - 204
materialsLibrary/dist/babylon.waterMaterial.js


Plik diff jest za duży
+ 1 - 1
materialsLibrary/dist/babylon.waterMaterial.min.js


+ 3 - 1
materialsLibrary/dist/dts/babylon.furMaterial.d.ts

@@ -15,8 +15,9 @@ declare module BABYLON {
         furTexture: DynamicTexture;
         disableLighting: boolean;
         highLevelFur: boolean;
+        maxSimultaneousLights: number;
+        _meshes: AbstractMesh[];
         private _worldViewProjectionMatrix;
-        private _scaledDiffuse;
         private _renderId;
         private _furTime;
         private _defines;
@@ -26,6 +27,7 @@ declare module BABYLON {
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
+        updateFur(): void;
         private _checkCache(scene, mesh?, useInstances?);
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         bindOnlyWorldMatrix(world: Matrix): void;

+ 1 - 2
materialsLibrary/dist/dts/babylon.terrainMaterial.d.ts

@@ -12,9 +12,8 @@ declare module BABYLON {
         specularColor: Color3;
         specularPower: number;
         disableLighting: boolean;
+        maxSimultaneousLights: number;
         private _worldViewProjectionMatrix;
-        private _scaledDiffuse;
-        private _scaledSpecular;
         private _renderId;
         private _defines;
         private _cachedDefines;

+ 1 - 2
materialsLibrary/dist/dts/babylon.triPlanarMaterial.d.ts

@@ -13,9 +13,8 @@ declare module BABYLON {
         specularColor: Color3;
         specularPower: number;
         disableLighting: boolean;
+        maxSimultaneousLights: number;
         private _worldViewProjectionMatrix;
-        private _scaledDiffuse;
-        private _scaledSpecular;
         private _renderId;
         private _defines;
         private _cachedDefines;

+ 3 - 2
materialsLibrary/dist/dts/babylon.waterMaterial.d.ts

@@ -8,6 +8,7 @@ declare module BABYLON {
         specularColor: Color3;
         specularPower: number;
         disableLighting: boolean;
+        maxSimultaneousLights: number;
         /**
         * @param {number}: Represents the wind force
         */
@@ -46,8 +47,6 @@ declare module BABYLON {
         private _material;
         private _reflectionTransform;
         private _lastTime;
-        private _scaledDiffuse;
-        private _scaledSpecular;
         private _renderId;
         private _defines;
         private _cachedDefines;
@@ -59,6 +58,8 @@ declare module BABYLON {
         reflectionTexture: RenderTargetTexture;
         addToRenderList(node: any): void;
         enableRenderTargets(enable: boolean): void;
+        getRenderList(): AbstractMesh[];
+        renderTargetsEnabled: boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;

+ 100 - 226
materialsLibrary/materials/fur/babylon.furMaterial.ts

@@ -10,60 +10,31 @@ module BABYLON {
         public ALPHATEST = false;
         public POINTSIZE = false;
         public FOG = false;
-        public LIGHT0 = false;
-        public LIGHT1 = false;
-        public LIGHT2 = false;
-        public LIGHT3 = false;
-        public SPOTLIGHT0 = false;
-        public SPOTLIGHT1 = false;
-        public SPOTLIGHT2 = false;
-        public SPOTLIGHT3 = false;
-        public HEMILIGHT0 = false;
-        public HEMILIGHT1 = false;
-        public HEMILIGHT2 = false;
-        public HEMILIGHT3 = false;
-        public DIRLIGHT0 = false;
-        public DIRLIGHT1 = false;
-        public DIRLIGHT2 = false;
-        public DIRLIGHT3 = false;
-        public POINTLIGHT0 = false;
-        public POINTLIGHT1 = false;
-        public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;        
-        public SHADOW0 = false;
-        public SHADOW1 = false;
-        public SHADOW2 = false;
-        public SHADOW3 = false;
-        public SHADOWS = false;
-        public SHADOWVSM0 = false;
-        public SHADOWVSM1 = false;
-        public SHADOWVSM2 = false;
-        public SHADOWVSM3 = false;
-        public SHADOWPCF0 = false;
-        public SHADOWPCF1 = false;
-        public SHADOWPCF2 = false;
-        public SHADOWPCF3 = false;
         public NORMAL = false;
         public UV1 = false;
         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 HIGHLEVEL = false;
 
         constructor() {
             super();
-            this._keys = Object.keys(this);
+            this.rebuild();
         }
     }
 
     export class FurMaterial extends Material {
         
+        @serializeAsTexture()
         public diffuseTexture: BaseTexture;
+        
+        @serializeAsTexture()
         public heightTexture: BaseTexture;
+        
+        @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         
         @serialize()
@@ -90,7 +61,6 @@ module BABYLON {
         @serialize()
         public furDensity: number = 20;
         
-        @serializeAsTexture()
         public furTexture: DynamicTexture;
         
         @serialize()
@@ -98,9 +68,13 @@ module BABYLON {
         
         @serialize()
         public highLevelFur: boolean = true;
+        
+        @serialize()
+        public maxSimultaneousLights = 4;
+        
+        public _meshes: AbstractMesh[];
 
         private _worldViewProjectionMatrix = Matrix.Zero();
-        private _scaledDiffuse = new Color3(1.,1.,1.);
         private _renderId: number;
         
         private _furTime: number = 0;
@@ -134,6 +108,24 @@ module BABYLON {
         public getAlphaTestTexture(): BaseTexture {
             return null;
         }
+        
+        public updateFur(): void {
+            for (var i = 1; i < this._meshes.length; i++) {
+                var offsetFur = <FurMaterial>this._meshes[i].material;
+                
+                offsetFur.furLength = this.furLength;
+                offsetFur.furAngle = this.furAngle;
+                offsetFur.furGravity = this.furGravity;
+                offsetFur.furSpacing = this.furSpacing;
+                offsetFur.furSpeed = this.furSpeed;
+                offsetFur.furColor = this.furColor;
+                offsetFur.diffuseTexture = this.diffuseTexture;
+                offsetFur.furTexture = this.furTexture;
+                offsetFur.highLevelFur = this.highLevelFur;
+                offsetFur.furTime = this.furTime;
+                offsetFur.furDensity = this.furDensity;
+            }
+        }
 
         // Methods   
         private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
@@ -219,82 +211,9 @@ module BABYLON {
                 this._defines.HIGHLEVEL = true;
             }
 
-            var lightIndex = 0;
+            // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    // Excluded check
-                    if (light._excludedMeshesIds.length > 0) {
-                        for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
-                            var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
-
-                            if (excludedMesh) {
-                                light.excludedMeshes.push(excludedMesh);
-                            }
-                        }
-
-                        light._excludedMeshesIds = [];
-                    }
-
-                    // Included check
-                    if (light._includedOnlyMeshesIds.length > 0) {
-                        for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
-                            var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
-
-                            if (includedOnlyMesh) {
-                                light.includedOnlyMeshes.push(includedOnlyMesh);
-                            }
-                        }
-
-                        light._includedOnlyMeshesIds = [];
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-                    needNormals = true;
-                    this._defines["LIGHT" + lightIndex] = true;
-
-                    var type;
-                    if (light instanceof SpotLight) {
-                        type = "SPOTLIGHT" + lightIndex;
-                    } else if (light instanceof HemisphericLight) {
-                        type = "HEMILIGHT" + lightIndex;
-                    } else if (light instanceof PointLight) {
-                        type = "POINTLIGHT" + lightIndex;
-                    } else {
-                        type = "DIRLIGHT" + lightIndex;
-                    }
-
-                    this._defines[type] = true;
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh && mesh.receiveShadows && shadowGenerator) {
-                            this._defines["SHADOW" + lightIndex] = true;
-
-                            this._defines.SHADOWS = true;
-
-                            if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
-                                this._defines["SHADOWVSM" + lightIndex] = true;
-                            }
-
-                            if (shadowGenerator.usePoissonSampling) {
-                                this._defines["SHADOWPCF" + lightIndex] = true;
-                            }
-                        }
-                    }
-
-                    lightIndex++;
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
-                }
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
             }
 
             // Attribs
@@ -317,10 +236,10 @@ module BABYLON {
                         this._defines.VERTEXALPHA = true;
                     }
                 }
+                
                 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
@@ -341,30 +260,10 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
 
-                for (lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
-                    if (!this._defines["LIGHT" + lightIndex]) {
-                        continue;
-                    }
-
-                    if (lightIndex > 0) {
-                        fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOW" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOW" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWPCF" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWVSM" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
-                    }
-                }
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
              
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -386,40 +285,28 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
-                    attribs.push(VertexBuffer.MatricesIndicesKind);
-                    attribs.push(VertexBuffer.MatricesWeightsKind);
-                }
-
-                if (this._defines.INSTANCES) {
-                    attribs.push("world0");
-                    attribs.push("world1");
-                    attribs.push("world2");
-                    attribs.push("world3");
-                }
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
 
                 // Legacy browser patch
                 var shaderName = "fur";
                 var join = this._defines.toString();
+                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                    "vFogInfos", "vFogColor", "pointSize",
+                    "vDiffuseInfos", 
+                    "mBones",
+                    "vClipPlane", "diffuseMatrix",
+                    "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing", "furDensity"
+                ];
+                var samplers = ["diffuseSampler",
+                    "heightTexture", "furTexture"
+                ];
+                
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                
                 this._effect = scene.getEngine().createEffect(shaderName,
-                    attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                        "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
-                        "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
-                        "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
-                        "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
-                        "vFogInfos", "vFogColor", "pointSize",
-                        "vDiffuseInfos", 
-                        "mBones",
-                        "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
-                        "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing", "furDensity"
-                    ],
-                    ["diffuseSampler",
-                        "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3",
-                        "heightTexture", "furTexture"
-                    ],
-                    join, fallbacks, this.onCompiled, this.onError);
+                    attribs, uniforms, samplers,
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
             }
             if (!this._effect.isReady()) {
                 return false;
@@ -451,9 +338,7 @@ module BABYLON {
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
             // Bones
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
-            }
+            MaterialHelper.BindBonesParameters(mesh, this._effect);
 
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
@@ -469,10 +354,7 @@ module BABYLON {
                 }
                 
                 // Clip plane
-                if (scene.clipPlane) {
-                    var clipPlane = scene.clipPlane;
-                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
-                }
+                MaterialHelper.BindClipPlane(this._effect, scene);
 
                 // Point size
                 if (this.pointsCloud) {
@@ -482,53 +364,10 @@ module BABYLON {
                 this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
 
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                var lightIndex = 0;
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-
-                    if (light instanceof PointLight) {
-                        // Point Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof DirectionalLight) {
-                        // Directional Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof SpotLight) {
-                        // Spot Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
-                    } else if (light instanceof HemisphericLight) {
-                        // Hemispheric Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
-                    }
-
-                    light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
-                    this._effect.setColor4("vLightDiffuse" + lightIndex, this._scaledDiffuse, light.range);
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh.receiveShadows && shadowGenerator) {
-                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                            this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                            this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
-                        }
-                    }
-
-                    lightIndex++;
-
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
-                }
+                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
             }
 
             // View
@@ -537,10 +376,7 @@ module BABYLON {
             }
 
             // Fog
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                this._effect.setColor3("vFogColor", scene.fogColor);
-            }
+            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
             
             this._effect.setFloat("furLength", this.furLength);
             this._effect.setFloat("furAngle", this.furAngle);
@@ -579,6 +415,13 @@ module BABYLON {
             if (this.diffuseTexture) {
                 this.diffuseTexture.dispose();
             }
+            
+            if (this._meshes) {
+                for (var i = 1; i < this._meshes.length; i++) {
+                    this._meshes[i].material.dispose(forceDisposeEffect);
+                    this._meshes[i].dispose();
+                }
+            }
 
             super.dispose(forceDisposeEffect);
         }
@@ -590,12 +433,31 @@ module BABYLON {
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.FurMaterial";
+            
+            if (this._meshes) {
+                serializationObject.sourceMeshName = this._meshes[0].name;
+                serializationObject.quality = this._meshes.length;
+            }
+            
             return serializationObject;
         }
 
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial {
-            return SerializationHelper.Parse(() => new FurMaterial(source.name, scene), source, scene, rootUrl);
+            var material = SerializationHelper.Parse(() => new FurMaterial(source.name, scene), source, scene, rootUrl);
+            
+            if (source.sourceMeshName && material.highLevelFur) {
+                scene.executeWhenReady(() => {
+                    var sourceMesh = <Mesh>scene.getMeshByName(source.sourceMeshName);
+                    if (sourceMesh) {
+                        var furTexture = FurMaterial.GenerateTexture("Fur Texture", scene);
+                        material.furTexture = furTexture;
+                        FurMaterial.FurifyMesh(sourceMesh, source.quality);
+                    }
+                });
+            }
+            
+            return material;
         }
         
         public static GenerateTexture(name: string, scene: Scene): DynamicTexture {
@@ -621,13 +483,18 @@ module BABYLON {
         public static FurifyMesh(sourceMesh: Mesh, quality: number): Mesh[] {
             var meshes = [sourceMesh];
             var mat: FurMaterial = <FurMaterial>sourceMesh.material;
+            var i;
             
             if (!(mat instanceof FurMaterial)) {
                 throw "The material of the source mesh must be a Fur Material";
             }
             
-            for (var i = 1; i < quality; i++) {
+            for (i = 1; i < quality; i++) {
                 var offsetFur = new BABYLON.FurMaterial(mat.name + i, sourceMesh.getScene());
+                sourceMesh.getScene().materials.pop();
+                Tags.EnableFor(offsetFur);
+                Tags.AddTagsTo(offsetFur, "furShellMaterial");
+                
                 offsetFur.furLength = mat.furLength;
                 offsetFur.furAngle = mat.furAngle;
                 offsetFur.furGravity = mat.furGravity;
@@ -642,12 +509,19 @@ module BABYLON {
                 offsetFur.furDensity = mat.furDensity;
                 
                 var offsetMesh = sourceMesh.clone(sourceMesh.name + i);
+                
                 offsetMesh.material = offsetFur;
                 offsetMesh.skeleton = sourceMesh.skeleton;
-                offsetMesh.parent = sourceMesh;
+                offsetMesh.position = Vector3.Zero();
                 meshes.push(offsetMesh);
             }
             
+            for (i = 1; i < meshes.length; i++) {
+                meshes[i].parent = sourceMesh;
+            }
+            
+            (<FurMaterial>sourceMesh.material)._meshes = meshes;
+            
             return meshes;
         }
     }

+ 11 - 479
materialsLibrary/materials/fur/fur.fragment.fx

@@ -18,85 +18,7 @@ varying vec4 vColor;
 #endif
 
 // Lights
-#ifdef LIGHT0
-uniform vec4 vLightData0;
-uniform vec4 vLightDiffuse0;
-#ifdef SHADOW0
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-varying vec4 vPositionFromLight0;
-uniform sampler2D shadowSampler0;
-#else
-uniform samplerCube shadowSampler0;
-#endif
-uniform vec3 shadowsInfo0;
-#endif
-#ifdef SPOTLIGHT0
-uniform vec4 vLightDirection0;
-#endif
-#ifdef HEMILIGHT0
-uniform vec3 vLightGround0;
-#endif
-#endif
-
-#ifdef LIGHT1
-uniform vec4 vLightData1;
-uniform vec4 vLightDiffuse1;
-#ifdef SHADOW1
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-varying vec4 vPositionFromLight1;
-uniform sampler2D shadowSampler1;
-#else
-uniform samplerCube shadowSampler1;
-#endif
-uniform vec3 shadowsInfo1;
-#endif
-#ifdef SPOTLIGHT1
-uniform vec4 vLightDirection1;
-#endif
-#ifdef HEMILIGHT1
-uniform vec3 vLightGround1;
-#endif
-#endif
-
-#ifdef LIGHT2
-uniform vec4 vLightData2;
-uniform vec4 vLightDiffuse2;
-#ifdef SHADOW2
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-varying vec4 vPositionFromLight2;
-uniform sampler2D shadowSampler2;
-#else
-uniform samplerCube shadowSampler2;
-#endif
-uniform vec3 shadowsInfo2;
-#endif
-#ifdef SPOTLIGHT2
-uniform vec4 vLightDirection2;
-#endif
-#ifdef HEMILIGHT2
-uniform vec3 vLightGround2;
-#endif
-#endif
-
-#ifdef LIGHT3
-uniform vec4 vLightData3;
-uniform vec4 vLightDiffuse3;
-#ifdef SHADOW3
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-varying vec4 vPositionFromLight3;
-uniform sampler2D shadowSampler3;
-#else
-uniform samplerCube shadowSampler3;
-#endif
-uniform vec3 shadowsInfo3;
-#endif
-#ifdef SPOTLIGHT3
-uniform vec4 vLightDirection3;
-#endif
-#ifdef HEMILIGHT3
-uniform vec3 vLightGround3;
-#endif
-#endif
+#include<lightFragmentDeclaration>[0..maxSimultaneousLights]
 
 // Samplers
 #ifdef DIFFUSE
@@ -113,262 +35,10 @@ uniform sampler2D furTexture;
 varying vec2 vFurUV;
 #endif
 
-// Shadows
-#ifdef SHADOWS
-
-float unpack(vec4 color)
-{
-	const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-	return dot(color, bit_shift);
-}
-
-#if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
-float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-
-	depth = clamp(depth, 0., 1.);
-
-	directionToLight.y = 1.0 - directionToLight.y;
-
-	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
-
-	if (depth > shadow)
-	{
-		return darkness;
-	}
-	return 1.0;
-}
-
-float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float bias, float darkness)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-
-	depth = clamp(depth, 0., 1.);
-
-	directionToLight.y = 1.0 - directionToLight.y;
-
-	float visibility = 1.;
-
-	vec3 poissonDisk[4];
-	poissonDisk[0] = vec3(-0.094201624, 0.04, -0.039906216);
-	poissonDisk[1] = vec3(0.094558609, -0.04, -0.076890725);
-	poissonDisk[2] = vec3(-0.094184101, 0.01, -0.092938870);
-	poissonDisk[3] = vec3(0.034495938, -0.01, 0.029387760);
-
-	// Poisson Sampling
-	float biasedDepth = depth - bias;
-
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3])) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-#endif
-
-#if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
-float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
-
-	if (depth.z > shadow)
-	{
-		return darkness;
-	}
-	return 1.;
-}
-
-float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float visibility = 1.;
-
-	vec2 poissonDisk[4];
-	poissonDisk[0] = vec2(-0.94201624, -0.39906216);
-	poissonDisk[1] = vec2(0.94558609, -0.76890725);
-	poissonDisk[2] = vec2(-0.094184101, -0.92938870);
-	poissonDisk[3] = vec2(0.34495938, 0.29387760);
-
-	// Poisson Sampling
-	float biasedDepth = depth.z - bias;
-
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] / mapSize)) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-
-// Thanks to http://devmaster.net/
-float unpackHalf(vec2 color)
-{
-	return color.x + (color.y / 255.0);
-}
-
-float linstep(float low, float high, float v) {
-	return clamp((v - low) / (high - low), 0.0, 1.0);
-}
-
-float ChebychevInequality(vec2 moments, float compare, float bias)
-{
-	float p = smoothstep(compare - bias, compare, moments.x);
-	float variance = max(moments.y - moments.x * moments.x, 0.02);
-	float d = compare - moments.x;
-	float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
-
-	return clamp(max(p, p_max), 0.0, 1.0);
-}
-
-float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
-	{
-		return 1.0;
-	}
-
-	vec4 texel = texture2D(shadowSampler, uv);
-
-	vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-	return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
-}
-#endif
-#endif
-
-
-#ifdef CLIPPLANE
-varying float fClipDistance;
-#endif
-
-// Fog
-#ifdef FOG
-
-#define FOGMODE_NONE    0.
-#define FOGMODE_EXP     1.
-#define FOGMODE_EXP2    2.
-#define FOGMODE_LINEAR  3.
-#define E 2.71828
-
-uniform vec4 vFogInfos;
-uniform vec3 vFogColor;
-varying float fFogDistance;
-
-float CalcFogFactor()
-{
-	float fogCoeff = 1.0;
-	float fogStart = vFogInfos.y;
-	float fogEnd = vFogInfos.z;
-	float fogDensity = vFogInfos.w;
-
-	if (FOGMODE_LINEAR == vFogInfos.x)
-	{
-		fogCoeff = (fogEnd - fFogDistance) / (fogEnd - fogStart);
-	}
-	else if (FOGMODE_EXP == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fogDensity);
-	}
-	else if (FOGMODE_EXP2 == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fFogDistance * fogDensity * fogDensity);
-	}
-
-	return clamp(fogCoeff, 0.0, 1.0);
-}
-#endif
-
-// Light Computing
-struct lightingInfo
-{
-	vec3 diffuse;
-};
-
-lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, float range) {
-	lightingInfo result;
-
-	vec3 lightVectorW;
-	float attenuation = 1.0;
-	if (lightData.w == 0.)
-	{
-		vec3 direction = lightData.xyz - vPositionW;
-
-		attenuation = max(0., 1.0 - length(direction) / range);
-		lightVectorW = normalize(direction);
-	}
-	else
-	{
-		lightVectorW = normalize(-lightData.xyz);
-	}
-
-	// diffuse
-	float ndl = max(0., dot(vNormal, lightVectorW));
-	result.diffuse = ndl * diffuseColor * attenuation;
-
-	return result;
-}
-
-lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, float range) {
-	lightingInfo result;
-
-	vec3 direction = lightData.xyz - vPositionW;
-	vec3 lightVectorW = normalize(direction);
-	float attenuation = max(0., 1.0 - length(direction) / range);
-
-	// diffuse
-	float cosAngle = max(0., dot(-lightDirection.xyz, lightVectorW));
-	float spotAtten = 0.0;
-
-	if (cosAngle >= lightDirection.w)
-	{
-		cosAngle = max(0., pow(cosAngle, lightData.w));
-		spotAtten = clamp((cosAngle - lightDirection.w) / (1. - cosAngle), 0.0, 1.0);
-
-		// Diffuse
-		float ndl = max(0., dot(vNormal, -lightDirection.xyz));
-		result.diffuse = ndl * spotAtten * diffuseColor * attenuation;
-
-		return result;
-	}
-
-	result.diffuse = vec3(0.);
-
-	return result;
-}
-
-lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 groundColor) {
-	lightingInfo result;
-
-	// Diffuse
-	float ndl = dot(vNormal, lightData.xyz) * 0.5 + 0.5;
-	result.diffuse = mix(groundColor, diffuseColor, ndl);
-
-	return result;
-}
+#include<lightsFragmentFunctions>
+#include<shadowsFragmentFunctions>
+#include<fogFragmentDeclaration>
+#include<clipPlaneFragmentDeclaration>
 
 float Rand(vec3 rv) {
 	float x = dot(rv, vec3(12.9898,78.233, 24.65487));
@@ -377,11 +47,8 @@ float Rand(vec3 rv) {
 
 void main(void) {
 	// Clip plane
-#ifdef CLIPPLANE
-	if (fClipDistance > 0.0)
-		discard;
-#endif
-
+	#include<clipPlaneFragment>
+	
 	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
 
 	// Base color
@@ -428,143 +95,11 @@ void main(void) {
 
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
+    lightingInfo info;
 	float shadow = 1.;
+	float glossiness = 0.;
 
-#ifdef LIGHT0
-#ifdef SPOTLIGHT0
-	lightingInfo info = computeSpotLighting(viewDirectionW, normalW, vLightData0, vLightDirection0, vLightDiffuse0.rgb, vLightDiffuse0.a);
-#endif
-#ifdef HEMILIGHT0
-	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightGround0);
-#endif
-#if defined(POINTLIGHT0) || defined(DIRLIGHT0)
-	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightDiffuse0.a);
-#endif
-#ifdef SHADOW0
-#ifdef SHADOWVSM0
-	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
-#else
-#ifdef SHADOWPCF0
-	#if defined(POINTLIGHT0)
-	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
-	#else
-	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
-	#endif
-#else
-	#if defined(POINTLIGHT0)
-	shadow = computeShadowCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-	#else
-	shadow = computeShadow(vPositionFromLight0, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-	#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#endif
-
-#ifdef LIGHT1
-#ifdef SPOTLIGHT1
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightDiffuse1.a);
-#endif
-#ifdef HEMILIGHT1
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightGround1.a);
-#endif
-#if defined(POINTLIGHT1) || defined(DIRLIGHT1)
-	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightDiffuse1.a);
-#endif
-#ifdef SHADOW1
-#ifdef SHADOWVSM1
-	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
-#else
-#ifdef SHADOWPCF1
-#if defined(POINTLIGHT1)
-	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
-#endif
-#else
-	#if defined(POINTLIGHT1)
-	shadow = computeShadowCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-	#else
-	shadow = computeShadow(vPositionFromLight1, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-	#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#endif
-
-#ifdef LIGHT2
-#ifdef SPOTLIGHT2
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData2, vLightDirection2, vLightDiffuse2.rgb, vLightDiffuse2.a);
-#endif
-#ifdef HEMILIGHT2
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightGround2);
-#endif
-#if defined(POINTLIGHT2) || defined(DIRLIGHT2)
-	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightDiffuse2.a);
-#endif
-#ifdef SHADOW2
-#ifdef SHADOWVSM2
-	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
-#else
-#ifdef SHADOWPCF2
-#if defined(POINTLIGHT2)
-	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
-#endif
-#else
-	#if defined(POINTLIGHT2)
-	shadow = computeShadowCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-	#else
-	shadow = computeShadow(vPositionFromLight2, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-	#endif
-#endif	
-#endif	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#endif
-
-#ifdef LIGHT3
-#ifdef SPOTLIGHT3
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightDiffuse3.a);
-#endif
-#ifdef HEMILIGHT3
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightGround3);
-#endif
-#if defined(POINTLIGHT3) || defined(DIRLIGHT3)
-	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightDiffuse3.a);
-#endif
-#ifdef SHADOW3
-#ifdef SHADOWVSM3
-		shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
-#else
-#ifdef SHADOWPCF3
-#if defined(POINTLIGHT3)
-	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
-#endif
-#else
-	#if defined(POINTLIGHT3)
-	shadow = computeShadowCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-	#else
-	shadow = computeShadow(vPositionFromLight3, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-	#endif
-#endif	
-#endif	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#endif
+	#include<lightFragment>[0..maxSimultaneousLights]
 
 #ifdef VERTEXALPHA
 	alpha *= vColor.a;
@@ -580,10 +115,7 @@ void main(void) {
 	vec4 color = vec4(finalDiffuse * (0.5 + r), alpha);
 	#endif
 	
-#ifdef FOG
-	float fog = CalcFogFactor();
-	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
-#endif
+#include<fogFragment>
 
 	gl_FragColor = color;
 }

+ 10 - 83
materialsLibrary/materials/fur/fur.vertex.fx

@@ -13,11 +13,8 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#endif
 
+#include<bonesDeclaration>
 
 // Uniforms
 uniform float furLength;
@@ -37,14 +34,7 @@ uniform sampler2D heightTexture;
 varying vec2 vFurUV;
 #endif
 
-#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;
@@ -55,10 +45,6 @@ uniform mat4 diffuseMatrix;
 uniform vec2 vDiffuseInfos;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -74,33 +60,9 @@ varying float vfur_length;
 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
+#include<clipPlaneVertexDeclaration>
+#include<fogVertexDeclaration>
+#include<shadowsVertexDeclaration>
 
 float Rand(vec3 rv) {
 	float x = dot(rv, vec3(12.9898,78.233, 24.65487));
@@ -108,27 +70,9 @@ float Rand(vec3 rv) {
 }
 
 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
+	#include<instancesVertex>
+    #include<bonesVertex>
 
 //FUR
 float r = Rand(position);
@@ -208,30 +152,13 @@ float r = Rand(position);
 #endif
 
 	// Clip plane
-#ifdef CLIPPLANE
-	fClipDistance = dot(worldPos, vClipPlane);
-#endif
+	#include<clipPlaneVertex>
 
 	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
+	#include<fogVertex>
 
 	// 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
+	#include<shadowsVertex>
 
 	// Vertex color
 #ifdef VERTEXCOLOR

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

@@ -211,19 +211,17 @@ module BABYLON {
                 var shaderName = "simple";
                 var join = this._defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                        "vFogInfos", "vFogColor", "pointSize",
-                        "vDiffuseInfos", 
-                        "mBones",
-                        "vClipPlane", "diffuseMatrix", "depthValues"
-                    ];
+                                "vFogInfos", "vFogColor", "pointSize",
+                                "vDiffuseInfos", 
+                                "mBones",
+                                "vClipPlane", "diffuseMatrix", "depthValues"
+                ];
+                var samplers = ["diffuseSampler"];
                     
-                MaterialHelper.PrepareUniformsListForList(uniforms, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
                 
                 this._effect = scene.getEngine().createEffect(shaderName,
-                    attribs, uniforms,
-                    ["diffuseSampler",
-                        "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
-                    ],
+                    attribs, uniforms, samplers,
                     join, fallbacks, this.onCompiled, this.onError, {maxSimultaneousLights: this.maxSimultaneousLights});
             }
             if (!this._effect.isReady()) {

+ 48 - 248
materialsLibrary/materials/terrain/babylon.terrainMaterial.ts

@@ -10,53 +10,19 @@ module BABYLON {
         public ALPHATEST = false;
         public POINTSIZE = false;
         public FOG = false;
-        public LIGHT0 = false;
-        public LIGHT1 = false;
-        public LIGHT2 = false;
-        public LIGHT3 = false;
-        public SPOTLIGHT0 = false;
-        public SPOTLIGHT1 = false;
-        public SPOTLIGHT2 = false;
-        public SPOTLIGHT3 = false;
-        public HEMILIGHT0 = false;
-        public HEMILIGHT1 = false;
-        public HEMILIGHT2 = false;
-        public HEMILIGHT3 = false;
-        public DIRLIGHT0 = false;
-        public DIRLIGHT1 = false;
-        public DIRLIGHT2 = false;
-        public DIRLIGHT3 = false;
-        public POINTLIGHT0 = false;
-        public POINTLIGHT1 = false;
-        public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;        
-        public SHADOW0 = false;
-        public SHADOW1 = false;
-        public SHADOW2 = false;
-        public SHADOW3 = false;
-        public SHADOWS = false;
-        public SHADOWVSM0 = false;
-        public SHADOWVSM1 = false;
-        public SHADOWVSM2 = false;
-        public SHADOWVSM3 = false;
-        public SHADOWPCF0 = false;
-        public SHADOWPCF1 = false;
-        public SHADOWPCF2 = false;
-        public SHADOWPCF3 = false;
         public SPECULARTERM = false;
         public NORMAL = false;
         public UV1 = false;
         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;
 
         constructor() {
             super();
-            this._keys = Object.keys(this);
+            this.rebuild();
         }
     }
 
@@ -93,10 +59,11 @@ module BABYLON {
         
         @serialize()
         public disableLighting = false;
+        
+        @serialize()
+        public maxSimultaneousLights = 4;
 
         private _worldViewProjectionMatrix = Matrix.Zero();
-        private _scaledDiffuse = new Color3();
-        private _scaledSpecular = new Color3();
         private _renderId: number;
 
         private _defines = new TerrainMaterialDefines();
@@ -160,23 +127,6 @@ module BABYLON {
 
             this._defines.reset();
 
-            // Textures
-            if (scene.texturesEnabled) {
-                if (this.mixTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.mixTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
-                    }
-                }
-                if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && StandardMaterial.BumpTextureEnabled) {
-                    needUVs = true;
-                    needNormals = true;
-                    this._defines.BUMP = true;
-                }
-            }
-
             // Effect
             if (scene.clipPlane) {
                 this._defines.CLIPPLANE = true;
@@ -196,86 +146,25 @@ module BABYLON {
                 this._defines.FOG = true;
             }
 
-            var lightIndex = 0;
+            // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    // Excluded check
-                    if (light._excludedMeshesIds.length > 0) {
-                        for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
-                            var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
-
-                            if (excludedMesh) {
-                                light.excludedMeshes.push(excludedMesh);
-                            }
-                        }
-
-                        light._excludedMeshesIds = [];
-                    }
-
-                    // Included check
-                    if (light._includedOnlyMeshesIds.length > 0) {
-                        for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
-                            var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
-
-                            if (includedOnlyMesh) {
-                                light.includedOnlyMeshes.push(includedOnlyMesh);
-                            }
-                        }
-
-                        light._includedOnlyMeshesIds = [];
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-                    needNormals = true;
-                    this._defines["LIGHT" + lightIndex] = true;
-
-                    var type;
-                    if (light instanceof SpotLight) {
-                        type = "SPOTLIGHT" + lightIndex;
-                    } else if (light instanceof HemisphericLight) {
-                        type = "HEMILIGHT" + lightIndex;
-                    } else if (light instanceof PointLight) {
-                        type = "POINTLIGHT" + lightIndex;
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
+            }
+            
+            // Textures
+            if (scene.texturesEnabled) {
+                if (this.mixTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this.mixTexture.isReady()) {
+                        return false;
                     } else {
-                        type = "DIRLIGHT" + lightIndex;
-                    }
-
-                    this._defines[type] = true;
-                    
-                    // Specular
-                    if (!light.specular.equalsFloats(0, 0, 0)) {
-                        this._defines.SPECULARTERM = true;
-                    }
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh && mesh.receiveShadows && shadowGenerator) {
-                            this._defines["SHADOW" + lightIndex] = true;
-
-                            this._defines.SHADOWS = true;
-
-                            if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
-                                this._defines["SHADOWVSM" + lightIndex] = true;
-                            }
-
-                            if (shadowGenerator.usePoissonSampling) {
-                                this._defines["SHADOWPCF" + lightIndex] = true;
-                            }
-                        }
+                        needUVs = true;
+                        this._defines.DIFFUSE = true;
                     }
-
-                    lightIndex++;
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
+                }
+                if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && StandardMaterial.BumpTextureEnabled) {
+                    needUVs = true;
+                    needNormals = true;
+                    this._defines.BUMP = true;
                 }
             }
 
@@ -300,9 +189,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
@@ -323,30 +211,10 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
 
-                for (lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
-                    if (!this._defines["LIGHT" + lightIndex]) {
-                        continue;
-                    }
-
-                    if (lightIndex > 0) {
-                        fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOW" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOW" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWPCF" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWVSM" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
-                    }
-                }
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
              
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -368,41 +236,29 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
-                    attribs.push(VertexBuffer.MatricesIndicesKind);
-                    attribs.push(VertexBuffer.MatricesWeightsKind);
-                }
-
-                if (this._defines.INSTANCES) {
-                    attribs.push("world0");
-                    attribs.push("world1");
-                    attribs.push("world2");
-                    attribs.push("world3");
-                }
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
 
                 // Legacy browser patch
                 var shaderName = "terrain";
                 var join = this._defines.toString();
+                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                    "vFogInfos", "vFogColor", "pointSize",
+                    "vTextureInfos", 
+                    "mBones",
+                    "vClipPlane", "textureMatrix",
+                    
+                    "diffuse1Infos", "diffuse2Infos", "diffuse3Infos"
+                ];
+                var samplers = ["textureSampler", "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler",
+                    "bump1Sampler", "bump2Sampler", "bump3Sampler"
+                ];
+                
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                
                 this._effect = scene.getEngine().createEffect(shaderName,
-                    attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
-                        "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
-                        "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
-                        "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
-                        "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
-                        "vFogInfos", "vFogColor", "pointSize",
-                        "vTextureInfos", 
-                        "mBones",
-                        "vClipPlane", "textureMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
-                        
-                        "diffuse1Infos", "diffuse2Infos", "diffuse3Infos"
-                    ],
-                    ["textureSampler", "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler",
-                        "bump1Sampler", "bump2Sampler", "bump3Sampler",
-                        "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
-                    ],
-                    join, fallbacks, this.onCompiled, this.onError);
+                    attribs, uniforms, samplers,
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
             }
             if (!this._effect.isReady()) {
                 return false;
@@ -434,9 +290,7 @@ module BABYLON {
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
             // Bones
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
-            }
+            MaterialHelper.BindBonesParameters(mesh, this._effect);
 
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
@@ -473,10 +327,7 @@ module BABYLON {
                     }
                 }
                 // Clip plane
-                if (scene.clipPlane) {
-                    var clipPlane = scene.clipPlane;
-                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
-                }
+                MaterialHelper.BindClipPlane(this._effect, scene);
 
                 // Point size
                 if (this.pointsCloud) {
@@ -486,62 +337,14 @@ module BABYLON {
                 this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
 
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             
             if (this._defines.SPECULARTERM) {
                 this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                var lightIndex = 0;
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-
-                    if (light instanceof PointLight) {
-                        // Point Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof DirectionalLight) {
-                        // Directional Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof SpotLight) {
-                        // Spot Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
-                    } else if (light instanceof HemisphericLight) {
-                        // Hemispheric Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
-                    }
-
-                    light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
-                    this._effect.setColor4("vLightDiffuse" + lightIndex, this._scaledDiffuse, light.range);
-                    
-                    if (this._defines.SPECULARTERM) {
-                        light.specular.scaleToRef(light.intensity, this._scaledSpecular);
-                        this._effect.setColor3("vLightSpecular" + lightIndex, this._scaledSpecular);
-                    }
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh.receiveShadows && shadowGenerator) {
-                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                            this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                            this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
-                        }
-                    }
-
-                    lightIndex++;
-
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
-                }
+                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
             }
 
             // View
@@ -550,10 +353,7 @@ module BABYLON {
             }
 
             // Fog
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                this._effect.setColor3("vFogColor", scene.fogColor);
-            }
+            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
 
             super.bind(world, mesh);
         }

+ 10 - 542
materialsLibrary/materials/terrain/terrain.fragment.fx

@@ -20,97 +20,7 @@ varying vec4 vColor;
 #endif
 
 // Lights
-#ifdef LIGHT0
-uniform vec4 vLightData0;
-uniform vec4 vLightDiffuse0;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular0;
-#endif
-#ifdef SHADOW0
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-varying vec4 vPositionFromLight0;
-uniform sampler2D shadowSampler0;
-#else
-uniform samplerCube shadowSampler0;
-#endif
-uniform vec3 shadowsInfo0;
-#endif
-#ifdef SPOTLIGHT0
-uniform vec4 vLightDirection0;
-#endif
-#ifdef HEMILIGHT0
-uniform vec3 vLightGround0;
-#endif
-#endif
-
-#ifdef LIGHT1
-uniform vec4 vLightData1;
-uniform vec4 vLightDiffuse1;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular1;
-#endif
-#ifdef SHADOW1
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-varying vec4 vPositionFromLight1;
-uniform sampler2D shadowSampler1;
-#else
-uniform samplerCube shadowSampler1;
-#endif
-uniform vec3 shadowsInfo1;
-#endif
-#ifdef SPOTLIGHT1
-uniform vec4 vLightDirection1;
-#endif
-#ifdef HEMILIGHT1
-uniform vec3 vLightGround1;
-#endif
-#endif
-
-#ifdef LIGHT2
-uniform vec4 vLightData2;
-uniform vec4 vLightDiffuse2;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular2;
-#endif
-#ifdef SHADOW2
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-varying vec4 vPositionFromLight2;
-uniform sampler2D shadowSampler2;
-#else
-uniform samplerCube shadowSampler2;
-#endif
-uniform vec3 shadowsInfo2;
-#endif
-#ifdef SPOTLIGHT2
-uniform vec4 vLightDirection2;
-#endif
-#ifdef HEMILIGHT2
-uniform vec3 vLightGround2;
-#endif
-#endif
-
-#ifdef LIGHT3
-uniform vec4 vLightData3;
-uniform vec4 vLightDiffuse3;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular3;
-#endif
-#ifdef SHADOW3
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-varying vec4 vPositionFromLight3;
-uniform sampler2D shadowSampler3;
-#else
-uniform samplerCube shadowSampler3;
-#endif
-uniform vec3 shadowsInfo3;
-#endif
-#ifdef SPOTLIGHT3
-uniform vec4 vLightDirection3;
-#endif
-#ifdef HEMILIGHT3
-uniform vec3 vLightGround3;
-#endif
-#endif
+#include<lightFragmentDeclaration>[0..maxSimultaneousLights]
 
 // Samplers
 #ifdef DIFFUSE
@@ -135,195 +45,12 @@ uniform sampler2D bump3Sampler;
 #endif
 
 // Shadows
-#ifdef SHADOWS
-
-float unpack(vec4 color)
-{
-	const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-	return dot(color, bit_shift);
-}
-
-#if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
-float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-	depth = clamp(depth, 0., 1.0);
-
-	directionToLight = normalize(directionToLight);
-	directionToLight.y = - directionToLight.y;
-
-	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
-
-	if (depth > shadow)
-	{
-		return darkness;
-	}
-	return 1.0;
-}
-
-float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-
-	depth = clamp(depth, 0., 1.0);
-	float diskScale = 2.0 / mapSize;
-
-	directionToLight = normalize(directionToLight);
-	directionToLight.y = -directionToLight.y;
-
-	float visibility = 1.;
-
-	vec3 poissonDisk[4];
-	poissonDisk[0] = vec3(-1.0, 1.0, -1.0);
-	poissonDisk[1] = vec3(1.0, -1.0, -1.0);
-	poissonDisk[2] = vec3(-1.0, -1.0, -1.0);
-	poissonDisk[3] = vec3(1.0, -1.0, 1.0);
-
-	// Poisson Sampling
-	float biasedDepth = depth - bias;
-
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * diskScale)) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * diskScale)) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * diskScale)) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * diskScale)) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-#endif
-
-#if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
-float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
-
-	if (depth.z > shadow)
-	{
-		return darkness;
-	}
-	return 1.;
-}
-
-float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float visibility = 1.;
-
-	vec2 poissonDisk[4];
-	poissonDisk[0] = vec2(-0.94201624, -0.39906216);
-	poissonDisk[1] = vec2(0.94558609, -0.76890725);
-	poissonDisk[2] = vec2(-0.094184101, -0.92938870);
-	poissonDisk[3] = vec2(0.34495938, 0.29387760);
-
-	// Poisson Sampling
-	float biasedDepth = depth.z - bias;
-
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] / mapSize)) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-
-// Thanks to http://devmaster.net/
-float unpackHalf(vec2 color)
-{
-	return color.x + (color.y / 255.0);
-}
-
-float linstep(float low, float high, float v) {
-	return clamp((v - low) / (high - low), 0.0, 1.0);
-}
-
-float ChebychevInequality(vec2 moments, float compare, float bias)
-{
-	float p = smoothstep(compare - bias, compare, moments.x);
-	float variance = max(moments.y - moments.x * moments.x, 0.02);
-	float d = compare - moments.x;
-	float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
-
-	return clamp(max(p, p_max), 0.0, 1.0);
-}
-
-float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
-	{
-		return 1.0;
-	}
-
-	vec4 texel = texture2D(shadowSampler, uv);
-
-	vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-	return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
-}
-#endif
-#endif
-
-
-#ifdef CLIPPLANE
-varying float fClipDistance;
-#endif
+#include<lightsFragmentFunctions>
+#include<shadowsFragmentFunctions>
+#include<clipPlaneFragmentDeclaration>
 
 // Fog
-#ifdef FOG
-
-#define FOGMODE_NONE    0.
-#define FOGMODE_EXP     1.
-#define FOGMODE_EXP2    2.
-#define FOGMODE_LINEAR  3.
-#define E 2.71828
-
-uniform vec4 vFogInfos;
-uniform vec3 vFogColor;
-varying float fFogDistance;
-
-float CalcFogFactor()
-{
-	float fogCoeff = 1.0;
-	float fogStart = vFogInfos.y;
-	float fogEnd = vFogInfos.z;
-	float fogDensity = vFogInfos.w;
-
-	if (FOGMODE_LINEAR == vFogInfos.x)
-	{
-		fogCoeff = (fogEnd - fFogDistance) / (fogEnd - fogStart);
-	}
-	else if (FOGMODE_EXP == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fogDensity);
-	}
-	else if (FOGMODE_EXP2 == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fFogDistance * fogDensity * fogDensity);
-	}
-
-	return clamp(fogCoeff, 0.0, 1.0);
-}
-#endif
+#include<fogFragmentDeclaration>
 
 // Bump
 #ifdef BUMP
@@ -364,105 +91,6 @@ vec3 perturbNormal(vec3 viewDir, vec3 mixColor)
 }
 #endif
 
-// Light Computing
-struct lightingInfo
-{
-	vec3 diffuse;
-#ifdef SPECULARTERM
-	vec3 specular;
-#endif
-};
-
-lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float range, float glossiness) {
-	lightingInfo result;
-
-	vec3 lightVectorW;
-	float attenuation = 1.0;
-	if (lightData.w == 0.)
-	{
-		vec3 direction = lightData.xyz - vPositionW;
-
-		attenuation = max(0., 1.0 - length(direction) / range);
-		lightVectorW = normalize(direction);
-	}
-	else
-	{
-		lightVectorW = normalize(-lightData.xyz);
-	}
-
-	// diffuse
-	float ndl = max(0., dot(vNormal, lightVectorW));
-	result.diffuse = ndl * diffuseColor * attenuation;
-
-#ifdef SPECULARTERM
-	// Specular
-	vec3 angleW = normalize(viewDirectionW + lightVectorW);
-	float specComp = max(0., dot(vNormal, angleW));
-	specComp = pow(specComp, max(1., glossiness));
-
-	result.specular = specComp * specularColor * attenuation;
-#endif
-	return result;
-}
-
-lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, vec3 specularColor, float range, float glossiness) {
-	lightingInfo result;
-
-	vec3 direction = lightData.xyz - vPositionW;
-	vec3 lightVectorW = normalize(direction);
-	float attenuation = max(0., 1.0 - length(direction) / range);
-
-	// diffuse
-	float cosAngle = max(0., dot(-lightDirection.xyz, lightVectorW));
-	float spotAtten = 0.0;
-
-	if (cosAngle >= lightDirection.w)
-	{
-		cosAngle = max(0., pow(cosAngle, lightData.w));
-		spotAtten = clamp((cosAngle - lightDirection.w) / (1. - cosAngle), 0.0, 1.0);
-
-		// Diffuse
-		float ndl = max(0., dot(vNormal, -lightDirection.xyz));
-		result.diffuse = ndl * spotAtten * diffuseColor * attenuation;
-
-#ifdef SPECULARTERM
-		// Specular
-		vec3 angleW = normalize(viewDirectionW - lightDirection.xyz);
-		float specComp = max(0., dot(vNormal, angleW));
-		specComp = pow(specComp, max(1., glossiness));
-
-		result.specular = specComp * specularColor * spotAtten * attenuation;
-#endif
-
-		return result;
-	}
-
-	result.diffuse = vec3(0.);
-#ifdef SPECULARTERM
-	result.specular = vec3(0.);
-#endif
-
-	return result;
-}
-
-lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, vec3 groundColor, float glossiness) {
-	lightingInfo result;
-
-	// Diffuse
-	float ndl = dot(vNormal, lightData.xyz) * 0.5 + 0.5;
-	result.diffuse = mix(groundColor, diffuseColor, ndl);
-
-#ifdef SPECULARTERM
-	// Specular
-	vec3 angleW = normalize(viewDirectionW + lightData.xyz);
-	float specComp = max(0., dot(vNormal, angleW));
-	specComp = pow(specComp, max(1., glossiness));
-
-	result.specular = specComp * specularColor;
-#endif
-
-	return result;
-}
 
 void main(void) {
 	// Clip plane
@@ -524,170 +152,13 @@ void main(void) {
 
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
-#ifdef SPECULARTERM
-	vec3 specularBase = vec3(0., 0., 0.);
-#endif
+    lightingInfo info;
 	float shadow = 1.;
-
-#ifdef LIGHT0
-#ifndef SPECULARTERM
-	vec3 vLightSpecular0 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT0
-	lightingInfo info = computeSpotLighting(viewDirectionW, normalW, vLightData0, vLightDirection0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness);
-#endif
-#ifdef HEMILIGHT0
-	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightGround0, glossiness);
-#endif
-#if defined(POINTLIGHT0) || defined(DIRLIGHT0)
-	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness);
-#endif
-#ifdef SHADOW0
-#ifdef SHADOWVSM0
-	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
-#else
-#ifdef SHADOWPCF0
-#if defined(POINTLIGHT0)
-	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
-#endif
-#else
-#if defined(POINTLIGHT0)
-	shadow = computeShadowCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-#else
-	shadow = computeShadow(vPositionFromLight0, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT1
-#ifndef SPECULARTERM
-	vec3 vLightSpecular1 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT1
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness);
-#endif
-#ifdef HEMILIGHT1
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightGround1, glossiness);
-#endif
-#if defined(POINTLIGHT1) || defined(DIRLIGHT1)
-	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness);
-#endif
-#ifdef SHADOW1
-#ifdef SHADOWVSM1
-	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
-#else
-#ifdef SHADOWPCF1
-#if defined(POINTLIGHT1)
-	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
-#endif
-#else
-#if defined(POINTLIGHT1)
-	shadow = computeShadowCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-#else
-	shadow = computeShadow(vPositionFromLight1, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT2
-#ifndef SPECULARTERM
-	vec3 vLightSpecular2 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT2
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData2, vLightDirection2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness);
-#endif
-#ifdef HEMILIGHT2
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightGround2, glossiness);
-#endif
-#if defined(POINTLIGHT2) || defined(DIRLIGHT2)
-	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness);
-#endif
-#ifdef SHADOW2
-#ifdef SHADOWVSM2
-	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
-#else
-#ifdef SHADOWPCF2
-#if defined(POINTLIGHT2)
-	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
-#endif
-#else
-#if defined(POINTLIGHT2)
-	shadow = computeShadowCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-#else
-	shadow = computeShadow(vPositionFromLight2, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-#endif
-#endif	
-#endif	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT3
-#ifndef SPECULARTERM
-	vec3 vLightSpecular3 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT3
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness);
-#endif
-#ifdef HEMILIGHT3
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightGround3, glossiness);
-#endif
-#if defined(POINTLIGHT3) || defined(DIRLIGHT3)
-	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness);
-#endif
-#ifdef SHADOW3
-#ifdef SHADOWVSM3
-	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
-#else
-#ifdef SHADOWPCF3
-#if defined(POINTLIGHT3)
-	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
-#endif
-#else
-#if defined(POINTLIGHT3)
-	shadow = computeShadowCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-#else
-	shadow = computeShadow(vPositionFromLight3, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-#endif
-#endif	
-#endif	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
+	
 #ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
+	vec3 specularBase = vec3(0., 0., 0.);
 #endif
+	#include<lightFragment>[0..maxSimultaneousLights]
 
 #ifdef VERTEXALPHA
 	alpha *= vColor.a;
@@ -704,10 +175,7 @@ void main(void) {
 	// Composition
 	vec4 color = vec4(finalDiffuse + finalSpecular, alpha);
 
-#ifdef FOG
-	float fog = CalcFogFactor();
-	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
-#endif
+#include<fogFragment>
 
 	gl_FragColor = color;
 }

+ 12 - 83
materialsLibrary/materials/terrain/terrain.vertex.fx

@@ -14,21 +14,11 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#endif
 
-// Uniforms
+#include<bonesDeclaration>
 
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+// Uniforms
+#include<instancesDeclaration>
 
 uniform mat4 view;
 uniform mat4 viewProjection;
@@ -39,10 +29,6 @@ uniform mat4 textureMatrix;
 uniform vec2 vTextureInfos;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -57,56 +43,14 @@ varying vec3 vNormalW;
 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
+#include<clipPlaneVertexDeclaration>
+#include<fogVertexDeclaration>
+#include<shadowsVertexDeclaration>
 
 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
+	#include<instancesVertex>
+    #include<bonesVertex>
+	
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);
@@ -141,25 +85,10 @@ void main(void) {
 #endif
 
 	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
-
+	#include<fogVertex>
+	
 	// 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
+    #include<shadowsVertex>
 
 	// Vertex color
 #ifdef VERTEXCOLOR

+ 33 - 232
materialsLibrary/materials/triPlanar/babylon.triPlanarMaterial.ts

@@ -16,51 +16,17 @@ module BABYLON {
         public ALPHATEST = false;
         public POINTSIZE = false;
         public FOG = false;
-        public LIGHT0 = false;
-        public LIGHT1 = false;
-        public LIGHT2 = false;
-        public LIGHT3 = false;
-        public SPOTLIGHT0 = false;
-        public SPOTLIGHT1 = false;
-        public SPOTLIGHT2 = false;
-        public SPOTLIGHT3 = false;
-        public HEMILIGHT0 = false;
-        public HEMILIGHT1 = false;
-        public HEMILIGHT2 = false;
-        public HEMILIGHT3 = false;
-        public DIRLIGHT0 = false;
-        public DIRLIGHT1 = false;
-        public DIRLIGHT2 = false;
-        public DIRLIGHT3 = false;
-        public POINTLIGHT0 = false;
-        public POINTLIGHT1 = false;
-        public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;        
-        public SHADOW0 = false;
-        public SHADOW1 = false;
-        public SHADOW2 = false;
-        public SHADOW3 = false;
-        public SHADOWS = false;
-        public SHADOWVSM0 = false;
-        public SHADOWVSM1 = false;
-        public SHADOWVSM2 = false;
-        public SHADOWVSM3 = false;
-        public SHADOWPCF0 = false;
-        public SHADOWPCF1 = false;
-        public SHADOWPCF2 = false;
-        public SHADOWPCF3 = false;
         public SPECULARTERM = false;
         public NORMAL = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public BONES = false;
-        public BONES4 = false;
+        public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
 
         constructor() {
             super();
-            this._keys = Object.keys(this);
+            this.rebuild();
         }
     }
 
@@ -100,10 +66,11 @@ module BABYLON {
         
         @serialize()
         public disableLighting = false;
+        
+        @serialize()
+        public maxSimultaneousLights = 4;
 
         private _worldViewProjectionMatrix = Matrix.Zero();
-        private _scaledDiffuse = new Color3();
-        private _scaledSpecular = new Color3();
         private _renderId: number;
 
         private _defines = new TriPlanarMaterialDefines();
@@ -217,87 +184,9 @@ module BABYLON {
                 this._defines.FOG = true;
             }
 
-            var lightIndex = 0;
+            // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    // Excluded check
-                    if (light._excludedMeshesIds.length > 0) {
-                        for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
-                            var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
-
-                            if (excludedMesh) {
-                                light.excludedMeshes.push(excludedMesh);
-                            }
-                        }
-
-                        light._excludedMeshesIds = [];
-                    }
-
-                    // Included check
-                    if (light._includedOnlyMeshesIds.length > 0) {
-                        for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
-                            var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
-
-                            if (includedOnlyMesh) {
-                                light.includedOnlyMeshes.push(includedOnlyMesh);
-                            }
-                        }
-
-                        light._includedOnlyMeshesIds = [];
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-                    needNormals = true;
-                    this._defines["LIGHT" + lightIndex] = true;
-
-                    var type;
-                    if (light instanceof SpotLight) {
-                        type = "SPOTLIGHT" + lightIndex;
-                    } else if (light instanceof HemisphericLight) {
-                        type = "HEMILIGHT" + lightIndex;
-                    } else if (light instanceof PointLight) {
-                        type = "POINTLIGHT" + lightIndex;
-                    } else {
-                        type = "DIRLIGHT" + lightIndex;
-                    }
-
-                    this._defines[type] = true;
-                    
-                    // Specular
-                    if (!light.specular.equalsFloats(0, 0, 0)) {
-                        this._defines.SPECULARTERM = true;
-                    }
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh && mesh.receiveShadows && shadowGenerator) {
-                            this._defines["SHADOW" + lightIndex] = true;
-
-                            this._defines.SHADOWS = true;
-
-                            if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
-                                this._defines["SHADOWVSM" + lightIndex] = true;
-                            }
-
-                            if (shadowGenerator.usePoissonSampling) {
-                                this._defines["SHADOWPCF" + lightIndex] = true;
-                            }
-                        }
-                    }
-
-                    lightIndex++;
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
-                }
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
             }
 
             // Attribs
@@ -312,10 +201,10 @@ module BABYLON {
                         this._defines.VERTEXALPHA = true;
                     }
                 }
+                
                 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
@@ -336,30 +225,10 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
 
-                for (lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
-                    if (!this._defines["LIGHT" + lightIndex]) {
-                        continue;
-                    }
-
-                    if (lightIndex > 0) {
-                        fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOW" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOW" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWPCF" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWVSM" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
-                    }
-                }
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
              
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -373,39 +242,27 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
-                    attribs.push(VertexBuffer.MatricesIndicesKind);
-                    attribs.push(VertexBuffer.MatricesWeightsKind);
-                }
-
-                if (this._defines.INSTANCES) {
-                    attribs.push("world0");
-                    attribs.push("world1");
-                    attribs.push("world2");
-                    attribs.push("world3");
-                }
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
 
                 // Legacy browser patch
                 var shaderName = "triplanar";
                 var join = this._defines.toString();
+                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                    "vFogInfos", "vFogColor", "pointSize",
+                    "mBones",
+                    "vClipPlane",
+                    "tileSize"
+                ];
+                var samplers = ["diffuseSamplerX", "diffuseSamplerY", "diffuseSamplerZ",
+                    "normalSamplerX", "normalSamplerY", "normalSamplerZ"
+                ];
+                
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                
                 this._effect = scene.getEngine().createEffect(shaderName,
-                    attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
-                        "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
-                        "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
-                        "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
-                        "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
-                        "vFogInfos", "vFogColor", "pointSize",
-                        "mBones",
-                        "vClipPlane",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
-                        "tileSize"
-                    ],
-                    ["diffuseSamplerX", "diffuseSamplerY", "diffuseSamplerZ",
-                        "normalSamplerX", "normalSamplerY", "normalSamplerZ",
-                        "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
-                    ],
-                    join, fallbacks, this.onCompiled, this.onError);
+                    attribs, uniforms, samplers,
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
             }
             if (!this._effect.isReady()) {
                 return false;
@@ -437,9 +294,7 @@ module BABYLON {
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
             // Bones
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
-            }
+            MaterialHelper.BindBonesParameters(mesh, this._effect);
             
             this._effect.setFloat("tileSize", this.tileSize);
 
@@ -464,10 +319,7 @@ module BABYLON {
                     this._effect.setTexture("normalSamplerZ", this.normalTextureZ);
                 }
                 // Clip plane
-                if (scene.clipPlane) {
-                    var clipPlane = scene.clipPlane;
-                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
-                }
+                MaterialHelper.BindClipPlane(this._effect, scene);
 
                 // Point size
                 if (this.pointsCloud) {
@@ -477,62 +329,14 @@ module BABYLON {
                 this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
 
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             
             if (this._defines.SPECULARTERM) {
                 this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                var lightIndex = 0;
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-
-                    if (light instanceof PointLight) {
-                        // Point Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof DirectionalLight) {
-                        // Directional Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof SpotLight) {
-                        // Spot Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
-                    } else if (light instanceof HemisphericLight) {
-                        // Hemispheric Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
-                    }
-
-                    light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
-                    this._effect.setColor4("vLightDiffuse" + lightIndex, this._scaledDiffuse, light.range);
-                    
-                    if (this._defines.SPECULARTERM) {
-                        light.specular.scaleToRef(light.intensity, this._scaledSpecular);
-                        this._effect.setColor3("vLightSpecular" + lightIndex, this._scaledSpecular);
-                    }
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh.receiveShadows && shadowGenerator) {
-                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                            this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                            this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
-                        }
-                    }
-
-                    lightIndex++;
-
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
-                }
+                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
             }
 
             // View
@@ -541,10 +345,7 @@ module BABYLON {
             }
 
             // Fog
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                this._effect.setColor3("vFogColor", scene.fogColor);
-            }
+            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
 
             super.bind(world, mesh);
         }

+ 14 - 555
materialsLibrary/materials/triPlanar/triplanar.fragment.fx

@@ -16,97 +16,7 @@ varying vec4 vColor;
 #endif
 
 // Lights
-#ifdef LIGHT0
-uniform vec4 vLightData0;
-uniform vec4 vLightDiffuse0;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular0;
-#endif
-#ifdef SHADOW0
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-varying vec4 vPositionFromLight0;
-uniform sampler2D shadowSampler0;
-#else
-uniform samplerCube shadowSampler0;
-#endif
-uniform vec3 shadowsInfo0;
-#endif
-#ifdef SPOTLIGHT0
-uniform vec4 vLightDirection0;
-#endif
-#ifdef HEMILIGHT0
-uniform vec3 vLightGround0;
-#endif
-#endif
-
-#ifdef LIGHT1
-uniform vec4 vLightData1;
-uniform vec4 vLightDiffuse1;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular1;
-#endif
-#ifdef SHADOW1
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-varying vec4 vPositionFromLight1;
-uniform sampler2D shadowSampler1;
-#else
-uniform samplerCube shadowSampler1;
-#endif
-uniform vec3 shadowsInfo1;
-#endif
-#ifdef SPOTLIGHT1
-uniform vec4 vLightDirection1;
-#endif
-#ifdef HEMILIGHT1
-uniform vec3 vLightGround1;
-#endif
-#endif
-
-#ifdef LIGHT2
-uniform vec4 vLightData2;
-uniform vec4 vLightDiffuse2;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular2;
-#endif
-#ifdef SHADOW2
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-varying vec4 vPositionFromLight2;
-uniform sampler2D shadowSampler2;
-#else
-uniform samplerCube shadowSampler2;
-#endif
-uniform vec3 shadowsInfo2;
-#endif
-#ifdef SPOTLIGHT2
-uniform vec4 vLightDirection2;
-#endif
-#ifdef HEMILIGHT2
-uniform vec3 vLightGround2;
-#endif
-#endif
-
-#ifdef LIGHT3
-uniform vec4 vLightData3;
-uniform vec4 vLightDiffuse3;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular3;
-#endif
-#ifdef SHADOW3
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-varying vec4 vPositionFromLight3;
-uniform sampler2D shadowSampler3;
-#else
-uniform samplerCube shadowSampler3;
-#endif
-uniform vec3 shadowsInfo3;
-#endif
-#ifdef SPOTLIGHT3
-uniform vec4 vLightDirection3;
-#endif
-#ifdef HEMILIGHT3
-uniform vec3 vLightGround3;
-#endif
-#endif
+#include<lightFragmentDeclaration>[0..maxSimultaneousLights]
 
 // Samplers
 #ifdef DIFFUSEX
@@ -137,316 +47,20 @@ uniform sampler2D normalSamplerZ;
 varying mat3 tangentSpace;
 #endif
 
-// Shadows
-#ifdef SHADOWS
-
-float unpack(vec4 color)
-{
-	const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-	return dot(color, bit_shift);
-}
-
-#if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
-float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-	depth = clamp(depth, 0., 1.0);
-
-	directionToLight = normalize(directionToLight);
-	directionToLight.y = - directionToLight.y;
-
-	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
-
-	if (depth > shadow)
-	{
-		return darkness;
-	}
-	return 1.0;
-}
-
-float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-
-	depth = clamp(depth, 0., 1.0);
-	float diskScale = 2.0 / mapSize;
-
-	directionToLight = normalize(directionToLight);
-	directionToLight.y = -directionToLight.y;
-
-	float visibility = 1.;
-
-	vec3 poissonDisk[4];
-	poissonDisk[0] = vec3(-1.0, 1.0, -1.0);
-	poissonDisk[1] = vec3(1.0, -1.0, -1.0);
-	poissonDisk[2] = vec3(-1.0, -1.0, -1.0);
-	poissonDisk[3] = vec3(1.0, -1.0, 1.0);
-
-	// Poisson Sampling
-	float biasedDepth = depth - bias;
-
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * diskScale)) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * diskScale)) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * diskScale)) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * diskScale)) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-#endif
-
-#if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
-float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
-
-	if (depth.z > shadow)
-	{
-		return darkness;
-	}
-	return 1.;
-}
-
-float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float visibility = 1.;
-
-	vec2 poissonDisk[4];
-	poissonDisk[0] = vec2(-0.94201624, -0.39906216);
-	poissonDisk[1] = vec2(0.94558609, -0.76890725);
-	poissonDisk[2] = vec2(-0.094184101, -0.92938870);
-	poissonDisk[3] = vec2(0.34495938, 0.29387760);
-
-	// Poisson Sampling
-	float biasedDepth = depth.z - bias;
-
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] / mapSize)) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-
-// Thanks to http://devmaster.net/
-float unpackHalf(vec2 color)
-{
-	return color.x + (color.y / 255.0);
-}
-
-float linstep(float low, float high, float v) {
-	return clamp((v - low) / (high - low), 0.0, 1.0);
-}
-
-float ChebychevInequality(vec2 moments, float compare, float bias)
-{
-	float p = smoothstep(compare - bias, compare, moments.x);
-	float variance = max(moments.y - moments.x * moments.x, 0.02);
-	float d = compare - moments.x;
-	float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
-
-	return clamp(max(p, p_max), 0.0, 1.0);
-}
-
-float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
-	{
-		return 1.0;
-	}
-
-	vec4 texel = texture2D(shadowSampler, uv);
-
-	vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-	return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
-}
-#endif
-#endif
-
-
-#ifdef CLIPPLANE
-varying float fClipDistance;
-#endif
-
-// Fog
-#ifdef FOG
-
-#define FOGMODE_NONE    0.
-#define FOGMODE_EXP     1.
-#define FOGMODE_EXP2    2.
-#define FOGMODE_LINEAR  3.
-#define E 2.71828
-
-uniform vec4 vFogInfos;
-uniform vec3 vFogColor;
-varying float fFogDistance;
-
-float CalcFogFactor()
-{
-	float fogCoeff = 1.0;
-	float fogStart = vFogInfos.y;
-	float fogEnd = vFogInfos.z;
-	float fogDensity = vFogInfos.w;
-
-	if (FOGMODE_LINEAR == vFogInfos.x)
-	{
-		fogCoeff = (fogEnd - fFogDistance) / (fogEnd - fogStart);
-	}
-	else if (FOGMODE_EXP == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fogDensity);
-	}
-	else if (FOGMODE_EXP2 == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fFogDistance * fogDensity * fogDensity);
-	}
-
-	return clamp(fogCoeff, 0.0, 1.0);
-}
-#endif
-
-// Light Computing
-struct lightingInfo
-{
-	vec3 diffuse;
-#ifdef SPECULARTERM
-	vec3 specular;
-#endif
-};
-
-lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float range, float glossiness) {
-	lightingInfo result;
-
-	vec3 lightVectorW;
-	float attenuation = 1.0;
-	if (lightData.w == 0.)
-	{
-		vec3 direction = lightData.xyz - vPositionW;
-
-		attenuation = max(0., 1.0 - length(direction) / range);
-		lightVectorW = normalize(direction);
-	}
-	else
-	{
-		lightVectorW = normalize(-lightData.xyz);
-	}
-
-	// diffuse
-	float ndl = max(0., dot(vNormal, lightVectorW));
-	result.diffuse = ndl * diffuseColor * attenuation;
-
-#ifdef SPECULARTERM
-	// Specular
-	vec3 angleW = normalize(viewDirectionW + lightVectorW);
-	float specComp = max(0., dot(vNormal, angleW));
-	specComp = pow(specComp, max(1., glossiness));
-
-	result.specular = specComp * specularColor * attenuation;
-#endif
-	return result;
-}
-
-lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, vec3 specularColor, float range, float glossiness) {
-	lightingInfo result;
-
-	vec3 direction = lightData.xyz - vPositionW;
-	vec3 lightVectorW = normalize(direction);
-	float attenuation = max(0., 1.0 - length(direction) / range);
-
-	// diffuse
-	float cosAngle = max(0., dot(-lightDirection.xyz, lightVectorW));
-	float spotAtten = 0.0;
-
-	if (cosAngle >= lightDirection.w)
-	{
-		cosAngle = max(0., pow(cosAngle, lightData.w));
-		spotAtten = clamp((cosAngle - lightDirection.w) / (1. - cosAngle), 0.0, 1.0);
-
-		// Diffuse
-		float ndl = max(0., dot(vNormal, -lightDirection.xyz));
-		result.diffuse = ndl * spotAtten * diffuseColor * attenuation;
-
-#ifdef SPECULARTERM
-		// Specular
-		vec3 angleW = normalize(viewDirectionW - lightDirection.xyz);
-		float specComp = max(0., dot(vNormal, angleW));
-		specComp = pow(specComp, max(1., glossiness));
-
-		result.specular = specComp * specularColor * spotAtten * attenuation;
-#endif
-
-		return result;
-	}
-
-	result.diffuse = vec3(0.);
-#ifdef SPECULARTERM
-	result.specular = vec3(0.);
-#endif
-
-	return result;
-}
-
-lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, vec3 groundColor, float glossiness) {
-	lightingInfo result;
-
-	// Diffuse
-	float ndl = dot(vNormal, lightData.xyz) * 0.5 + 0.5;
-	result.diffuse = mix(groundColor, diffuseColor, ndl);
-
-#ifdef SPECULARTERM
-	// Specular
-	vec3 angleW = normalize(viewDirectionW + lightData.xyz);
-	float specComp = max(0., dot(vNormal, angleW));
-	specComp = pow(specComp, max(1., glossiness));
-
-	result.specular = specComp * specularColor;
-#endif
-
-	return result;
-}
+#include<lightsFragmentFunctions>
+#include<shadowsFragmentFunctions>
+#include<clipPlaneFragmentDeclaration>
+#include<fogFragmentDeclaration>
 
 void main(void) {
 	// Clip plane
-#ifdef CLIPPLANE
-	if (fClipDistance > 0.0)
-		discard;
-#endif
+	#include<clipPlaneFragment>
 
 	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
 
 	// Base color
 	vec4 baseColor = vec4(0., 0., 0., 1.);
 	vec3 diffuseColor = vDiffuseColor.rgb;
-	
-#ifdef SPECULARTERM
-	float glossiness = vSpecularColor.a;
-	vec3 specularColor = vSpecularColor.rgb;
-#else
-	float glossiness = 0.;
-#endif
 
 	// Alpha
 	float alpha = vDiffuseColor.a;
@@ -497,170 +111,18 @@ void main(void) {
 
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
-#ifdef SPECULARTERM
-	vec3 specularBase = vec3(0., 0., 0.);
-#endif
+    lightingInfo info;
 	float shadow = 1.;
-
-#ifdef LIGHT0
-#ifndef SPECULARTERM
-	vec3 vLightSpecular0 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT0
-	lightingInfo info = computeSpotLighting(viewDirectionW, normalW, vLightData0, vLightDirection0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness);
-#endif
-#ifdef HEMILIGHT0
-	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightGround0, glossiness);
-#endif
-#if defined(POINTLIGHT0) || defined(DIRLIGHT0)
-	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness);
-#endif
-#ifdef SHADOW0
-#ifdef SHADOWVSM0
-	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
-#else
-#ifdef SHADOWPCF0
-#if defined(POINTLIGHT0)
-	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
-#endif
-#else
-#if defined(POINTLIGHT0)
-	shadow = computeShadowCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-#else
-	shadow = computeShadow(vPositionFromLight0, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT1
-#ifndef SPECULARTERM
-	vec3 vLightSpecular1 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT1
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness);
-#endif
-#ifdef HEMILIGHT1
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightGround1, glossiness);
-#endif
-#if defined(POINTLIGHT1) || defined(DIRLIGHT1)
-	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness);
-#endif
-#ifdef SHADOW1
-#ifdef SHADOWVSM1
-	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
-#else
-#ifdef SHADOWPCF1
-#if defined(POINTLIGHT1)
-	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
-#endif
-#else
-#if defined(POINTLIGHT1)
-	shadow = computeShadowCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-#else
-	shadow = computeShadow(vPositionFromLight1, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
+	
 #ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT2
-#ifndef SPECULARTERM
-	vec3 vLightSpecular2 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT2
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData2, vLightDirection2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness);
-#endif
-#ifdef HEMILIGHT2
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightGround2, glossiness);
-#endif
-#if defined(POINTLIGHT2) || defined(DIRLIGHT2)
-	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness);
-#endif
-#ifdef SHADOW2
-#ifdef SHADOWVSM2
-	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
-#else
-#ifdef SHADOWPCF2
-#if defined(POINTLIGHT2)
-	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
-#endif
-#else
-#if defined(POINTLIGHT2)
-	shadow = computeShadowCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-#else
-	shadow = computeShadow(vPositionFromLight2, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-#endif
-#endif	
-#endif	
+	float glossiness = vSpecularColor.a;
+	vec3 specularBase = vec3(0., 0., 0.);
+    vec3 specularColor = vSpecularColor.rgb;
 #else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
+	float glossiness = 0.;
 #endif
 
-#ifdef LIGHT3
-#ifndef SPECULARTERM
-	vec3 vLightSpecular3 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT3
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness);
-#endif
-#ifdef HEMILIGHT3
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightGround3, glossiness);
-#endif
-#if defined(POINTLIGHT3) || defined(DIRLIGHT3)
-	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness);
-#endif
-#ifdef SHADOW3
-#ifdef SHADOWVSM3
-	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
-#else
-#ifdef SHADOWPCF3
-#if defined(POINTLIGHT3)
-	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
-#endif
-#else
-#if defined(POINTLIGHT3)
-	shadow = computeShadowCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-#else
-	shadow = computeShadow(vPositionFromLight3, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-#endif
-#endif	
-#endif	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
+#include<lightFragment>[0..maxSimultaneousLights]
 
 #ifdef VERTEXALPHA
 	alpha *= vColor.a;
@@ -677,10 +139,7 @@ void main(void) {
 	// Composition
 	vec4 color = vec4(finalDiffuse + finalSpecular, alpha);
 
-#ifdef FOG
-	float fog = CalcFogFactor();
-	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
-#endif
+#include<fogFragment>
 
 	gl_FragColor = color;
 }

+ 14 - 84
materialsLibrary/materials/triPlanar/triplanar.vertex.fx

@@ -8,21 +8,11 @@ attribute vec3 normal;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#endif
 
-// Uniforms
+#include<bonesDeclaration>
 
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+// Uniforms
+#include<instancesDeclaration>
 
 uniform mat4 view;
 uniform mat4 viewProjection;
@@ -41,10 +31,6 @@ varying vec2 vTextureUVZ;
 
 uniform float tileSize;
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -59,56 +45,17 @@ varying mat3 tangentSpace;
 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;
+#include<clipPlaneVertexDeclaration>
 
-#ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
-#else
-	finalWorld = world;
-#endif
+#include<fogVertexDeclaration>
+#include<shadowsVertexDeclaration>
 
-#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;
+void main(void)
+{
 
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = finalWorld * (m0 + m1 + m2);
-#endif 
-
-#endif
+	#include<instancesVertex>
+    #include<bonesVertex>
+	
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);
@@ -153,30 +100,13 @@ void main(void) {
 #endif
 
 	// Clip plane
-#ifdef CLIPPLANE
-	fClipDistance = dot(worldPos, vClipPlane);
-#endif
+	#include<clipPlaneVertex>
 
 	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
+	#include<fogVertex>
 
 	// 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
+	#include<shadowsVertex>
 
 	// Vertex color
 #ifdef VERTEXCOLOR

+ 48 - 240
materialsLibrary/materials/water/babylon.waterMaterial.ts

@@ -2,8 +2,6 @@
 /// <reference path="../simple/babylon.simpleMaterial.ts"/>
 
 module BABYLON {
-	var maxSimultaneousLights = 4;
-
     class WaterMaterialDefines extends MaterialDefines {
         public BUMP = false;
         public REFLECTION = false;
@@ -11,53 +9,19 @@ module BABYLON {
         public ALPHATEST = false;
         public POINTSIZE = false;
         public FOG = false;
-        public LIGHT0 = false;
-        public LIGHT1 = false;
-        public LIGHT2 = false;
-        public LIGHT3 = false;
-        public SPOTLIGHT0 = false;
-        public SPOTLIGHT1 = false;
-        public SPOTLIGHT2 = false;
-        public SPOTLIGHT3 = false;
-        public HEMILIGHT0 = false;
-        public HEMILIGHT1 = false;
-        public HEMILIGHT2 = false;
-        public HEMILIGHT3 = false;
-        public DIRLIGHT0 = false;
-        public DIRLIGHT1 = false;
-        public DIRLIGHT2 = false;
-        public DIRLIGHT3 = false;
-        public POINTLIGHT0 = false;
-        public POINTLIGHT1 = false;
-        public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;        
-        public SHADOW0 = false;
-        public SHADOW1 = false;
-        public SHADOW2 = false;
-        public SHADOW3 = false;
-        public SHADOWS = false;
-        public SHADOWVSM0 = false;
-        public SHADOWVSM1 = false;
-        public SHADOWVSM2 = false;
-        public SHADOWVSM3 = false;
-        public SHADOWPCF0 = false;
-        public SHADOWPCF1 = false;
-        public SHADOWPCF2 = false;
-        public SHADOWPCF3 = false;
         public NORMAL = false;
         public UV1 = false;
         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 SPECULARTERM = false;
 
         constructor() {
             super();
-            this._keys = Object.keys(this);
+            this.rebuild();
         }
     }
 	
@@ -80,6 +44,9 @@ module BABYLON {
         @serialize()
         public disableLighting = false;
         
+        @serialize()
+        public maxSimultaneousLights = 4;
+        
         /**
         * @param {number}: Represents the wind force
         */
@@ -135,8 +102,6 @@ module BABYLON {
 		private _reflectionTransform: Matrix = Matrix.Zero();
 		private _lastTime: number = 0;
         
-        private _scaledDiffuse = new Color3();
-        private _scaledSpecular = new Color3();
         private _renderId: number;
 
         private _defines = new WaterMaterialDefines();
@@ -174,6 +139,14 @@ module BABYLON {
             this._reflectionRTT.refreshRate = refreshRate;
         }
         
+        public getRenderList(): AbstractMesh[] {
+            return this._refractionRTT.renderList;
+        }
+        
+        public get renderTargetsEnabled(): boolean {
+            return !(this._refractionRTT.refreshRate === 0);
+        }
+        
 		public needAlphaBlending(): boolean {
             return (this.alpha < 1.0);
         }
@@ -259,88 +232,10 @@ module BABYLON {
             if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
                 this._defines.FOG = true;
             }
-
-            var lightIndex = 0;
+            
+            // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    // Excluded check
-                    if (light._excludedMeshesIds.length > 0) {
-                        for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
-                            var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
-
-                            if (excludedMesh) {
-                                light.excludedMeshes.push(excludedMesh);
-                            }
-                        }
-
-                        light._excludedMeshesIds = [];
-                    }
-
-                    // Included check
-                    if (light._includedOnlyMeshesIds.length > 0) {
-                        for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
-                            var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
-
-                            if (includedOnlyMesh) {
-                                light.includedOnlyMeshes.push(includedOnlyMesh);
-                            }
-                        }
-
-                        light._includedOnlyMeshesIds = [];
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-                    needNormals = true;
-                    this._defines["LIGHT" + lightIndex] = true;
-
-                    var type;
-                    if (light instanceof SpotLight) {
-                        type = "SPOTLIGHT" + lightIndex;
-                    } else if (light instanceof HemisphericLight) {
-                        type = "HEMILIGHT" + lightIndex;
-                    } else if (light instanceof PointLight) {
-                        type = "POINTLIGHT" + lightIndex;
-                    } else {
-                        type = "DIRLIGHT" + lightIndex;
-                    }
-
-                    this._defines[type] = true;
-                    
-                    // Specular
-                    if (!light.specular.equalsFloats(0, 0, 0)) {
-                        this._defines.SPECULARTERM = true;
-                    }
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh && mesh.receiveShadows && shadowGenerator) {
-                            this._defines["SHADOW" + lightIndex] = true;
-
-                            this._defines.SHADOWS = true;
-
-                            if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
-                                this._defines["SHADOWVSM" + lightIndex] = true;
-                            }
-
-                            if (shadowGenerator.usePoissonSampling) {
-                                this._defines["SHADOWPCF" + lightIndex] = true;
-                            }
-                        }
-                    }
-
-                    lightIndex++;
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
-                }
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
             }
 
             // Attribs
@@ -363,10 +258,10 @@ module BABYLON {
                         this._defines.VERTEXALPHA = true;
                     }
                 }
+                
                 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
@@ -389,30 +284,10 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
 
-                for (lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
-                    if (!this._defines["LIGHT" + lightIndex]) {
-                        continue;
-                    }
-
-                    if (lightIndex > 0) {
-                        fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOW" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOW" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWPCF" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
-                    }
-
-                    if (this._defines["SHADOWVSM" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
-                    }
-                }
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
              
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -434,44 +309,31 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
-                    attribs.push(VertexBuffer.MatricesIndicesKind);
-                    attribs.push(VertexBuffer.MatricesWeightsKind);
-                }
-
-                if (this._defines.INSTANCES) {
-                    attribs.push("world0");
-                    attribs.push("world1");
-                    attribs.push("world2");
-                    attribs.push("world3");
-                }
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
 
                 // Legacy browser patch
                 var shaderName = "water";
                 var join = this._defines.toString();
-				
+                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                    "vFogInfos", "vFogColor", "pointSize",
+                    "vNormalInfos", 
+                    "mBones",
+                    "vClipPlane", "normalMatrix",
+                    // Water
+                    "worldReflectionViewProjection", "windDirection", "waveLength", "time", "windForce",
+                    "cameraPosition", "bumpHeight", "waveHeight", "waterColor", "colorBlendFactor", "waveSpeed"
+                ]
+                var samplers = ["normalSampler",
+                    // Water
+                    "refractionSampler", "reflectionSampler"
+                ];
+                
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                
                 this._effect = scene.getEngine().createEffect(shaderName,
-                    attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
-                        "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
-                        "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
-                        "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
-                        "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
-                        "vFogInfos", "vFogColor", "pointSize",
-                        "vNormalInfos", 
-                        "mBones",
-                        "vClipPlane", "normalMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
-						// Water
-						"worldReflectionViewProjection", "windDirection", "waveLength", "time", "windForce",
-						"cameraPosition", "bumpHeight", "waveHeight", "waterColor", "colorBlendFactor", "waveSpeed"
-                    ],
-                    ["normalSampler",
-                        "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3",
-						// Water
-						"refractionSampler", "reflectionSampler"
-                    ],
-                    join, fallbacks, this.onCompiled, this.onError);
+                    attribs, uniforms, samplers,
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
             }
             if (!this._effect.isReady()) {
                 return false;
@@ -503,9 +365,7 @@ module BABYLON {
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
             // Bones
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
-            }
+            MaterialHelper.BindBonesParameters(mesh, this._effect);
 
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
@@ -516,10 +376,7 @@ module BABYLON {
                     this._effect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
                 }
                 // Clip plane
-                if (scene.clipPlane) {
-                    var clipPlane = scene.clipPlane;
-                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
-                }
+                MaterialHelper.BindClipPlane(this._effect, scene);
 
                 // Point size
                 if (this.pointsCloud) {
@@ -529,62 +386,14 @@ module BABYLON {
                 this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
 
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             
             if (this._defines.SPECULARTERM) {
                 this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                var lightIndex = 0;
-                for (var index = 0; index < scene.lights.length; index++) {
-                    var light = scene.lights[index];
-
-                    if (!light.isEnabled()) {
-                        continue;
-                    }
-
-                    if (!light.canAffectMesh(mesh)) {
-                        continue;
-                    }
-
-                    if (light instanceof PointLight) {
-                        // Point Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof DirectionalLight) {
-                        // Directional Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
-                    } else if (light instanceof SpotLight) {
-                        // Spot Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
-                    } else if (light instanceof HemisphericLight) {
-                        // Hemispheric Light
-                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
-                    }
-
-                    light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
-                    this._effect.setColor4("vLightDiffuse" + lightIndex, this._scaledDiffuse, light.range);
-                    
-                    if (this._defines.SPECULARTERM) {
-                        light.specular.scaleToRef(light.intensity, this._scaledSpecular);
-                        this._effect.setColor3("vLightSpecular" + lightIndex, this._scaledSpecular);
-                    }
-
-                    // Shadows
-                    if (scene.shadowsEnabled) {
-                        var shadowGenerator = light.getShadowGenerator();
-                        if (mesh.receiveShadows && shadowGenerator) {
-                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                            this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                            this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
-                        }
-                    }
-
-                    lightIndex++;
-
-                    if (lightIndex === maxSimultaneousLights)
-                        break;
-                }
+                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
             }
 
             // View
@@ -593,10 +402,7 @@ module BABYLON {
             }
 
             // Fog
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                this._effect.setColor3("vFogColor", scene.fogColor);
-            }
+            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
             
             // Water
             if (StandardMaterial.ReflectionTextureEnabled) {
@@ -740,6 +546,8 @@ module BABYLON {
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.WaterMaterial";
+            serializationObject.reflectionTexture.isRenderTarget = true;
+            serializationObject.refractionTexture.isRenderTarget = true;
             return serializationObject;
         }
 

+ 15 - 561
materialsLibrary/materials/water/water.fragment.fx

@@ -20,97 +20,10 @@ varying vec4 vColor;
 #endif
 
 // Lights
-#ifdef LIGHT0
-uniform vec4 vLightData0;
-uniform vec4 vLightDiffuse0;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular0;
-#endif
-#ifdef SHADOW0
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-varying vec4 vPositionFromLight0;
-uniform sampler2D shadowSampler0;
-#else
-uniform samplerCube shadowSampler0;
-#endif
-uniform vec3 shadowsInfo0;
-#endif
-#ifdef SPOTLIGHT0
-uniform vec4 vLightDirection0;
-#endif
-#ifdef HEMILIGHT0
-uniform vec3 vLightGround0;
-#endif
-#endif
+#include<lightFragmentDeclaration>[0..maxSimultaneousLights]
 
-#ifdef LIGHT1
-uniform vec4 vLightData1;
-uniform vec4 vLightDiffuse1;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular1;
-#endif
-#ifdef SHADOW1
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-varying vec4 vPositionFromLight1;
-uniform sampler2D shadowSampler1;
-#else
-uniform samplerCube shadowSampler1;
-#endif
-uniform vec3 shadowsInfo1;
-#endif
-#ifdef SPOTLIGHT1
-uniform vec4 vLightDirection1;
-#endif
-#ifdef HEMILIGHT1
-uniform vec3 vLightGround1;
-#endif
-#endif
-
-#ifdef LIGHT2
-uniform vec4 vLightData2;
-uniform vec4 vLightDiffuse2;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular2;
-#endif
-#ifdef SHADOW2
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-varying vec4 vPositionFromLight2;
-uniform sampler2D shadowSampler2;
-#else
-uniform samplerCube shadowSampler2;
-#endif
-uniform vec3 shadowsInfo2;
-#endif
-#ifdef SPOTLIGHT2
-uniform vec4 vLightDirection2;
-#endif
-#ifdef HEMILIGHT2
-uniform vec3 vLightGround2;
-#endif
-#endif
-
-#ifdef LIGHT3
-uniform vec4 vLightData3;
-uniform vec4 vLightDiffuse3;
-#ifdef SPECULARTERM
-uniform vec3 vLightSpecular3;
-#endif
-#ifdef SHADOW3
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-varying vec4 vPositionFromLight3;
-uniform sampler2D shadowSampler3;
-#else
-uniform samplerCube shadowSampler3;
-#endif
-uniform vec3 shadowsInfo3;
-#endif
-#ifdef SPOTLIGHT3
-uniform vec4 vLightDirection3;
-#endif
-#ifdef HEMILIGHT3
-uniform vec3 vLightGround3;
-#endif
-#endif
+#include<lightsFragmentFunctions>
+#include<shadowsFragmentFunctions>
 
 // Samplers
 #ifdef BUMP
@@ -137,324 +50,20 @@ varying vec3 vRefractionMapTexCoord;
 varying vec3 vReflectionMapTexCoord;
 varying vec3 vPosition;
 
-// Shadows
-#ifdef SHADOWS
-
-float unpack(vec4 color)
-{
-	const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-	return dot(color, bit_shift);
-}
-
-#if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
-float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-	depth = clamp(depth, 0., 1.0);
-
-	directionToLight = normalize(directionToLight);
-	directionToLight.y = - directionToLight.y;
-
-	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
-
-	if (depth > shadow)
-	{
-		return darkness;
-	}
-	return 1.0;
-}
-
-float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float bias, float darkness, float mapSize)
-{
-	vec3 directionToLight = vPositionW - lightPosition;
-	float depth = length(directionToLight);
-
-	depth = clamp(depth, 0., 1.0);
-	float diskScale = 2.0 / mapSize;
-
-	directionToLight = normalize(directionToLight);
-	directionToLight.y = -directionToLight.y;
-
-	float visibility = 1.;
-
-	vec3 poissonDisk[4];
-	poissonDisk[0] = vec3(-0.094201624, 0.04, -0.039906216);
-	poissonDisk[1] = vec3(0.094558609, -0.04, -0.076890725);
-	poissonDisk[2] = vec3(-0.094184101, 0.01, -0.092938870);
-	poissonDisk[3] = vec3(0.034495938, -0.01, 0.029387760);
-
-	// Poisson Sampling
-	float biasedDepth = depth - bias;
-
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3])) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-#endif
-
-#if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
-float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
-
-	if (depth.z > shadow)
-	{
-		return darkness;
-	}
-	return 1.;
-}
-
-float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-	{
-		return 1.0;
-	}
-
-	float visibility = 1.;
-
-	vec2 poissonDisk[4];
-	poissonDisk[0] = vec2(-0.94201624, -0.39906216);
-	poissonDisk[1] = vec2(0.94558609, -0.76890725);
-	poissonDisk[2] = vec2(-0.094184101, -0.92938870);
-	poissonDisk[3] = vec2(0.34495938, 0.29387760);
-
-	// Poisson Sampling
-	float biasedDepth = depth.z - bias;
-
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] / mapSize)) < biasedDepth) visibility -= 0.25;
-	if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] / mapSize)) < biasedDepth) visibility -= 0.25;
-
-	return  min(1.0, visibility + darkness);
-}
-
-// Thanks to http://devmaster.net/
-float unpackHalf(vec2 color)
-{
-	return color.x + (color.y / 255.0);
-}
-
-float linstep(float low, float high, float v) {
-	return clamp((v - low) / (high - low), 0.0, 1.0);
-}
-
-float ChebychevInequality(vec2 moments, float compare, float bias)
-{
-	float p = smoothstep(compare - bias, compare, moments.x);
-	float variance = max(moments.y - moments.x * moments.x, 0.02);
-	float d = compare - moments.x;
-	float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
-
-	return clamp(max(p, p_max), 0.0, 1.0);
-}
-
-float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
-{
-	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-	depth = 0.5 * depth + vec3(0.5);
-	vec2 uv = depth.xy;
-
-	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
-	{
-		return 1.0;
-	}
-
-	vec4 texel = texture2D(shadowSampler, uv);
-
-	vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-	return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
-}
-#endif
-#endif
-
-#ifdef CLIPPLANE
-varying float fClipDistance;
-#endif
+#include<clipPlaneFragmentDeclaration>
 
 // Fog
-#ifdef FOG
-
-#define FOGMODE_NONE    0.
-#define FOGMODE_EXP     1.
-#define FOGMODE_EXP2    2.
-#define FOGMODE_LINEAR  3.
-#define E 2.71828
-
-uniform vec4 vFogInfos;
-uniform vec3 vFogColor;
-varying float fFogDistance;
-
-float CalcFogFactor()
-{
-	float fogCoeff = 1.0;
-	float fogStart = vFogInfos.y;
-	float fogEnd = vFogInfos.z;
-	float fogDensity = vFogInfos.w;
-
-	if (FOGMODE_LINEAR == vFogInfos.x)
-	{
-		fogCoeff = (fogEnd - fFogDistance) / (fogEnd - fogStart);
-	}
-	else if (FOGMODE_EXP == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fogDensity);
-	}
-	else if (FOGMODE_EXP2 == vFogInfos.x)
-	{
-		fogCoeff = 1.0 / pow(E, fFogDistance * fFogDistance * fogDensity * fogDensity);
-	}
-
-	return clamp(fogCoeff, 0.0, 1.0);
-}
-#endif
-
-// Light Computing
-struct lightingInfo
-{
-	vec3 diffuse;
-#ifdef SPECULARTERM
-	vec3 specular;
-#endif
-};
-
-lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float range, float glossiness, vec3 bumpColor) {
-	lightingInfo result;
-
-	vec3 lightVectorW;
-	float attenuation = 1.0;
-	if (lightData.w == 0.)
-	{
-		vec3 direction = lightData.xyz - vPositionW;
-
-		attenuation = max(0., 1.0 - length(direction) / range);
-		lightVectorW = normalize(direction);
-	}
-	else
-	{
-		lightVectorW = normalize(-lightData.xyz);
-	}
-
-	// diffuse
-	float ndl = max(0., dot(vNormal, lightVectorW));
-	result.diffuse = ndl * diffuseColor * attenuation;
-
-	// Specular
-#ifdef SPECULARTERM
-	vec3 angleW = normalize(viewDirectionW + lightVectorW);
-	vec3 perturbation = bumpHeight * (bumpColor.rgb - 0.5);
-	vec3 halfvec = normalize(angleW + lightVectorW + vec3(perturbation.x, perturbation.y, perturbation.z));
-	
-	float temp = max(0., dot(vNormal, halfvec));
-	temp = pow(temp, max(1., glossiness));
-	
-	result.specular = temp * specularColor * attenuation;
-#endif
-
-	return result;
-}
-
-lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 specularColor, vec3 diffuseColor, float range, float glossiness, vec3 bumpColor) {
-	lightingInfo result;
-
-	vec3 direction = lightData.xyz - vPositionW;
-	vec3 lightVectorW = normalize(direction);
-	float attenuation = max(0., 1.0 - length(direction) / range);
-
-	// diffuse
-	float cosAngle = max(0., dot(-lightDirection.xyz, lightVectorW));
-	float spotAtten = 0.0;
-
-	if (cosAngle >= lightDirection.w)
-	{
-		cosAngle = max(0., pow(cosAngle, lightData.w));
-		spotAtten = clamp((cosAngle - lightDirection.w) / (1. - cosAngle), 0.0, 1.0);
-
-		// Diffuse
-		float ndl = max(0., dot(vNormal, -lightDirection.xyz));
-		result.diffuse = ndl * spotAtten * diffuseColor * attenuation;
-
-		// Specular
-#ifdef SPECULARTERM		
-		vec3 angleW = normalize(viewDirectionW - lightDirection.xyz);
-		vec3 perturbation = bumpHeight * (bumpColor.rgb - 0.5);
-		vec3 halfvec = normalize(angleW + vec3(perturbation.x, perturbation.y, perturbation.z));
-		
-		float temp = max(0., dot(vNormal, halfvec));
-		temp = pow(temp, max(1., glossiness));
-		
-		result.specular = specularColor * temp * spotAtten * attenuation;
-#endif
-		return result;
-	}
-
-	result.diffuse = vec3(0.);
-#ifdef SPECULARTERM
-	result.specular = vec3(0.);
-#endif
-
-	return result;
-}
-
-lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, vec3 groundColor, float glossiness, vec3 bumpColor) {
-	lightingInfo result;
-
-	// Diffuse
-	float ndl = dot(vNormal, lightData.xyz) * 0.5 + 0.5;
-	result.diffuse = mix(groundColor, diffuseColor, ndl);
-	
-	// Specular
-#ifdef SPECULARTERM
-	vec3 angleW = normalize(viewDirectionW + lightData.xyz);
-	vec3 perturbation = bumpHeight * (bumpColor.rgb - 0.5);
-	vec3 halfvec = normalize(angleW + vec3(perturbation.x, perturbation.y, perturbation.z));
-	
-	float temp = max(0.0, dot(vNormal, halfvec));
-	temp = pow(temp, max(1.0, glossiness));
-	
-	result.specular = temp * specularColor;
-#endif
-
-	return result;
-}
+#include<fogFragmentDeclaration>
 
 void main(void) {
 	// Clip plane
-#ifdef CLIPPLANE
-	if (fClipDistance > 0.0)
-		discard;
-#endif
+    #include<clipPlaneFragment>
 
 	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
 
 	// Base color
 	vec4 baseColor = vec4(1., 1., 1., 1.);
 	vec3 diffuseColor = vDiffuseColor.rgb;
-	
-#ifdef SPECULARTERM
-	float glossiness = vSpecularColor.a;
-	vec3 specularColor = vSpecularColor.rgb;
-#else
-	float glossiness = 0.;
-#endif
 
 	// Alpha
 	float alpha = vDiffuseColor.a;
@@ -507,170 +116,18 @@ void main(void) {
 
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
-#ifdef SPECULARTERM
-	vec3 specularBase = vec3(0., 0., 0.);
-#endif
+    lightingInfo info;
 	float shadow = 1.;
-
-#ifdef LIGHT0
-#ifndef SPECULARTERM
-	vec3 vLightSpecular0 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT0
-	lightingInfo info = computeSpotLighting(viewDirectionW, normalW, vLightData0, vLightDirection0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness, bumpColor);
-#endif
-#ifdef HEMILIGHT0
-	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightGround0, glossiness, bumpColor);
-#endif
-#if defined(POINTLIGHT0) || defined(DIRLIGHT0)
-	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness, bumpColor);
-#endif
-#ifdef SHADOW0
-#ifdef SHADOWVSM0
-	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
-#else
-#ifdef SHADOWPCF0
-	#if defined(POINTLIGHT0)
-	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x, shadowsInfo0.y);
-	#else
-	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
-	#endif
-#else
-	#if defined(POINTLIGHT0)
-	shadow = computeShadowCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-	#else
-	shadow = computeShadow(vPositionFromLight0, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-	#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT1
-#ifndef SPECULARTERM
-	vec3 vLightSpecular1 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT1
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness, bumpColor);
-#endif
-#ifdef HEMILIGHT1
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightGround1.a, glossiness, bumpColor);
-#endif
-#if defined(POINTLIGHT1) || defined(DIRLIGHT1)
-	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness, bumpColor);
-#endif
-#ifdef SHADOW1
-#ifdef SHADOWVSM1
-	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
-#else
-#ifdef SHADOWPCF1
-#if defined(POINTLIGHT1)
-	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x, shadowsInfo1.y);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
-#endif
-#else
-	#if defined(POINTLIGHT1)
-	shadow = computeShadowCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-	#else
-	shadow = computeShadow(vPositionFromLight1, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-	#endif
-#endif
-#endif
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT2
-#ifndef SPECULARTERM
-	vec3 vLightSpecular2 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT2
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData2, vLightDirection2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness, bumpColor);
-#endif
-#ifdef HEMILIGHT2
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightGround2, glossiness, bumpColor);
-#endif
-#if defined(POINTLIGHT2) || defined(DIRLIGHT2)
-	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness, bumpColor);
-#endif
-#ifdef SHADOW2
-#ifdef SHADOWVSM2
-	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
-#else
-#ifdef SHADOWPCF2
-#if defined(POINTLIGHT2)
-	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x, shadowsInfo2.y);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
-#endif
-#else
-	#if defined(POINTLIGHT2)
-	shadow = computeShadowCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-	#else
-	shadow = computeShadow(vPositionFromLight2, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-	#endif
-#endif	
-#endif	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
+    
 #ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
-#endif
-
-#ifdef LIGHT3
-#ifndef SPECULARTERM
-	vec3 vLightSpecular3 = vec3(0.0);
-#endif
-#ifdef SPOTLIGHT3
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness, bumpColor);
-#endif
-#ifdef HEMILIGHT3
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightGround3, glossiness, bumpColor);
-#endif
-#if defined(POINTLIGHT3) || defined(DIRLIGHT3)
-	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness, bumpColor);
-#endif
-#ifdef SHADOW3
-#ifdef SHADOWVSM3
-		shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
-#else
-#ifdef SHADOWPCF3
-#if defined(POINTLIGHT3)
-	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x, shadowsInfo3.y);
-#else
-	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
-#endif
-#else
-	#if defined(POINTLIGHT3)
-	shadow = computeShadowCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-	#else
-	shadow = computeShadow(vPositionFromLight3, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-	#endif
-#endif	
-#endif	
+	float glossiness = vSpecularColor.a;
+	vec3 specularBase = vec3(0., 0., 0.);
+    vec3 specularColor = vSpecularColor.rgb;
 #else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#ifdef SPECULARTERM
-	specularBase += info.specular * shadow;
-#endif
+	float glossiness = 0.;
 #endif
+    
+#include<lightFragment>[0..maxSimultaneousLights]
 
 #ifdef VERTEXALPHA
 	alpha *= vColor.a;
@@ -687,10 +144,7 @@ void main(void) {
 	// Composition
 	vec4 color = vec4(finalDiffuse + finalSpecular, alpha);
 
-#ifdef FOG
-	float fog = CalcFogFactor();
-	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
-#endif
+#include<fogFragment>
 	
 	gl_FragColor = color;
 }

+ 13 - 85
materialsLibrary/materials/water/water.vertex.fx

@@ -14,21 +14,11 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#endif
 
-// Uniforms
+#include<bonesDeclaration>
 
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+// Uniforms
+#include<instancesDeclaration>
 
 uniform mat4 view;
 uniform mat4 viewProjection;
@@ -39,10 +29,6 @@ uniform mat4 normalMatrix;
 uniform vec2 vNormalInfos;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -57,33 +43,10 @@ varying vec3 vNormalW;
 varying vec4 vColor;
 #endif
 
-#ifdef CLIPPLANE
-uniform vec4 vClipPlane;
-varying float fClipDistance;
-#endif
+#include<clipPlaneVertexDeclaration>
 
-#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
+#include<fogVertexDeclaration>
+#include<shadowsVertexDeclaration>
 
 // Water uniforms
 uniform mat4 worldReflectionViewProjection;
@@ -100,27 +63,9 @@ varying vec3 vRefractionMapTexCoord;
 varying vec3 vReflectionMapTexCoord;
 
 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
+    #include<instancesVertex>
+    #include<bonesVertex>
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);
 	vPositionW = vec3(worldPos);
@@ -149,31 +94,14 @@ void main(void) {
 #endif
 
 	// Clip plane
-#ifdef CLIPPLANE
-	fClipDistance = dot(worldPos, vClipPlane);
-#endif
+	#include<clipPlaneVertex>
 
 	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
-
+    #include<fogVertex>
+	
 	// 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
-
+    #include<shadowsVertex>
+    
 	// Vertex color
 #ifdef VERTEXCOLOR
 	vColor = color;

+ 1 - 1
src/Actions/babylon.action.js

@@ -126,6 +126,6 @@ var BABYLON;
             };
         };
         return Action;
-    })();
+    }());
     BABYLON.Action = Action;
 })(BABYLON || (BABYLON = {}));

+ 2 - 2
src/Actions/babylon.actionManager.js

@@ -47,7 +47,7 @@ var BABYLON;
             return new ActionEvent(null, scene.pointerX, scene.pointerY, scene.meshUnderPointer, evt);
         };
         return ActionEvent;
-    })();
+    }());
     BABYLON.ActionEvent = ActionEvent;
     /**
      * Action Manager manages all events to be triggered on a given mesh or the global scene.
@@ -519,6 +519,6 @@ var BABYLON;
         ActionManager.DragMovementThreshold = 10; // in pixels
         ActionManager.LongPressDelay = 500; // in milliseconds
         return ActionManager;
-    })();
+    }());
     BABYLON.ActionManager = ActionManager;
 })(BABYLON || (BABYLON = {}));

+ 4 - 4
src/Actions/babylon.condition.js

@@ -29,7 +29,7 @@ var BABYLON;
             };
         };
         return Condition;
-    })();
+    }());
     BABYLON.Condition = Condition;
     var ValueCondition = (function (_super) {
         __extends(ValueCondition, _super);
@@ -117,7 +117,7 @@ var BABYLON;
         ValueCondition._IsGreater = 2;
         ValueCondition._IsLesser = 3;
         return ValueCondition;
-    })(Condition);
+    }(Condition));
     BABYLON.ValueCondition = ValueCondition;
     var PredicateCondition = (function (_super) {
         __extends(PredicateCondition, _super);
@@ -129,7 +129,7 @@ var BABYLON;
             return this.predicate();
         };
         return PredicateCondition;
-    })(Condition);
+    }(Condition));
     BABYLON.PredicateCondition = PredicateCondition;
     var StateCondition = (function (_super) {
         __extends(StateCondition, _super);
@@ -152,6 +152,6 @@ var BABYLON;
             });
         };
         return StateCondition;
-    })(Condition);
+    }(Condition));
     BABYLON.StateCondition = StateCondition;
 })(BABYLON || (BABYLON = {}));

+ 12 - 12
src/Actions/babylon.directActions.js

@@ -29,7 +29,7 @@ var BABYLON;
             }, parent);
         };
         return SwitchBooleanAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.SwitchBooleanAction = SwitchBooleanAction;
     var SetStateAction = (function (_super) {
         __extends(SetStateAction, _super);
@@ -51,7 +51,7 @@ var BABYLON;
             }, parent);
         };
         return SetStateAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.SetStateAction = SetStateAction;
     var SetValueAction = (function (_super) {
         __extends(SetValueAction, _super);
@@ -79,7 +79,7 @@ var BABYLON;
             }, parent);
         };
         return SetValueAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.SetValueAction = SetValueAction;
     var IncrementValueAction = (function (_super) {
         __extends(IncrementValueAction, _super);
@@ -110,7 +110,7 @@ var BABYLON;
             }, parent);
         };
         return IncrementValueAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.IncrementValueAction = IncrementValueAction;
     var PlayAnimationAction = (function (_super) {
         __extends(PlayAnimationAction, _super);
@@ -139,7 +139,7 @@ var BABYLON;
             }, parent);
         };
         return PlayAnimationAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.PlayAnimationAction = PlayAnimationAction;
     var StopAnimationAction = (function (_super) {
         __extends(StopAnimationAction, _super);
@@ -160,7 +160,7 @@ var BABYLON;
             }, parent);
         };
         return StopAnimationAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.StopAnimationAction = StopAnimationAction;
     var DoNothingAction = (function (_super) {
         __extends(DoNothingAction, _super);
@@ -177,7 +177,7 @@ var BABYLON;
             }, parent);
         };
         return DoNothingAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.DoNothingAction = DoNothingAction;
     var CombineAction = (function (_super) {
         __extends(CombineAction, _super);
@@ -208,7 +208,7 @@ var BABYLON;
             return serializationObject;
         };
         return CombineAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.CombineAction = CombineAction;
     var ExecuteCodeAction = (function (_super) {
         __extends(ExecuteCodeAction, _super);
@@ -220,7 +220,7 @@ var BABYLON;
             this.func(evt);
         };
         return ExecuteCodeAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.ExecuteCodeAction = ExecuteCodeAction;
     var SetParentAction = (function (_super) {
         __extends(SetParentAction, _super);
@@ -250,7 +250,7 @@ var BABYLON;
             }, parent);
         };
         return SetParentAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.SetParentAction = SetParentAction;
     var PlaySoundAction = (function (_super) {
         __extends(PlaySoundAction, _super);
@@ -271,7 +271,7 @@ var BABYLON;
             }, parent);
         };
         return PlaySoundAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.PlaySoundAction = PlaySoundAction;
     var StopSoundAction = (function (_super) {
         __extends(StopSoundAction, _super);
@@ -292,6 +292,6 @@ var BABYLON;
             }, parent);
         };
         return StopSoundAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.StopSoundAction = StopSoundAction;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Actions/babylon.interpolateValueAction.js

@@ -72,6 +72,6 @@ var BABYLON;
             }, parent);
         };
         return InterpolateValueAction;
-    })(BABYLON.Action);
+    }(BABYLON.Action));
     BABYLON.InterpolateValueAction = InterpolateValueAction;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Animations/babylon.animatable.js

@@ -127,6 +127,6 @@ var BABYLON;
             return running;
         };
         return Animatable;
-    })();
+    }());
     BABYLON.Animatable = Animatable;
 })(BABYLON || (BABYLON = {}));

+ 4 - 4
src/Animations/babylon.animation.js

@@ -10,7 +10,7 @@ var BABYLON;
             return new AnimationRange(this.name, this.from, this.to);
         };
         return AnimationRange;
-    })();
+    }());
     BABYLON.AnimationRange = AnimationRange;
     /**
      * Composed of a frame, and an action function
@@ -23,7 +23,7 @@ var BABYLON;
             this.isDone = false;
         }
         return AnimationEvent;
-    })();
+    }());
     BABYLON.AnimationEvent = AnimationEvent;
     var PathCursor = (function () {
         function PathCursor(path) {
@@ -80,7 +80,7 @@ var BABYLON;
             return this;
         };
         return PathCursor;
-    })();
+    }());
     BABYLON.PathCursor = PathCursor;
     var Animation = (function () {
         function Animation(name, targetProperty, framePerSecond, dataType, loopMode, enableBlending) {
@@ -706,6 +706,6 @@ var BABYLON;
         Animation._ANIMATIONLOOPMODE_CYCLE = 1;
         Animation._ANIMATIONLOOPMODE_CONSTANT = 2;
         return Animation;
-    })();
+    }());
     BABYLON.Animation = Animation;
 })(BABYLON || (BABYLON = {}));

+ 13 - 13
src/Animations/babylon.easing.js

@@ -58,7 +58,7 @@ var BABYLON;
         EasingFunction._EASINGMODE_EASEOUT = 1;
         EasingFunction._EASINGMODE_EASEINOUT = 2;
         return EasingFunction;
-    })();
+    }());
     BABYLON.EasingFunction = EasingFunction;
     var CircleEase = (function (_super) {
         __extends(CircleEase, _super);
@@ -70,7 +70,7 @@ var BABYLON;
             return (1.0 - Math.sqrt(1.0 - (gradient * gradient)));
         };
         return CircleEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.CircleEase = CircleEase;
     var BackEase = (function (_super) {
         __extends(BackEase, _super);
@@ -84,7 +84,7 @@ var BABYLON;
             return (Math.pow(gradient, 3.0) - ((gradient * num) * Math.sin(3.1415926535897931 * gradient)));
         };
         return BackEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.BackEase = BackEase;
     var BounceEase = (function (_super) {
         __extends(BounceEase, _super);
@@ -116,7 +116,7 @@ var BABYLON;
             return (((-Math.pow(1.0 / bounciness, y - num3) / (num2 * num2)) * (num6 - num2)) * (num6 + num2));
         };
         return BounceEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.BounceEase = BounceEase;
     var CubicEase = (function (_super) {
         __extends(CubicEase, _super);
@@ -127,7 +127,7 @@ var BABYLON;
             return (gradient * gradient * gradient);
         };
         return CubicEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.CubicEase = CubicEase;
     var ElasticEase = (function (_super) {
         __extends(ElasticEase, _super);
@@ -151,7 +151,7 @@ var BABYLON;
             return (num2 * Math.sin(((6.2831853071795862 * num3) + 1.5707963267948966) * gradient));
         };
         return ElasticEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.ElasticEase = ElasticEase;
     var ExponentialEase = (function (_super) {
         __extends(ExponentialEase, _super);
@@ -167,7 +167,7 @@ var BABYLON;
             return ((Math.exp(this.exponent * gradient) - 1.0) / (Math.exp(this.exponent) - 1.0));
         };
         return ExponentialEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.ExponentialEase = ExponentialEase;
     var PowerEase = (function (_super) {
         __extends(PowerEase, _super);
@@ -181,7 +181,7 @@ var BABYLON;
             return Math.pow(gradient, y);
         };
         return PowerEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.PowerEase = PowerEase;
     var QuadraticEase = (function (_super) {
         __extends(QuadraticEase, _super);
@@ -192,7 +192,7 @@ var BABYLON;
             return (gradient * gradient);
         };
         return QuadraticEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.QuadraticEase = QuadraticEase;
     var QuarticEase = (function (_super) {
         __extends(QuarticEase, _super);
@@ -203,7 +203,7 @@ var BABYLON;
             return (gradient * gradient * gradient * gradient);
         };
         return QuarticEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.QuarticEase = QuarticEase;
     var QuinticEase = (function (_super) {
         __extends(QuinticEase, _super);
@@ -214,7 +214,7 @@ var BABYLON;
             return (gradient * gradient * gradient * gradient * gradient);
         };
         return QuinticEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.QuinticEase = QuinticEase;
     var SineEase = (function (_super) {
         __extends(SineEase, _super);
@@ -225,7 +225,7 @@ var BABYLON;
             return (1.0 - Math.sin(1.5707963267948966 * (1.0 - gradient)));
         };
         return SineEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.SineEase = SineEase;
     var BezierCurveEase = (function (_super) {
         __extends(BezierCurveEase, _super);
@@ -244,6 +244,6 @@ var BABYLON;
             return BABYLON.BezierCurve.interpolate(gradient, this.x1, this.y1, this.x2, this.y2);
         };
         return BezierCurveEase;
-    })(EasingFunction);
+    }(EasingFunction));
     BABYLON.BezierCurveEase = BezierCurveEase;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Audio/babylon.analyser.js

@@ -106,6 +106,6 @@ var BABYLON;
             }
         };
         return Analyser;
-    })();
+    }());
     BABYLON.Analyser = Analyser;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Audio/babylon.audioEngine.js

@@ -101,6 +101,6 @@ var BABYLON;
             }
         };
         return AudioEngine;
-    })();
+    }());
     BABYLON.AudioEngine = AudioEngine;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Audio/babylon.sound.js

@@ -547,6 +547,6 @@ var BABYLON;
             return newSound;
         };
         return Sound;
-    })();
+    }());
     BABYLON.Sound = Sound;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Audio/babylon.soundtrack.js

@@ -96,6 +96,6 @@ var BABYLON;
             }
         };
         return SoundTrack;
-    })();
+    }());
     BABYLON.SoundTrack = SoundTrack;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Bones/babylon.bone.js

@@ -124,6 +124,6 @@ var BABYLON;
             return true;
         };
         return Bone;
-    })(BABYLON.Node);
+    }(BABYLON.Node));
     BABYLON.Bone = Bone;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Bones/babylon.skeleton.js

@@ -329,6 +329,6 @@ var BABYLON;
             return skeleton;
         };
         return Skeleton;
-    })();
+    }());
     BABYLON.Skeleton = Skeleton;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.arcrotatecamera.input.gamepad.js

@@ -65,7 +65,7 @@ var BABYLON;
             BABYLON.serialize()
         ], ArcRotateCameraGamepadInput.prototype, "gamepadMoveSensibility", void 0);
         return ArcRotateCameraGamepadInput;
-    })();
+    }());
     BABYLON.ArcRotateCameraGamepadInput = ArcRotateCameraGamepadInput;
     BABYLON.CameraInputTypes["ArcRotateCameraGamepadInput"] = ArcRotateCameraGamepadInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.arcrotatecamera.input.keyboard.js

@@ -107,7 +107,7 @@ var BABYLON;
             BABYLON.serialize()
         ], ArcRotateCameraKeyboardMoveInput.prototype, "keysRight", void 0);
         return ArcRotateCameraKeyboardMoveInput;
-    })();
+    }());
     BABYLON.ArcRotateCameraKeyboardMoveInput = ArcRotateCameraKeyboardMoveInput;
     BABYLON.CameraInputTypes["ArcRotateCameraKeyboardMoveInput"] = ArcRotateCameraKeyboardMoveInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.arcrotatecamera.input.mousewheel.js

@@ -51,7 +51,7 @@ var BABYLON;
             BABYLON.serialize()
         ], ArcRotateCameraMouseWheelInput.prototype, "wheelPrecision", void 0);
         return ArcRotateCameraMouseWheelInput;
-    })();
+    }());
     BABYLON.ArcRotateCameraMouseWheelInput = ArcRotateCameraMouseWheelInput;
     BABYLON.CameraInputTypes["ArcRotateCameraMouseWheelInput"] = ArcRotateCameraMouseWheelInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.js

@@ -213,7 +213,7 @@ var BABYLON;
             BABYLON.serialize()
         ], ArcRotateCameraPointersInput.prototype, "panningSensibility", void 0);
         return ArcRotateCameraPointersInput;
-    })();
+    }());
     BABYLON.ArcRotateCameraPointersInput = ArcRotateCameraPointersInput;
     BABYLON.CameraInputTypes["ArcRotateCameraPointersInput"] = ArcRotateCameraPointersInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.arcrotatecamera.input.vrdeviceorientation.js

@@ -42,7 +42,7 @@ var BABYLON;
             return "VRDeviceOrientation";
         };
         return ArcRotateCameraVRDeviceOrientationInput;
-    })();
+    }());
     BABYLON.ArcRotateCameraVRDeviceOrientationInput = ArcRotateCameraVRDeviceOrientationInput;
     BABYLON.CameraInputTypes["ArcRotateCameraVRDeviceOrientationInput"] = ArcRotateCameraVRDeviceOrientationInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.deviceorientation.js

@@ -70,7 +70,7 @@ var BABYLON;
             BABYLON.serialize()
         ], FreeCameraDeviceOrientationInput.prototype, "moveSensibility", void 0);
         return FreeCameraDeviceOrientationInput;
-    })();
+    }());
     BABYLON.FreeCameraDeviceOrientationInput = FreeCameraDeviceOrientationInput;
     BABYLON.CameraInputTypes["FreeCameraDeviceOrientationInput"] = FreeCameraDeviceOrientationInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.gamepad.js

@@ -60,7 +60,7 @@ var BABYLON;
             BABYLON.serialize()
         ], FreeCameraGamepadInput.prototype, "gamepadMoveSensibility", void 0);
         return FreeCameraGamepadInput;
-    })();
+    }());
     BABYLON.FreeCameraGamepadInput = FreeCameraGamepadInput;
     BABYLON.CameraInputTypes["FreeCameraGamepadInput"] = FreeCameraGamepadInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.keyboard.js

@@ -111,7 +111,7 @@ var BABYLON;
             BABYLON.serialize()
         ], FreeCameraKeyboardMoveInput.prototype, "keysRight", void 0);
         return FreeCameraKeyboardMoveInput;
-    })();
+    }());
     BABYLON.FreeCameraKeyboardMoveInput = FreeCameraKeyboardMoveInput;
     BABYLON.CameraInputTypes["FreeCameraKeyboardMoveInput"] = FreeCameraKeyboardMoveInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.mouse.js

@@ -92,7 +92,7 @@ var BABYLON;
             BABYLON.serialize()
         ], FreeCameraMouseInput.prototype, "angularSensibility", void 0);
         return FreeCameraMouseInput;
-    })();
+    }());
     BABYLON.FreeCameraMouseInput = FreeCameraMouseInput;
     BABYLON.CameraInputTypes["FreeCameraMouseInput"] = FreeCameraMouseInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.touch.js

@@ -116,7 +116,7 @@ var BABYLON;
             BABYLON.serialize()
         ], FreeCameraTouchInput.prototype, "touchMoveSensibility", void 0);
         return FreeCameraTouchInput;
-    })();
+    }());
     BABYLON.FreeCameraTouchInput = FreeCameraTouchInput;
     BABYLON.CameraInputTypes["FreeCameraTouchInput"] = FreeCameraTouchInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.virtualjoystick.js

@@ -48,7 +48,7 @@ var BABYLON;
             return "virtualJoystick";
         };
         return FreeCameraVirtualJoystickInput;
-    })();
+    }());
     BABYLON.FreeCameraVirtualJoystickInput = FreeCameraVirtualJoystickInput;
     BABYLON.CameraInputTypes["FreeCameraVirtualJoystickInput"] = FreeCameraVirtualJoystickInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/Inputs/babylon.freecamera.input.vrdeviceorientation.js

@@ -47,7 +47,7 @@ var BABYLON;
             return "VRDeviceOrientation";
         };
         return FreeCameraVRDeviceOrientationInput;
-    })();
+    }());
     BABYLON.FreeCameraVRDeviceOrientationInput = FreeCameraVRDeviceOrientationInput;
     BABYLON.CameraInputTypes["FreeCameraVRDeviceOrientationInput"] = FreeCameraVRDeviceOrientationInput;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/VR/babylon.vrCameraMetrics.js

@@ -67,6 +67,6 @@ var BABYLON;
             return result;
         };
         return VRCameraMetrics;
-    })();
+    }());
     BABYLON.VRCameraMetrics = VRCameraMetrics;
 })(BABYLON || (BABYLON = {}));

+ 2 - 2
src/Cameras/VR/babylon.vrDeviceOrientationCamera.js

@@ -19,7 +19,7 @@ var BABYLON;
             return "VRDeviceOrientationFreeCamera";
         };
         return VRDeviceOrientationFreeCamera;
-    })(BABYLON.FreeCamera);
+    }(BABYLON.FreeCamera));
     BABYLON.VRDeviceOrientationFreeCamera = VRDeviceOrientationFreeCamera;
     var VRDeviceOrientationArcRotateCamera = (function (_super) {
         __extends(VRDeviceOrientationArcRotateCamera, _super);
@@ -35,6 +35,6 @@ var BABYLON;
             return "VRDeviceOrientationArcRotateCamera";
         };
         return VRDeviceOrientationArcRotateCamera;
-    })(BABYLON.ArcRotateCamera);
+    }(BABYLON.ArcRotateCamera));
     BABYLON.VRDeviceOrientationArcRotateCamera = VRDeviceOrientationArcRotateCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/VR/babylon.webVRCamera.js

@@ -72,6 +72,6 @@ var BABYLON;
             return "WebVRFreeCamera";
         };
         return WebVRFreeCamera;
-    })(BABYLON.FreeCamera);
+    }(BABYLON.FreeCamera));
     BABYLON.WebVRFreeCamera = WebVRFreeCamera;
 })(BABYLON || (BABYLON = {}));

+ 18 - 12
src/Cameras/babylon.arcRotateCamera.js

@@ -440,36 +440,42 @@ var BABYLON;
          * Override Camera.createRigCamera
          */
         ArcRotateCamera.prototype.createRigCamera = function (name, cameraIndex) {
+            var alphaShift;
             switch (this.cameraRigMode) {
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
-                case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
                 case BABYLON.Camera.RIG_MODE_VR:
-                    var alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);
-                    var rigCam = new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this.target, this.getScene());
-                    rigCam._cameraRigParams = {};
-                    return rigCam;
+                    alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);
+                    break;
+                case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
+                    alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? -1 : 1);
+                    break;
             }
-            return null;
+            var rigCam = new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this.target, this.getScene());
+            rigCam._cameraRigParams = {};
+            return rigCam;
         };
         /**
          * @override
          * Override Camera._updateRigCameras
          */
         ArcRotateCamera.prototype._updateRigCameras = function () {
+            var camLeft = this._rigCameras[0];
+            var camRight = this._rigCameras[1];
+            camLeft.beta = camRight.beta = this.beta;
+            camLeft.radius = camRight.radius = this.radius;
             switch (this.cameraRigMode) {
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
-                case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
                 case BABYLON.Camera.RIG_MODE_VR:
-                    var camLeft = this._rigCameras[0];
-                    var camRight = this._rigCameras[1];
                     camLeft.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;
                     camRight.alpha = this.alpha + this._cameraRigParams.stereoHalfAngle;
-                    camLeft.beta = camRight.beta = this.beta;
-                    camLeft.radius = camRight.radius = this.radius;
+                    break;
+                case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
+                    camLeft.alpha = this.alpha + this._cameraRigParams.stereoHalfAngle;
+                    camRight.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;
                     break;
             }
             _super.prototype._updateRigCameras.call(this);
@@ -533,6 +539,6 @@ var BABYLON;
             BABYLON.serialize()
         ], ArcRotateCamera.prototype, "allowUpsideDown", void 0);
         return ArcRotateCamera;
-    })(BABYLON.TargetCamera);
+    }(BABYLON.TargetCamera));
     BABYLON.ArcRotateCamera = ArcRotateCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.arcRotateCameraInputsManager.js

@@ -31,6 +31,6 @@ var BABYLON;
             return this;
         };
         return ArcRotateCameraInputsManager;
-    })(BABYLON.CameraInputsManager);
+    }(BABYLON.CameraInputsManager));
     BABYLON.ArcRotateCameraInputsManager = ArcRotateCameraInputsManager;
 })(BABYLON || (BABYLON = {}));

+ 58 - 82
src/Cameras/babylon.camera.js

@@ -36,7 +36,6 @@ var BABYLON;
             this._computedViewMatrix = BABYLON.Matrix.Identity();
             this._projectionMatrix = new BABYLON.Matrix();
             this._postProcesses = new Array();
-            this._postProcessesTakenIndices = [];
             this._activeMeshes = new BABYLON.SmartArray(256);
             this._globalPosition = BABYLON.Vector3.Zero();
             scene.addCamera(this);
@@ -229,6 +228,27 @@ var BABYLON;
         };
         Camera.prototype._checkInputs = function () {
         };
+        Camera.prototype._cascadePostProcessesToRigCams = function () {
+            // invalidate framebuffer
+            if (this._postProcesses.length > 0) {
+                this._postProcesses[0].markTextureDirty();
+            }
+            // glue the rigPostProcess to the end of the user postprocesses & assign to each sub-camera
+            for (var i = 0, len = this._rigCameras.length; i < len; i++) {
+                var cam = this._rigCameras[i];
+                var rigPostProcess = cam._rigPostProcess;
+                // for VR rig, there does not have to be a post process 
+                if (rigPostProcess) {
+                    var isPass = rigPostProcess instanceof BABYLON.PassPostProcess;
+                    if (isPass) {
+                        // any rig which has a PassPostProcess for rig[0], cannot be isIntermediate when there are also user postProcesses
+                        cam.isIntermediate = this._postProcesses.length === 0;
+                    }
+                    cam._postProcesses = this._postProcesses.slice(0).concat(rigPostProcess);
+                    rigPostProcess.markTextureDirty();
+                }
+            }
+        };
         Camera.prototype.attachPostProcess = function (postProcess, insertAt) {
             if (insertAt === void 0) { insertAt = null; }
             if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {
@@ -237,36 +257,12 @@ var BABYLON;
             }
             if (insertAt == null || insertAt < 0) {
                 this._postProcesses.push(postProcess);
-                this._postProcessesTakenIndices.push(this._postProcesses.length - 1);
-                return this._postProcesses.length - 1;
-            }
-            var add = 0;
-            var i;
-            var start;
-            if (this._postProcesses[insertAt]) {
-                start = this._postProcesses.length - 1;
-                for (i = start; i >= insertAt + 1; --i) {
-                    this._postProcesses[i + 1] = this._postProcesses[i];
-                }
-                add = 1;
-            }
-            for (i = 0; i < this._postProcessesTakenIndices.length; ++i) {
-                if (this._postProcessesTakenIndices[i] < insertAt) {
-                    continue;
-                }
-                start = this._postProcessesTakenIndices.length - 1;
-                for (var j = start; j >= i; --j) {
-                    this._postProcessesTakenIndices[j + 1] = this._postProcessesTakenIndices[j] + add;
-                }
-                this._postProcessesTakenIndices[i] = insertAt;
-                break;
             }
-            if (!add && this._postProcessesTakenIndices.indexOf(insertAt) === -1) {
-                this._postProcessesTakenIndices.push(insertAt);
+            else {
+                this._postProcesses.splice(insertAt, 0, postProcess);
             }
-            var result = insertAt + add;
-            this._postProcesses[result] = postProcess;
-            return result;
+            this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated            
+            return this._postProcesses.indexOf(postProcess);
         };
         Camera.prototype.detachPostProcess = function (postProcess, atIndices) {
             if (atIndices === void 0) { atIndices = null; }
@@ -274,29 +270,23 @@ var BABYLON;
             var i;
             var index;
             if (!atIndices) {
-                var length = this._postProcesses.length;
-                for (i = 0; i < length; i++) {
-                    if (this._postProcesses[i] !== postProcess) {
-                        continue;
-                    }
-                    delete this._postProcesses[i];
-                    index = this._postProcessesTakenIndices.indexOf(i);
-                    this._postProcessesTakenIndices.splice(index, 1);
+                var idx = this._postProcesses.indexOf(postProcess);
+                if (idx !== -1) {
+                    this._postProcesses.splice(idx, 1);
                 }
             }
             else {
                 atIndices = (atIndices instanceof Array) ? atIndices : [atIndices];
-                for (i = 0; i < atIndices.length; i++) {
-                    var foundPostProcess = this._postProcesses[atIndices[i]];
-                    if (foundPostProcess !== postProcess) {
+                // iterate descending, so can just splice as we go
+                for (i = atIndices.length - 1; i >= 0; i--) {
+                    if (this._postProcesses[atIndices[i]] !== postProcess) {
                         result.push(i);
                         continue;
                     }
-                    delete this._postProcesses[atIndices[i]];
-                    index = this._postProcessesTakenIndices.indexOf(atIndices[i]);
-                    this._postProcessesTakenIndices.splice(index, 1);
+                    this._postProcesses.splice(index, 1);
                 }
             }
+            this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated
             return result;
         };
         Camera.prototype.getWorldMatrix = function () {
@@ -365,8 +355,8 @@ var BABYLON;
                 this._rigCameras.pop().dispose();
             }
             // Postprocesses
-            for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {
-                this._postProcesses[this._postProcessesTakenIndices[i]].dispose(this);
+            for (var i = 0; i < this._postProcesses.length; ++i) {
+                this._postProcesses[i].dispose(this);
             }
             _super.prototype.dispose.call(this);
         };
@@ -377,44 +367,28 @@ var BABYLON;
             }
             this.cameraRigMode = mode;
             this._cameraRigParams = {};
-            switch (this.cameraRigMode) {
-                case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
-                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
-                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
-                case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
-                    this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
-                    //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target, 
-                    //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
-                    this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
-                    this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
-                    this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
-                    break;
+            //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target, 
+            //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
+            this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
+            this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
+            // create the rig cameras, unless none
+            if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {
+                this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
+                this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
             }
-            var postProcesses = new Array();
             switch (this.cameraRigMode) {
                 case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
-                    postProcesses.push(new BABYLON.PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]));
-                    this._rigCameras[0].isIntermediate = true;
-                    postProcesses.push(new BABYLON.AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras[1]));
-                    postProcesses[1].onApply = function (effect) {
-                        effect.setTextureFromPostProcess("leftSampler", postProcesses[0]);
-                    };
+                    this._rigCameras[0]._rigPostProcess = new BABYLON.PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
+                    this._rigCameras[1]._rigPostProcess = new BABYLON.AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras);
                     break;
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
-                    var isStereoscopicHoriz = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED);
-                    var firstCamIndex = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : 0;
-                    var secondCamIndex = 1 - firstCamIndex;
-                    postProcesses.push(new BABYLON.PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[firstCamIndex]));
-                    this._rigCameras[firstCamIndex].isIntermediate = true;
-                    postProcesses.push(new BABYLON.StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras[secondCamIndex], postProcesses[0], isStereoscopicHoriz));
+                    var isStereoscopicHoriz = this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
+                    this._rigCameras[0]._rigPostProcess = new BABYLON.PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
+                    this._rigCameras[1]._rigPostProcess = new BABYLON.StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras, isStereoscopicHoriz);
                     break;
                 case Camera.RIG_MODE_VR:
-                    this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
-                    this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
-                    this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
-                    this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
                     var metrics = rigParams.vrCameraMetrics || BABYLON.VRCameraMetrics.GetDefault();
                     this._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
                     this._rigCameras[0].viewport = new BABYLON.Viewport(0, 0, 0.5, 1.0);
@@ -422,20 +396,19 @@ var BABYLON;
                     this._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
                     this._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
                     this._rigCameras[0].getProjectionMatrix = this._rigCameras[0]._getVRProjectionMatrix;
-                    if (metrics.compensateDistortion) {
-                        postProcesses.push(new BABYLON.VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics));
-                    }
-                    this._rigCameras[1]._cameraRigParams.vrMetrics = this._rigCameras[0]._cameraRigParams.vrMetrics;
+                    this._rigCameras[1]._cameraRigParams.vrMetrics = metrics;
                     this._rigCameras[1].viewport = new BABYLON.Viewport(0.5, 0, 0.5, 1.0);
                     this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new BABYLON.Matrix();
                     this._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
                     this._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
                     this._rigCameras[1].getProjectionMatrix = this._rigCameras[1]._getVRProjectionMatrix;
                     if (metrics.compensateDistortion) {
-                        postProcesses.push(new BABYLON.VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics));
+                        this._rigCameras[0]._rigPostProcess = new BABYLON.VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics);
+                        this._rigCameras[1]._rigPostProcess = new BABYLON.VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics);
                     }
                     break;
             }
+            this._cascadePostProcessesToRigCams();
             this._update();
         };
         Camera.prototype._getVRProjectionMatrix = function () {
@@ -444,6 +417,9 @@ var BABYLON;
             return this._projectionMatrix;
         };
         Camera.prototype.setCameraRigParameter = function (name, value) {
+            if (!this._cameraRigParams) {
+                this._cameraRigParams = {};
+            }
             this._cameraRigParams[name] = value;
             //provisionnally:
             if (name === "interaxialDistance") {
@@ -451,13 +427,13 @@ var BABYLON;
             }
         };
         /**
-         * May needs to be overridden by children so sub has required properties to be copied
+         * needs to be overridden by children so sub has required properties to be copied
          */
         Camera.prototype.createRigCamera = function (name, cameraIndex) {
             return null;
         };
         /**
-         * May needs to be overridden by children
+         * May need to be overridden by children
          */
         Camera.prototype._updateRigCameras = function () {
             for (var i = 0; i < this._rigCameras.length; i++) {
@@ -636,6 +612,6 @@ var BABYLON;
             BABYLON.serialize()
         ], Camera.prototype, "isStereoscopicSideBySide", void 0);
         return Camera;
-    })(BABYLON.Node);
+    }(BABYLON.Node));
     BABYLON.Camera = Camera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.cameraInputsManager.js

@@ -128,6 +128,6 @@ var BABYLON;
             }
         };
         return CameraInputsManager;
-    })();
+    }());
     BABYLON.CameraInputsManager = CameraInputsManager;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.deviceOrientationCamera.js

@@ -46,6 +46,6 @@ var BABYLON;
             return "DeviceOrientationCamera";
         };
         return DeviceOrientationCamera;
-    })(BABYLON.FreeCamera);
+    }(BABYLON.FreeCamera));
     BABYLON.DeviceOrientationCamera = DeviceOrientationCamera;
 })(BABYLON || (BABYLON = {}));

+ 2 - 2
src/Cameras/babylon.followCamera.js

@@ -84,7 +84,7 @@ var BABYLON;
             BABYLON.serializeAsMeshReference("lockedTargetId")
         ], FollowCamera.prototype, "target", void 0);
         return FollowCamera;
-    })(BABYLON.TargetCamera);
+    }(BABYLON.TargetCamera));
     BABYLON.FollowCamera = FollowCamera;
     var ArcFollowCamera = (function (_super) {
         __extends(ArcFollowCamera, _super);
@@ -112,6 +112,6 @@ var BABYLON;
             return "ArcFollowCamera";
         };
         return ArcFollowCamera;
-    })(BABYLON.TargetCamera);
+    }(BABYLON.TargetCamera));
     BABYLON.ArcFollowCamera = ArcFollowCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.freeCamera.js

@@ -180,6 +180,6 @@ var BABYLON;
             BABYLON.serialize()
         ], FreeCamera.prototype, "applyGravity", void 0);
         return FreeCamera;
-    })(BABYLON.TargetCamera);
+    }(BABYLON.TargetCamera));
     BABYLON.FreeCamera = FreeCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.freeCameraInputsManager.js

@@ -40,6 +40,6 @@ var BABYLON;
             return this;
         };
         return FreeCameraInputsManager;
-    })(BABYLON.CameraInputsManager);
+    }(BABYLON.CameraInputsManager));
     BABYLON.FreeCameraInputsManager = FreeCameraInputsManager;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.gamepadCamera.js

@@ -46,6 +46,6 @@ var BABYLON;
             return "GamepadCamera";
         };
         return GamepadCamera;
-    })(BABYLON.UniversalCamera);
+    }(BABYLON.UniversalCamera));
     BABYLON.GamepadCamera = GamepadCamera;
 })(BABYLON || (BABYLON = {}));

+ 8 - 8
src/Cameras/babylon.stereoscopicCameras.js

@@ -16,7 +16,7 @@ var BABYLON;
             return "AnaglyphFreeCamera";
         };
         return AnaglyphFreeCamera;
-    })(BABYLON.FreeCamera);
+    }(BABYLON.FreeCamera));
     BABYLON.AnaglyphFreeCamera = AnaglyphFreeCamera;
     var AnaglyphArcRotateCamera = (function (_super) {
         __extends(AnaglyphArcRotateCamera, _super);
@@ -29,7 +29,7 @@ var BABYLON;
             return "AnaglyphArcRotateCamera";
         };
         return AnaglyphArcRotateCamera;
-    })(BABYLON.ArcRotateCamera);
+    }(BABYLON.ArcRotateCamera));
     BABYLON.AnaglyphArcRotateCamera = AnaglyphArcRotateCamera;
     var AnaglyphGamepadCamera = (function (_super) {
         __extends(AnaglyphGamepadCamera, _super);
@@ -42,7 +42,7 @@ var BABYLON;
             return "AnaglyphGamepadCamera";
         };
         return AnaglyphGamepadCamera;
-    })(BABYLON.GamepadCamera);
+    }(BABYLON.GamepadCamera));
     BABYLON.AnaglyphGamepadCamera = AnaglyphGamepadCamera;
     var AnaglyphUniversalCamera = (function (_super) {
         __extends(AnaglyphUniversalCamera, _super);
@@ -55,7 +55,7 @@ var BABYLON;
             return "AnaglyphUniversalCamera";
         };
         return AnaglyphUniversalCamera;
-    })(BABYLON.UniversalCamera);
+    }(BABYLON.UniversalCamera));
     BABYLON.AnaglyphUniversalCamera = AnaglyphUniversalCamera;
     var StereoscopicFreeCamera = (function (_super) {
         __extends(StereoscopicFreeCamera, _super);
@@ -69,7 +69,7 @@ var BABYLON;
             return "StereoscopicFreeCamera";
         };
         return StereoscopicFreeCamera;
-    })(BABYLON.FreeCamera);
+    }(BABYLON.FreeCamera));
     BABYLON.StereoscopicFreeCamera = StereoscopicFreeCamera;
     var StereoscopicArcRotateCamera = (function (_super) {
         __extends(StereoscopicArcRotateCamera, _super);
@@ -83,7 +83,7 @@ var BABYLON;
             return "StereoscopicArcRotateCamera";
         };
         return StereoscopicArcRotateCamera;
-    })(BABYLON.ArcRotateCamera);
+    }(BABYLON.ArcRotateCamera));
     BABYLON.StereoscopicArcRotateCamera = StereoscopicArcRotateCamera;
     var StereoscopicGamepadCamera = (function (_super) {
         __extends(StereoscopicGamepadCamera, _super);
@@ -97,7 +97,7 @@ var BABYLON;
             return "StereoscopicGamepadCamera";
         };
         return StereoscopicGamepadCamera;
-    })(BABYLON.GamepadCamera);
+    }(BABYLON.GamepadCamera));
     BABYLON.StereoscopicGamepadCamera = StereoscopicGamepadCamera;
     var StereoscopicUniversalCamera = (function (_super) {
         __extends(StereoscopicUniversalCamera, _super);
@@ -111,6 +111,6 @@ var BABYLON;
             return "StereoscopicUniversalCamera";
         };
         return StereoscopicUniversalCamera;
-    })(BABYLON.UniversalCamera);
+    }(BABYLON.UniversalCamera));
     BABYLON.StereoscopicUniversalCamera = StereoscopicUniversalCamera;
 })(BABYLON || (BABYLON = {}));

+ 16 - 17
src/Cameras/babylon.targetCamera.js

@@ -211,28 +211,27 @@ var BABYLON;
          * Override Camera._updateRigCameras
          */
         TargetCamera.prototype._updateRigCameras = function () {
+            var camLeft = this._rigCameras[0];
+            var camRight = this._rigCameras[1];
             switch (this.cameraRigMode) {
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
+                    //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
+                    var leftSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
+                    var rightSign = (this.cameraRigMode === BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
+                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft.position);
+                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * rightSign, camRight.position);
+                    camLeft.setTarget(this.getTarget());
+                    camRight.setTarget(this.getTarget());
+                    break;
                 case BABYLON.Camera.RIG_MODE_VR:
-                    var camLeft = this._rigCameras[0];
-                    var camRight = this._rigCameras[1];
-                    if (this.cameraRigMode === BABYLON.Camera.RIG_MODE_VR) {
-                        camLeft.rotation.x = camRight.rotation.x = this.rotation.x;
-                        camLeft.rotation.y = camRight.rotation.y = this.rotation.y;
-                        camLeft.rotation.z = camRight.rotation.z = this.rotation.z;
-                        camLeft.position.copyFrom(this.position);
-                        camRight.position.copyFrom(this.position);
-                    }
-                    else {
-                        //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
-                        this._getRigCamPosition(-this._cameraRigParams.stereoHalfAngle, camLeft.position);
-                        this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle, camRight.position);
-                        camLeft.setTarget(this.getTarget());
-                        camRight.setTarget(this.getTarget());
-                    }
+                    camLeft.rotation.x = camRight.rotation.x = this.rotation.x;
+                    camLeft.rotation.y = camRight.rotation.y = this.rotation.y;
+                    camLeft.rotation.z = camRight.rotation.z = this.rotation.z;
+                    camLeft.position.copyFrom(this.position);
+                    camRight.position.copyFrom(this.position);
                     break;
             }
             _super.prototype._updateRigCameras.call(this);
@@ -259,6 +258,6 @@ var BABYLON;
             BABYLON.serializeAsMeshReference("lockedTargetId")
         ], TargetCamera.prototype, "lockedTarget", void 0);
         return TargetCamera;
-    })(BABYLON.Camera);
+    }(BABYLON.Camera));
     BABYLON.TargetCamera = TargetCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.touchCamera.js

@@ -53,6 +53,6 @@ var BABYLON;
             }
         };
         return TouchCamera;
-    })(BABYLON.FreeCamera);
+    }(BABYLON.FreeCamera));
     BABYLON.TouchCamera = TouchCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.universalCamera.js

@@ -46,6 +46,6 @@ var BABYLON;
             return "UniversalCamera";
         };
         return UniversalCamera;
-    })(BABYLON.TouchCamera);
+    }(BABYLON.TouchCamera));
     BABYLON.UniversalCamera = UniversalCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Cameras/babylon.virtualJoysticksCamera.js

@@ -13,6 +13,6 @@ var BABYLON;
             this.inputs.addVirtualJoystick();
         }
         return VirtualJoysticksCamera;
-    })(BABYLON.FreeCamera);
+    }(BABYLON.FreeCamera));
     BABYLON.VirtualJoysticksCamera = VirtualJoysticksCamera;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Collisions/babylon.collider.js

@@ -267,6 +267,6 @@ var BABYLON;
             this._destinationPoint.subtractToRef(this.intersectionPoint, vel);
         };
         return Collider;
-    })();
+    }());
     BABYLON.Collider = Collider;
 })(BABYLON || (BABYLON = {}));

+ 2 - 2
src/Collisions/babylon.collisionCoordinator.js

@@ -205,7 +205,7 @@ var BABYLON;
             };
         };
         return CollisionCoordinatorWorker;
-    })();
+    }());
     BABYLON.CollisionCoordinatorWorker = CollisionCoordinatorWorker;
     var CollisionCoordinatorLegacy = (function () {
         function CollisionCoordinatorLegacy() {
@@ -268,6 +268,6 @@ var BABYLON;
             this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh);
         };
         return CollisionCoordinatorLegacy;
-    })();
+    }());
     BABYLON.CollisionCoordinatorLegacy = CollisionCoordinatorLegacy;
 })(BABYLON || (BABYLON = {}));

+ 3 - 3
src/Collisions/babylon.collisionWorker.js

@@ -32,7 +32,7 @@ var BABYLON;
             delete this._geometries[id];
         };
         return CollisionCache;
-    })();
+    }());
     BABYLON.CollisionCache = CollisionCache;
     var CollideWorker = (function () {
         function CollideWorker(collider, _collisionCache, finalPosition) {
@@ -144,7 +144,7 @@ var BABYLON;
             return this.collider._canDoCollision(BABYLON.Vector3.FromArray(subMesh.sphereCenter), subMesh.sphereRadius, BABYLON.Vector3.FromArray(subMesh.boxMinimum), BABYLON.Vector3.FromArray(subMesh.boxMaximum));
         };
         return CollideWorker;
-    })();
+    }());
     BABYLON.CollideWorker = CollideWorker;
     var CollisionDetectorTransferable = (function () {
         function CollisionDetectorTransferable() {
@@ -206,7 +206,7 @@ var BABYLON;
             postMessage(reply, undefined);
         };
         return CollisionDetectorTransferable;
-    })();
+    }());
     BABYLON.CollisionDetectorTransferable = CollisionDetectorTransferable;
     //check if we are in a web worker, as this code should NOT run on the main UI thread
     try {

+ 2 - 2
src/Collisions/babylon.pickingInfo.js

@@ -9,7 +9,7 @@ var BABYLON;
             this.subMeshId = 0;
         }
         return IntersectionInfo;
-    })();
+    }());
     BABYLON.IntersectionInfo = IntersectionInfo;
     var PickingInfo = (function () {
         function PickingInfo() {
@@ -71,6 +71,6 @@ var BABYLON;
             return new BABYLON.Vector2(uv0.x + uv1.x + uv2.x, uv0.y + uv1.y + uv2.y);
         };
         return PickingInfo;
-    })();
+    }());
     BABYLON.PickingInfo = PickingInfo;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Culling/Octrees/babylon.octree.js

@@ -83,6 +83,6 @@ var BABYLON;
             }
         };
         return Octree;
-    })();
+    }());
     BABYLON.Octree = Octree;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Culling/Octrees/babylon.octreeBlock.js

@@ -117,6 +117,6 @@ var BABYLON;
             BABYLON.Octree._CreateBlocks(this._minPoint, this._maxPoint, this.entries, this._capacity, this._depth, this._maxDepth, this, this._creationFunc);
         };
         return OctreeBlock;
-    })();
+    }());
     BABYLON.OctreeBlock = OctreeBlock;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Culling/babylon.boundingBox.js

@@ -138,6 +138,6 @@ var BABYLON;
             return true;
         };
         return BoundingBox;
-    })();
+    }());
     BABYLON.BoundingBox = BoundingBox;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Culling/babylon.boundingInfo.js

@@ -114,6 +114,6 @@ var BABYLON;
             return true;
         };
         return BoundingInfo;
-    })();
+    }());
     BABYLON.BoundingInfo = BoundingInfo;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Culling/babylon.boundingSphere.js

@@ -44,6 +44,6 @@ var BABYLON;
             return true;
         };
         return BoundingSphere;
-    })();
+    }());
     BABYLON.BoundingSphere = BoundingSphere;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Culling/babylon.ray.js

@@ -269,6 +269,6 @@ var BABYLON;
         Ray.smallnum = 0.00000001;
         Ray.rayl = 10e8;
         return Ray;
-    })();
+    }());
     BABYLON.Ray = Ray;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Debug/babylon.debugLayer.js

@@ -674,6 +674,6 @@ var BABYLON;
             }
         };
         return DebugLayer;
-    })();
+    }());
     BABYLON.DebugLayer = DebugLayer;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Debug/babylon.skeletonViewer.js

@@ -131,7 +131,7 @@ var BABYLON;
                 }
             };
             return SkeletonViewer;
-        })();
+        }());
         Debug.SkeletonViewer = SkeletonViewer;
     })(Debug = BABYLON.Debug || (BABYLON.Debug = {}));
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Layer/babylon.layer.js

@@ -90,6 +90,6 @@ var BABYLON;
             }
         };
         return Layer;
-    })();
+    }());
     BABYLON.Layer = Layer;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/LensFlare/babylon.lensFlare.js

@@ -18,6 +18,6 @@ var BABYLON;
             system.lensFlares.push(this);
         }
         return LensFlare;
-    })();
+    }());
     BABYLON.LensFlare = LensFlare;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/LensFlare/babylon.lensFlareSystem.js

@@ -208,6 +208,6 @@ var BABYLON;
             return serializationObject;
         };
         return LensFlareSystem;
-    })();
+    }());
     BABYLON.LensFlareSystem = LensFlareSystem;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Lights/Shadows/babylon.shadowGenerator.js

@@ -402,6 +402,6 @@ var BABYLON;
         ShadowGenerator._FILTER_POISSONSAMPLING = 2;
         ShadowGenerator._FILTER_BLURVARIANCESHADOWMAP = 3;
         return ShadowGenerator;
-    })();
+    }());
     BABYLON.ShadowGenerator = ShadowGenerator;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Lights/babylon.directionalLight.js

@@ -124,6 +124,6 @@ var BABYLON;
             BABYLON.serialize()
         ], DirectionalLight.prototype, "autoUpdateExtends", void 0);
         return DirectionalLight;
-    })(BABYLON.Light);
+    }(BABYLON.Light));
     BABYLON.DirectionalLight = DirectionalLight;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Lights/babylon.hemisphericLight.js

@@ -46,6 +46,6 @@ var BABYLON;
             BABYLON.serializeAsVector3()
         ], HemisphericLight.prototype, "direction", void 0);
         return HemisphericLight;
-    })(BABYLON.Light);
+    }(BABYLON.Light));
     BABYLON.HemisphericLight = HemisphericLight;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Lights/babylon.light.js

@@ -189,6 +189,6 @@ var BABYLON;
             BABYLON.serialize()
         ], Light.prototype, "radius", void 0);
         return Light;
-    })(BABYLON.Node);
+    }(BABYLON.Node));
     BABYLON.Light = Light;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Lights/babylon.pointLight.js

@@ -82,6 +82,6 @@ var BABYLON;
             BABYLON.serializeAsVector3()
         ], PointLight.prototype, "position", void 0);
         return PointLight;
-    })(BABYLON.Light);
+    }(BABYLON.Light));
     BABYLON.PointLight = PointLight;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Lights/babylon.spotLight.js

@@ -93,6 +93,6 @@ var BABYLON;
             BABYLON.serialize()
         ], SpotLight.prototype, "exponent", void 0);
         return SpotLight;
-    })(BABYLON.Light);
+    }(BABYLON.Light));
     BABYLON.SpotLight = SpotLight;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Loading/babylon.sceneLoader.js

@@ -257,7 +257,7 @@ var BABYLON;
         // Members
         SceneLoader._registeredPlugins = new Array();
         return SceneLoader;
-    })();
+    }());
     BABYLON.SceneLoader = SceneLoader;
     ;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js

@@ -119,6 +119,6 @@ var BABYLON;
             configurable: true
         });
         return CustomProceduralTexture;
-    })(BABYLON.ProceduralTexture);
+    }(BABYLON.ProceduralTexture));
     BABYLON.CustomProceduralTexture = CustomProceduralTexture;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Materials/Textures/Procedurals/babylon.proceduralTexture.js

@@ -271,6 +271,6 @@ var BABYLON;
             _super.prototype.dispose.call(this);
         };
         return ProceduralTexture;
-    })(BABYLON.Texture);
+    }(BABYLON.Texture));
     BABYLON.ProceduralTexture = ProceduralTexture;
 })(BABYLON || (BABYLON = {}));

+ 0 - 0
src/Materials/Textures/babylon.baseTexture.js


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików