浏览代码

Merge remote-tracking branch 'refs/remotes/BabylonJS/master' into PhysicsEngine

Raanan Weber 9 年之前
父节点
当前提交
f9b9e89972
共有 100 个文件被更改,包括 6814 次插入8612 次删除
  1. 二进制
      Exporters/3ds Max/Max2Babylon-0.4.1.zip
  2. 二进制
      Exporters/3ds Max/Max2Babylon-0.4.2.zip
  3. 3 1
      Tools/Gulp/config.json
  4. 4 2
      Tools/Gulp/gulpfile.js
  5. 22 28
      dist/preview release/babylon.core.js
  6. 642 712
      dist/preview release/babylon.d.ts
  7. 29 37
      dist/preview release/babylon.js
  8. 4498 5047
      dist/preview release/babylon.max.js
  9. 29 37
      dist/preview release/babylon.noworker.js
  10. 1 0
      dist/preview release/what's new.md
  11. 1 1
      materialsLibrary/dist/babylon.fireMaterial.js
  12. 1 1
      materialsLibrary/dist/babylon.fireMaterial.min.js
  13. 14 157
      materialsLibrary/dist/babylon.gradientMaterial.js
  14. 1 1
      materialsLibrary/dist/babylon.gradientMaterial.min.js
  15. 11 157
      materialsLibrary/dist/babylon.lavaMaterial.js
  16. 1 1
      materialsLibrary/dist/babylon.lavaMaterial.min.js
  17. 2 5
      materialsLibrary/dist/babylon.normalMaterial.js
  18. 1 1
      materialsLibrary/dist/babylon.normalMaterial.min.js
  19. 28 7
      materialsLibrary/dist/babylon.pbrMaterial.js
  20. 2 2
      materialsLibrary/dist/babylon.pbrMaterial.min.js
  21. 1 4
      materialsLibrary/dist/babylon.simpleMaterial.js
  22. 1 1
      materialsLibrary/dist/babylon.simpleMaterial.min.js
  23. 1 1
      materialsLibrary/dist/babylon.terrainMaterial.js
  24. 1 1
      materialsLibrary/dist/babylon.terrainMaterial.min.js
  25. 10 8
      materialsLibrary/dist/dts/babylon.pbrMaterial.d.ts
  26. 14 174
      materialsLibrary/materials/gradient/babylon.gradientMaterial.ts
  27. 17 481
      materialsLibrary/materials/gradient/gradient.fragment.fx
  28. 11 86
      materialsLibrary/materials/gradient/gradient.vertex.fx
  29. 10 177
      materialsLibrary/materials/lava/babylon.lavaMaterial.ts
  30. 17 481
      materialsLibrary/materials/lava/lava.fragment.fx
  31. 12 105
      materialsLibrary/materials/lava/lava.vertex.fx
  32. 4 1
      materialsLibrary/materials/normal/normal.fragment.fx
  33. 32 10
      materialsLibrary/materials/pbr/babylon.pbrMaterial.ts
  34. 25 84
      materialsLibrary/materials/pbr/pbr.fragment.fx
  35. 1 18
      materialsLibrary/test/index.html
  36. 256 79
      materialsLibrary/test/refs/babylon.max.js
  37. 5 0
      src/Cameras/VR/babylon.vrDeviceOrientationCamera.js
  38. 8 0
      src/Cameras/VR/babylon.vrDeviceOrientationCamera.ts
  39. 5 0
      src/Cameras/VR/babylon.webVRCamera.js
  40. 8 0
      src/Cameras/VR/babylon.webVRCamera.ts
  41. 7 0
      src/Cameras/babylon.arcRotateCamera.js
  42. 11 0
      src/Cameras/babylon.arcRotateCamera.ts
  43. 0 1
      src/Cameras/babylon.camera.js
  44. 0 2
      src/Cameras/babylon.camera.ts
  45. 5 0
      src/Cameras/babylon.deviceOrientationCamera.js
  46. 8 0
      src/Cameras/babylon.deviceOrientationCamera.ts
  47. 2 0
      src/Cameras/babylon.followCamera.js
  48. 3 0
      src/Cameras/babylon.followCamera.ts
  49. 1 0
      src/Cameras/babylon.freeCamera.js
  50. 1 0
      src/Cameras/babylon.freeCamera.ts
  51. 5 0
      src/Cameras/babylon.gamepadCamera.js
  52. 8 0
      src/Cameras/babylon.gamepadCamera.ts
  53. 30 0
      src/Cameras/babylon.stereoscopicCameras.js
  54. 36 0
      src/Cameras/babylon.stereoscopicCameras.ts
  55. 1 0
      src/Cameras/babylon.targetCamera.js
  56. 1 0
      src/Cameras/babylon.targetCamera.ts
  57. 5 0
      src/Cameras/babylon.touchCamera.js
  58. 8 0
      src/Cameras/babylon.touchCamera.ts
  59. 5 0
      src/Cameras/babylon.universalCamera.js
  60. 8 0
      src/Cameras/babylon.universalCamera.ts
  61. 5 0
      src/Cameras/babylon.virtualJoysticksCamera.js
  62. 8 0
      src/Cameras/babylon.virtualJoysticksCamera.ts
  63. 3 1
      src/Materials/Textures/babylon.texture.js
  64. 6 1
      src/Materials/Textures/babylon.texture.ts
  65. 37 0
      src/Materials/babylon.fresnelParameters.js
  66. 41 0
      src/Materials/babylon.fresnelParameters.ts
  67. 54 26
      src/Materials/babylon.material.js
  68. 33 34
      src/Materials/babylon.material.ts
  69. 3 3
      src/Materials/babylon.shaderMaterial.js
  70. 5 4
      src/Materials/babylon.shaderMaterial.ts
  71. 113 219
      src/Materials/babylon.standardMaterial.js
  72. 73 271
      src/Materials/babylon.standardMaterial.ts
  73. 1 1
      src/Math/babylon.math.js
  74. 2 3
      src/Math/babylon.math.ts
  75. 40 16
      src/Mesh/babylon.groundMesh.js
  76. 42 16
      src/Mesh/babylon.groundMesh.ts
  77. 21 0
      src/Mesh/babylon.mesh.vertexData.js
  78. 24 1
      src/Mesh/babylon.mesh.vertexData.ts
  79. 25 0
      src/Mesh/babylon.meshBuilder.js
  80. 28 1
      src/Mesh/babylon.meshBuilder.ts
  81. 1 0
      src/Mesh/babylon.subMesh.js
  82. 2 0
      src/Mesh/babylon.subMesh.ts
  83. 4 1
      src/Particles/babylon.particleSystem.js
  84. 6 1
      src/Particles/babylon.particleSystem.ts
  85. 6 0
      src/Particles/babylon.solidParticleSystem.js
  86. 9 4
      src/Particles/babylon.solidParticleSystem.ts
  87. 7 0
      src/Shaders/ShadersInclude/fresnelFunction.fx
  88. 3 0
      src/Shaders/ShadersInclude/pointCloudVertex.fx
  89. 3 0
      src/Shaders/ShadersInclude/pointCloudVertexDeclaration.fx
  90. 61 0
      src/Shaders/ShadersInclude/reflectionFunction.fx
  91. 6 68
      src/Shaders/default.fragment.fx
  92. 2 8
      src/Shaders/default.vertex.fx
  93. 1 7
      src/Shaders/legacydefault.fragment.fx
  94. 10 0
      src/Sprites/babylon.spriteManager.js
  95. 8 0
      src/Sprites/babylon.spriteManager.ts
  96. 116 0
      src/Tools/babylon.decorators.js
  97. 128 0
      src/Tools/babylon.decorators.ts
  98. 1 7
      src/Tools/babylon.tools.js
  99. 2 8
      src/Tools/babylon.tools.ts
  100. 0 0
      src/babylon.scene.js

二进制
Exporters/3ds Max/Max2Babylon-0.4.1.zip


二进制
Exporters/3ds Max/Max2Babylon-0.4.2.zip


+ 3 - 1
Tools/Gulp/config.json

@@ -16,6 +16,7 @@
     ],
     "files": [
       "../../src/Math/babylon.math.js",
+      "../../src/Tools/babylon.decorators.js",
       "../../src/Tools/babylon.database.js",
       "../../src/Tools/babylon.tools.tga.js",
       "../../src/Tools/babylon.smartArray.js",
@@ -62,7 +63,8 @@
       "../../src/Materials/Textures/babylon.videoTexture.js",
       "../../src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js",
       "../../src/Materials/babylon.effect.js",
-      "../../src/Materials/babylon.materialHelper.js",
+      "../../src/Materials/babylon.materialHelper.js",      
+      "../../src/Materials/babylon.fresnelParameters.js",
       "../../src/Materials/babylon.material.js",
       "../../src/Materials/babylon.standardMaterial.js",
       "../../src/Materials/babylon.multiMaterial.js",

+ 4 - 2
Tools/Gulp/gulpfile.js

@@ -67,7 +67,8 @@ gulp.task('typescript-compile', function () {
             noExternalResolve: true,
             target: 'ES5',
             declarationFiles: true,
-            typescript: require('typescript')
+            typescript: require('typescript'),
+            experimentalDecorators: true
         }));
     return merge2([
         tsResult.dts
@@ -85,7 +86,8 @@ gulp.task('typescript-sourcemaps', function () {
             noExternalResolve: true,
             target: 'ES5',
             declarationFiles: true,
-            typescript: require('typescript')
+            typescript: require('typescript'),
+            experimentalDecorators: true
         }));
     return tsResult.js
         .pipe(sourcemaps.write("./")) // sourcemaps are written.

文件差异内容过多而无法显示
+ 22 - 28
dist/preview release/babylon.core.js


文件差异内容过多而无法显示
+ 642 - 712
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 29 - 37
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 4498 - 5047
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 29 - 37
dist/preview release/babylon.noworker.js


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

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

文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.fireMaterial.js


文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.fireMaterial.min.js


文件差异内容过多而无法显示
+ 14 - 157
materialsLibrary/dist/babylon.gradientMaterial.js


文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.gradientMaterial.min.js


文件差异内容过多而无法显示
+ 11 - 157
materialsLibrary/dist/babylon.lavaMaterial.js


文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.lavaMaterial.min.js


文件差异内容过多而无法显示
+ 2 - 5
materialsLibrary/dist/babylon.normalMaterial.js


文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.normalMaterial.min.js


文件差异内容过多而无法显示
+ 28 - 7
materialsLibrary/dist/babylon.pbrMaterial.js


文件差异内容过多而无法显示
+ 2 - 2
materialsLibrary/dist/babylon.pbrMaterial.min.js


+ 1 - 4
materialsLibrary/dist/babylon.simpleMaterial.js

@@ -244,10 +244,7 @@ var BABYLON;
                     this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.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);
-                }
+                BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
                 // Point size
                 if (this.pointsCloud) {
                     this._effect.setFloat("pointSize", this.pointSize);

文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.simpleMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.terrainMaterial.js


文件差异内容过多而无法显示
+ 1 - 1
materialsLibrary/dist/babylon.terrainMaterial.min.js


+ 10 - 8
materialsLibrary/dist/dts/babylon.pbrMaterial.d.ts

@@ -41,22 +41,24 @@ declare module BABYLON {
         albedoColor: Color3;
         reflectivityColor: Color3;
         reflectionColor: Color3;
-        microSurface: number;
         emissiveColor: Color3;
-        useAlphaFromAlbedoTexture: boolean;
-        useEmissiveAsIllumination: boolean;
-        linkEmissiveWithAlbedo: boolean;
-        useSpecularOverAlpha: boolean;
-        disableLighting: boolean;
+        microSurface: number;
         indexOfRefraction: number;
         invertRefractionY: boolean;
-        linkRefractionWithTransparency: boolean;
-        useLightmapAsShadowmap: boolean;
         opacityFresnelParameters: FresnelParameters;
         emissiveFresnelParameters: FresnelParameters;
+        linkRefractionWithTransparency: boolean;
+        linkEmissiveWithAlbedo: boolean;
+        useLightmapAsShadowmap: boolean;
+        useEmissiveAsIllumination: boolean;
+        useAlphaFromAlbedoTexture: boolean;
+        useSpecularOverAlpha: boolean;
         useMicroSurfaceFromReflectivityMapAlpha: boolean;
         useAutoMicroSurfaceFromReflectivityMap: boolean;
         useScalarInLinearSpace: boolean;
+        usePhysicalLightFalloff: boolean;
+        useRadianceOverAlpha: boolean;
+        disableLighting: boolean;
         private _renderTargets;
         private _worldViewProjectionMatrix;
         private _globalAmbientColor;

+ 14 - 174
materialsLibrary/materials/gradient/babylon.gradientMaterial.ts

@@ -47,8 +47,7 @@ module BABYLON {
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public BONES = false;
-        public BONES4 = false;
+        public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
 
@@ -162,80 +161,7 @@ module BABYLON {
 
             var lightIndex = 0;
             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);
             }
 
             // Attribs
@@ -259,9 +185,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
@@ -282,30 +207,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);
              
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -327,17 +232,9 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
-                    attribs.push(VertexBuffer.MatricesIndicesKind);
-                    attribs.push(VertexBuffer.MatricesWeightsKind);
-                }
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
 
-                if (this._defines.INSTANCES) {
-                    attribs.push("world0");
-                    attribs.push("world1");
-                    attribs.push("world2");
-                    attribs.push("world3");
-                }
 
                 // Legacy browser patch
                 var shaderName = "gradient";
@@ -390,16 +287,13 @@ 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) {
                 // 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) {
@@ -412,58 +306,7 @@ module BABYLON {
             this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                var lightIndex = 0;
-                var depthValuesAlreadySet = false;
-                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) {
-                            if (!(<any>light).needCube()) {
-                                this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                            } else {
-                                if (!depthValuesAlreadySet) {
-                                    depthValuesAlreadySet = true;
-                                    this._effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
-                                }
-                            }
-                            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);
             }
 
             // View
@@ -472,10 +315,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.setColor4("topColor", this.topColor, this.topColorAlpha);
             this._effect.setColor4("bottomColor", this.bottomColor, this.bottomColorAlpha);

+ 17 - 481
materialsLibrary/materials/gradient/gradient.fragment.fx

@@ -22,85 +22,15 @@ 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
+#include<light0FragmentDeclaration>
+#include<light1FragmentDeclaration>
+#include<light2FragmentDeclaration>
+#include<light3FragmentDeclaration>
 
-#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<lightsFragmentFunctions>
+#include<shadowsFragmentFunctions>
 
 // Samplers
 #ifdef DIFFUSE
@@ -109,274 +39,13 @@ uniform sampler2D diffuseSampler;
 uniform vec2 vDiffuseInfos;
 #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)
-uniform vec2 depthValues;
-
-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;
-};
-
-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<fogFragmentDeclaration>
 
 void main(void) {
-	// Clip plane
-#ifdef CLIPPLANE
-	if (fClipDistance > 0.0)
-		discard;
-#endif
+#include<clipPlaneFragment>
 
 	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
 
@@ -386,7 +55,7 @@ void main(void) {
     vec4 baseColor = mix(bottomColor, topColor, max(pow(max(h, 0.0), mysmoothness), 0.0));
 
 	// Base color
-	vec3 diffuseColor = vDiffuseColor.rgb;
+	vec3 diffuseColor = baseColor.rgb;
 
 	// Alpha
 	float alpha = baseColor.a;
@@ -411,142 +80,12 @@ void main(void) {
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
 	float shadow = 1.;
-
-#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, 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;
-#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, 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;
-#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, 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;
-#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, 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	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#endif
+    float glossiness = 0.;
+    
+#include<light0Fragment>
+#include<light1Fragment>
+#include<light2Fragment>
+#include<light3Fragment>
 
 #ifdef VERTEXALPHA
 	alpha *= vColor.a;
@@ -557,10 +96,7 @@ void main(void) {
 	// Composition
 	vec4 color = vec4(finalDiffuse, alpha);
 
-#ifdef FOG
-	float fog = CalcFogFactor();
-	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
-#endif
+#include<fogFragment>
 
 	gl_FragColor = color;
 }

+ 11 - 86
materialsLibrary/materials/gradient/gradient.vertex.fx

@@ -15,21 +15,10 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#endif
+#include<bonesDeclaration>
 
 // Uniforms
-
-#ifdef INSTANCES
-attribute vec4 world0;
-attribute vec4 world1;
-attribute vec4 world2;
-attribute vec4 world3;
-#else
-uniform mat4 world;
-#endif
+#include<instancesDeclaration>
 
 uniform mat4 view;
 uniform mat4 viewProjection;
@@ -40,10 +29,6 @@ uniform mat4 diffuseMatrix;
 uniform vec2 vDiffuseInfos;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -58,56 +43,15 @@ 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>
 
 void main(void) {
-	mat4 finalWorld;
+#include<instancesVertex>
+#include<bonesVertex> 
 
-#ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
-#else
-	finalWorld = world;
-#endif
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = finalWorld * (m0 + m1 + m2);
-#endif 
-
-#endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);
@@ -137,30 +81,11 @@ void main(void) {
 #endif
 
 	// Clip plane
-#ifdef CLIPPLANE
-	fClipDistance = dot(worldPos, vClipPlane);
-#endif
+#include<clipPlaneVertex>
 
-	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
-
-	// Shadows
-#ifdef SHADOWS
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-	vPositionFromLight0 = lightMatrix0 * worldPos;
-#endif
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-	vPositionFromLight1 = lightMatrix1 * worldPos;
-#endif
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-	vPositionFromLight2 = lightMatrix2 * worldPos;
-#endif
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-	vPositionFromLight3 = lightMatrix3 * worldPos;
-#endif
-#endif
+    // Fog
+#include<fogVertex>
+#include<shadowsVertex>
 
 	// Vertex color
 #ifdef VERTEXCOLOR

+ 10 - 177
materialsLibrary/materials/lava/babylon.lavaMaterial.ts

@@ -131,7 +131,6 @@ module BABYLON {
             }
 
             var engine = scene.getEngine();
-            var needNormals = false;
             var needUVs = false;
 
             this._defines.reset();
@@ -169,85 +168,12 @@ module BABYLON {
 
             var lightIndex = 0;
             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;
-                }
+                MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines);
             }
 
             // Attribs
             if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
+                if (mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
                     this._defines.NORMAL = true;
                 }
                 if (needUVs) {
@@ -265,7 +191,6 @@ module BABYLON {
                         this._defines.VERTEXALPHA = true;
                     }
                 }
-
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
                     this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
@@ -289,29 +214,9 @@ 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);
-                    }
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
 
-                    if (this._defines["SHADOWVSM" + lightIndex]) {
-                        fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
-                    }
-                }
-
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
@@ -334,21 +239,8 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
-                    attribs.push(VertexBuffer.MatricesIndicesKind);
-                    attribs.push(VertexBuffer.MatricesWeightsKind);
-                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
-                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                    }
-                }
-
-                if (this._defines.INSTANCES) {
-                    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 = "lava";
@@ -403,9 +295,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        
@@ -421,10 +311,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) {
@@ -437,58 +324,7 @@ module BABYLON {
             this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                var lightIndex = 0;
-                var depthValuesAlreadySet = false;
-                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) {
-                            if (!(<any>light).needCube()) {
-                                this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                            } else {
-                                if (!depthValuesAlreadySet) {
-                                    depthValuesAlreadySet = true;
-                                    this._effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
-                                }
-                            }
-                            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);
             }
 
             // View
@@ -497,10 +333,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._lastTime += scene.getEngine().getDeltaTime();

+ 17 - 481
materialsLibrary/materials/lava/lava.fragment.fx

@@ -27,85 +27,14 @@ 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
+#include<light0FragmentDeclaration>
+#include<light1FragmentDeclaration>
+#include<light2FragmentDeclaration>
+#include<light3FragmentDeclaration>
 
-#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<lightsFragmentFunctions>
+#include<shadowsFragmentFunctions>
 
 // Samplers
 #ifdef DIFFUSE
@@ -114,266 +43,10 @@ uniform sampler2D diffuseSampler;
 uniform vec2 vDiffuseInfos;
 #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)
-uniform vec2 depthValues;
-
-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;
-};
-
-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<fogFragmentDeclaration>
 
 
 float random( vec3 scale, float seed ){
@@ -382,11 +55,7 @@ float random( vec3 scale, float seed ){
 
 
 void main(void) {
-	// Clip plane
-#ifdef CLIPPLANE
-	if (fClipDistance > 0.0)
-		discard;
-#endif
+#include<clipPlaneFragment>
 
 	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
 
@@ -424,7 +93,7 @@ void main(void) {
     fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );
 
     baseColor = mix( baseColor, vec4( fogColor, baseColor.w ), fogFactor );
-
+    diffuseColor = baseColor.rgb;
     ///// END MAGMA ////
 
 
@@ -453,142 +122,13 @@ void main(void) {
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
 	float shadow = 1.;
+    float glossiness = 0.;
+    
+#include<light0Fragment>
+#include<light1Fragment>
+#include<light2Fragment>
+#include<light3Fragment>
 
-#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, 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;
-#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, 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;
-#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, 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;
-#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, 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	
-#else
-	shadow = 1.;
-#endif
-	diffuseBase += info.diffuse * shadow;
-#endif
 
 #ifdef VERTEXALPHA
 	alpha *= vColor.a;
@@ -599,11 +139,7 @@ void main(void) {
 	// Composition
 	vec4 color = vec4(finalDiffuse, alpha);
 
-#ifdef FOG
-	float fog = CalcFogFactor();
-	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
-#endif
-
+#include<fogFragment>
 
 	gl_FragColor = color;
 }

+ 12 - 105
materialsLibrary/materials/lava/lava.vertex.fx

@@ -20,16 +20,10 @@ attribute vec2 uv2;
 attribute vec4 color;
 #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;
@@ -40,17 +34,6 @@ uniform mat4 diffuseMatrix;
 uniform vec2 vDiffuseInfos;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -65,33 +48,11 @@ varying vec3 vNormalW;
 varying vec4 vColor;
 #endif
 
-#ifdef CLIPPLANE
-uniform vec4 vClipPlane;
-varying float fClipDistance;
-#endif
 
-#ifdef FOG
-varying float fFogDistance;
-#endif
+#include<clipPlaneVertexDeclaration>
 
-#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>
 
 /* NOISE FUNCTIONS */
 ////// ASHIMA webgl noise
@@ -202,45 +163,11 @@ float turbulence( vec3 p ) {
 }
 
 void main(void) {
-	mat4 finalWorld;
-
-#ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
-#else
-	finalWorld = world;
-#endif
-
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
-#endif
 
+#include<instancesVertex>
+#include<bonesVertex>
 
+#ifdef NORMAL
     // get a turbulent 3d noise using the normal, normal to high freq
     noise = 10.0 *  -.10 * turbulence( .5 * normal + time*1.15 );
     // get a 3d noise using the position, low frequency
@@ -256,7 +183,6 @@ void main(void) {
 	vec4 worldPos = finalWorld * vec4(newPosition, 1.0);
 	vPositionW = vec3(worldPos);
 
-#ifdef NORMAL
 	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
 #endif
 
@@ -280,30 +206,11 @@ void main(void) {
 #endif
 
 	// Clip plane
-#ifdef CLIPPLANE
-	fClipDistance = dot(worldPos, vClipPlane);
-#endif
+#include<clipPlaneVertex>
 
 	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
-
-	// Shadows
-#ifdef SHADOWS
-#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-	vPositionFromLight0 = lightMatrix0 * worldPos;
-#endif
-#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-	vPositionFromLight1 = lightMatrix1 * worldPos;
-#endif
-#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-	vPositionFromLight2 = lightMatrix2 * worldPos;
-#endif
-#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-	vPositionFromLight3 = lightMatrix3 * worldPos;
-#endif
-#endif
+#include<fogVertex>
+#include<shadowsVertex>
 
 	// Vertex color
 #ifdef VERTEXCOLOR

+ 4 - 1
materialsLibrary/materials/normal/normal.fragment.fx

@@ -60,7 +60,10 @@ void main(void) {
 	baseColor.rgb *= vDiffuseInfos.y;
 #endif
 
-baseColor = mix(baseColor, vec4(vNormalW, 1.0), 0.5);
+#ifdef NORMAL
+    baseColor = mix(baseColor, vec4(vNormalW, 1.0), 0.5);
+#endif
+
 #ifdef VERTEXCOLOR
 	baseColor.rgb *= vColor.rgb;
 #endif

+ 32 - 10
materialsLibrary/materials/pbr/babylon.pbrMaterial.ts

@@ -89,6 +89,8 @@ module BABYLON {
         public LINKREFRACTIONTOTRANSPARENCY = false;
         public REFRACTIONMAPINLINEARSPACE = false;
         public LODBASEDMICROSFURACE = false;
+        public USEPHYSICALLIGHTFALLOFF = false;
+        public RADIANCEOVERALPHA = false;
 
         constructor() {
             super();
@@ -148,26 +150,28 @@ module BABYLON {
         public albedoColor = new Color3(1, 1, 1);
         public reflectivityColor = new Color3(1, 1, 1);
         public reflectionColor = new Color3(0.5, 0.5, 0.5);
-        public microSurface = 0.5;
         public emissiveColor = new Color3(0, 0, 0);
-        public useAlphaFromAlbedoTexture = false;
-        public useEmissiveAsIllumination = false;
-        public linkEmissiveWithAlbedo = false;
-        public useSpecularOverAlpha = true;
-        public disableLighting = false;
-        
+        public microSurface = 0.5;
         public indexOfRefraction = 0.66;
         public invertRefractionY = false;
-        public linkRefractionWithTransparency = false;
-
-        public useLightmapAsShadowmap = false;
 
         public opacityFresnelParameters: FresnelParameters;
         public emissiveFresnelParameters: FresnelParameters;
 
+        public linkRefractionWithTransparency = false;
+        public linkEmissiveWithAlbedo = false;
+        
+        public useLightmapAsShadowmap = false;
+        public useEmissiveAsIllumination = false;
+        public useAlphaFromAlbedoTexture = false;
+        public useSpecularOverAlpha = true;
         public useMicroSurfaceFromReflectivityMapAlpha = false;
         public useAutoMicroSurfaceFromReflectivityMap = false;
         public useScalarInLinearSpace = false;
+        public usePhysicalLightFalloff = true;
+        public useRadianceOverAlpha = true;
+        
+        public disableLighting = false;
 
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _worldViewProjectionMatrix = Matrix.Zero();
@@ -253,6 +257,10 @@ module BABYLON {
         private static convertColorToLinearSpaceToRef (color: Color3, ref: Color3, useScalarInLinear: boolean): void {
             if (!useScalarInLinear) {
                 color.toLinearSpaceToRef(ref);
+            } else {
+                ref.r = color.r;
+                ref.g = color.g;
+                ref.b = color.b;
             }
         }
         
@@ -557,6 +565,14 @@ module BABYLON {
             if (this._defines.SPECULARTERM && this.useSpecularOverAlpha) {
                 this._defines.SPECULAROVERALPHA = true;
             }
+            
+            if (this.usePhysicalLightFalloff) {
+                this._defines.USEPHYSICALLIGHTFALLOFF = true;
+            }
+            
+            if (this.useRadianceOverAlpha) {
+                this._defines.RADIANCEOVERALPHA = true;
+            }
 
             // Attribs
             if (mesh) {
@@ -1127,6 +1143,8 @@ module BABYLON {
             newPBRMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
             newPBRMaterial.indexOfRefraction = this.indexOfRefraction;
             newPBRMaterial.invertRefractionY = this.invertRefractionY;
+            newPBRMaterial.usePhysicalLightFalloff = this.usePhysicalLightFalloff;
+            newPBRMaterial.useRadianceOverAlpha = this.useRadianceOverAlpha;
 
             newPBRMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
             newPBRMaterial.opacityFresnelParameters = this.opacityFresnelParameters.clone();
@@ -1211,6 +1229,8 @@ module BABYLON {
             serializationObject.useSpecularOverAlpha = this.useSpecularOverAlpha;
             serializationObject.indexOfRefraction = this.indexOfRefraction;
             serializationObject.invertRefractionY = this.invertRefractionY;
+            serializationObject.usePhysicalLightFalloff = this.usePhysicalLightFalloff;
+            serializationObject.useRadianceOverAlpha = this.useRadianceOverAlpha;
 
             serializationObject.emissiveFresnelParameters = this.emissiveFresnelParameters.serialize();
             serializationObject.opacityFresnelParameters = this.opacityFresnelParameters.serialize();
@@ -1308,6 +1328,8 @@ module BABYLON {
             material.useSpecularOverAlpha = source.useSpecularOverAlpha;
             material.indexOfRefraction = source.indexOfRefraction;
             material.invertRefractionY = source.invertRefractionY;
+            material.usePhysicalLightFalloff = source.usePhysicalLightFalloff;
+            material.useRadianceOverAlpha = source.useRadianceOverAlpha;
 
             material.emissiveFresnelParameters = FresnelParameters.Parse(source.emissiveFresnelParameters);
             material.opacityFresnelParameters = FresnelParameters.Parse(source.opacityFresnelParameters);

+ 25 - 84
materialsLibrary/materials/pbr/pbr.fragment.fx

@@ -269,6 +269,17 @@ vec3 toGammaSpace(vec3 color)
     return vec3(pow(color.r, 1.0 / 2.2), pow(color.g, 1.0 / 2.2), pow(color.b, 1.0 / 2.2));
 }
 
+float computeLightFalloff(vec3 lightOffset, float lightDistanceSquared, float range)
+{
+    #ifdef USEPHYSICALLIGHTFALLOFF
+        float lightDistanceFalloff = 1.0 / ((lightDistanceSquared + 0.0001));
+        return lightDistanceFalloff;
+    #else
+        float lightFalloff = max(0., 1.0 - length(lightOffset) / range);
+        return lightFalloff;
+    #endif
+}
+
 #ifdef CAMERATONEMAP
     vec3 toneMaps(vec3 color)
     {
@@ -367,13 +378,7 @@ uniform sampler2D reflectivitySampler;
 #endif
 
 // Fresnel
-#ifdef FRESNEL
-float computeFresnelTerm(vec3 viewDirection, vec3 worldNormal, float bias, float power)
-{
-    float fresnelTerm = pow(bias + abs(dot(viewDirection, worldNormal)), power);
-    return clamp(fresnelTerm, 0., 1.);
-}
-#endif
+#include<fresnelFunction>
 
 #ifdef OPACITYFRESNEL
 uniform vec4 opacityParts;
@@ -423,67 +428,7 @@ varying vec3 vPositionUVW;
     #endif
 #endif
 
-vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
-{
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
-    vec3 direction = normalize(vDirectionW);
-
-    float t = clamp(direction.y * -0.5 + 0.5, 0., 1.0);
-    float s = atan(direction.z, direction.x) * RECIPROCAL_PI2 + 0.5;
-
-    return vec3(s, t, 0);
-#endif
-
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR
-
-	vec3 cameraToVertex = normalize(worldPos.xyz - vEyePosition);
-	vec3 r = reflect(cameraToVertex, worldNormal);
-	float t = clamp(r.y * -0.5 + 0.5, 0., 1.0);
-	float s = atan(r.z, r.x) * RECIPROCAL_PI2 + 0.5;
-
-	return vec3(s, t, 0);
-#endif
-
-#ifdef REFLECTIONMAP_SPHERICAL
-    vec3 viewDir = normalize(vec3(view * worldPos));
-    vec3 viewNormal = normalize(vec3(view * vec4(worldNormal, 0.0)));
-
-    vec3 r = reflect(viewDir, viewNormal);
-    r.z = r.z - 1.0;
-
-    float m = 2.0 * length(r);
-
-    return vec3(r.x / m + 0.5, 1.0 - r.y / m - 0.5, 0);
-#endif
-
-#ifdef REFLECTIONMAP_PLANAR
-    vec3 viewDir = worldPos.xyz - vEyePosition;
-    vec3 coords = normalize(reflect(viewDir, worldNormal));
-
-    return vec3(reflectionMatrix * vec4(coords, 1));
-#endif
-
-#ifdef REFLECTIONMAP_CUBIC
-    vec3 viewDir = worldPos.xyz - vEyePosition;
-    vec3 coords = reflect(viewDir, worldNormal);
-#ifdef INVERTCUBICMAP
-    coords.y = 1.0 - coords.y;
-#endif
-    return vec3(reflectionMatrix * vec4(coords, 0));
-#endif
-
-#ifdef REFLECTIONMAP_PROJECTION
-    return vec3(reflectionMatrix * (view * worldPos));
-#endif
-
-#ifdef REFLECTIONMAP_SKYBOX
-    return vPositionUVW;
-#endif
-
-#ifdef REFLECTIONMAP_EXPLICIT
-    return vec3(0, 0, 0);
-#endif
-}
+#include<reflectionFunction>
 
 #endif
 
@@ -686,11 +631,8 @@ lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData,
     if (lightData.w == 0.)
     {
         vec3 lightOffset = lightData.xyz - vPositionW;
-        
-        // Inverse squared falloff.
         float lightDistanceSquared = dot(lightOffset, lightOffset);
-        float lightDistanceFalloff = 1.0 / ((lightDistanceSquared + 0.0001) * range);
-        attenuation = lightDistanceFalloff;
+        attenuation = computeLightFalloff(lightOffset, lightDistanceSquared, range);
         
         lightDistance = sqrt(lightDistanceSquared);
         lightDirection = normalize(lightOffset);
@@ -739,8 +681,7 @@ lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightDa
         
         // Inverse squared falloff.
         float lightDistanceSquared = dot(lightOffset, lightOffset);
-        float lightDistanceFalloff = 1.0 / ((lightDistanceSquared + 0.0001) * range);
-        float attenuation = lightDistanceFalloff;
+        float attenuation = computeLightFalloff(lightOffset, lightDistanceSquared, range);
         
         // Directional falloff.
         attenuation *= cosAngle;
@@ -1130,10 +1071,10 @@ void main(void) {
 vec3 surfaceRefractionColor = vec3(0., 0., 0.);
 
 // Go mat -> blurry reflexion according to microSurface
-#ifndef LODBASEDMICROSFURACE
-    float bias = 20. * (1.0 - microSurface);
-#else
+#ifdef LODBASEDMICROSFURACE
     float alphaG = convertRoughnessToAverageSlope(roughness);
+#else
+    float bias = 20. * (1.0 - microSurface);
 #endif
         
 #ifdef REFRACTION
@@ -1168,7 +1109,7 @@ vec3 surfaceRefractionColor = vec3(0., 0., 0.);
         #ifdef LODBASEDMICROSFURACE
             surfaceRefractionColor = texture2DLodEXT(refraction2DSampler, refractionCoords, lodRefraction).rgb * vRefractionInfos.x;
         #else
-            surfaceRefractionColor = texture2D(refraction2DSampler, refractionCoords).rgb * vRefractionInfos.x;
+            surfaceRefractionColor = texture2D(refraction2DSampler, refractionCoords, bias).rgb * vRefractionInfos.x;
         #endif    
         
         surfaceRefractionColor = toLinearSpace(surfaceRefractionColor.rgb); 
@@ -1219,9 +1160,9 @@ vec3 environmentIrradiance = vReflectionColor.rgb;
 
         coords.y = 1.0 - coords.y;
         #ifdef LODBASEDMICROSFURACE
-            environmentRadiance = texture2DLodExt(reflection2DSampler, coords, lodReflection).rgb * vReflectionInfos.x;
+            environmentRadiance = texture2DLodEXT(reflection2DSampler, coords, lodReflection).rgb * vReflectionInfos.x;
         #else
-            environmentRadiance = texture2D(reflection2DSampler, coords).rgb * vReflectionInfos.x;
+            environmentRadiance = texture2D(reflection2DSampler, coords, bias).rgb * vReflectionInfos.x;
         #endif
     
         environmentRadiance = toLinearSpace(environmentRadiance.rgb);
@@ -1339,12 +1280,12 @@ vec3 surfaceEmissiveColor = vEmissiveColor;
     vec3 finalSpecular = vec3(0.0);
 #endif
 
-#ifdef OVERLOADEDSHADOWVALUES
-    finalSpecular = mix(finalSpecular, vec3(0.0), (1.0 - vOverloadedShadowIntensity.y));
+#ifdef SPECULAROVERALPHA
+    alpha = clamp(alpha + getLuminance(finalSpecular), 0., 1.);
 #endif
 
-#ifdef SPECULAROVERALPHA
-    alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
+#ifdef RADIANCEOVERALPHA
+    alpha = clamp(alpha + getLuminance(environmentRadiance), 0., 1.);
 #endif
 
 // Composition

+ 1 - 18
materialsLibrary/test/index.html

@@ -215,15 +215,6 @@
 					skybox.material = skyboxMaterial;
 					currentMesh.isVisible = true;
 					fur.resetFur();
-					
-                    options.lightRange = 1000;
-                    hemisphericLight.range = 1000;
-                    options.lightRange = 1000;
-                    directionalLight.range = 1000;
-                    options.lightRange = 1000;
-                    pointLight.range = 1000;
-                    options.lightRange = 1000;
-                    spotLight.range = 1000;
                     
 					switch (options.material) {
 						case "simple":
@@ -248,14 +239,6 @@
 							break;
 						case "pbr":
 							currentMaterial = pbr;
-                            options.lightRange = 1;
-                            hemisphericLight.range = 1;
-                            options.lightRange = 1;
-                            directionalLight.range = 1;
-                            options.lightRange = 1;
-                            pointLight.range = 1;
-                            options.lightRange = 1;
-                            spotLight.range = 1;
 							break;
 						case "fur":
 							currentMaterial = fur.material;
@@ -329,7 +312,7 @@
                     directionalLight.range = options.lightRange;
                     pointLight.range = options.lightRange;
                     spotLight.range = options.lightRange;
-                }).listen();
+                });
                 
                 f1.add(options, 'lightRadius').onChange(function() {
                     hemisphericLight.radius = options.lightRadius;

文件差异内容过多而无法显示
+ 256 - 79
materialsLibrary/test/refs/babylon.max.js


+ 5 - 0
src/Cameras/VR/babylon.vrDeviceOrientationCamera.js

@@ -41,6 +41,11 @@ var BABYLON;
             _super.prototype.detachControl.call(this, element);
             window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
         };
+        VRDeviceOrientationFreeCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "VRDeviceOrientationFreeCamera";
+            return serializationObject;
+        };
         return VRDeviceOrientationFreeCamera;
     })(BABYLON.FreeCamera);
     BABYLON.VRDeviceOrientationFreeCamera = VRDeviceOrientationFreeCamera;

+ 8 - 0
src/Cameras/VR/babylon.vrDeviceOrientationCamera.ts

@@ -46,5 +46,13 @@ module BABYLON {
 
             window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+
+            serializationObject.type = "VRDeviceOrientationFreeCamera";
+
+            return serializationObject;
+        }
     }
 }

+ 5 - 0
src/Cameras/VR/babylon.webVRCamera.js

@@ -67,6 +67,11 @@ var BABYLON;
             _super.prototype.detachControl.call(this, element);
             this._vrEnabled = false;
         };
+        WebVRFreeCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "WebVRFreeCamera";
+            return serializationObject;
+        };
         return WebVRFreeCamera;
     })(BABYLON.FreeCamera);
     BABYLON.WebVRFreeCamera = WebVRFreeCamera;

+ 8 - 0
src/Cameras/VR/babylon.webVRCamera.ts

@@ -77,5 +77,13 @@ module BABYLON {
             super.detachControl(element);
             this._vrEnabled = false;
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+
+            serializationObject.type = "WebVRFreeCamera";
+
+            return serializationObject;
+        }
     }
 }

+ 7 - 0
src/Cameras/babylon.arcRotateCamera.js

@@ -70,6 +70,9 @@ var BABYLON;
                 var sina = Math.sin(_this.alpha);
                 var cosb = Math.cos(_this.beta);
                 var sinb = Math.sin(_this.beta);
+                if (sinb === 0) {
+                    sinb = 0.0001;
+                }
                 var target = _this._getTargetPosition();
                 target.addToRef(new BABYLON.Vector3(_this.radius * cosa * sinb, _this.radius * cosb, _this.radius * sina * sinb), _this._newPosition);
                 _this.position.copyFrom(_this._newPosition);
@@ -484,6 +487,9 @@ var BABYLON;
             var sina = Math.sin(this.alpha);
             var cosb = Math.cos(this.beta);
             var sinb = Math.sin(this.beta);
+            if (sinb === 0) {
+                sinb = 0.0001;
+            }
             var target = this._getTargetPosition();
             target.addToRef(new BABYLON.Vector3(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb), this._newPosition);
             if (this.getScene().collisionsEnabled && this.checkCollisions) {
@@ -570,6 +576,7 @@ var BABYLON;
         };
         ArcRotateCamera.prototype.serialize = function () {
             var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "ArcRotateCamera";
             if (this.target instanceof BABYLON.Vector3) {
                 serializationObject.target = this.target.asArray();
             }

+ 11 - 0
src/Cameras/babylon.arcRotateCamera.ts

@@ -533,6 +533,10 @@
             var cosb = Math.cos(this.beta);
             var sinb = Math.sin(this.beta);
 
+            if (sinb === 0) {
+                sinb = 0.0001;
+            }
+
             var target = this._getTargetPosition();
             target.addToRef(new Vector3(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb), this._newPosition);
             if (this.getScene().collisionsEnabled && this.checkCollisions) {
@@ -577,6 +581,11 @@
             var sina = Math.sin(this.alpha);
             var cosb = Math.cos(this.beta);
             var sinb = Math.sin(this.beta);
+
+            if (sinb === 0) {
+                sinb = 0.0001;
+            }
+
             var target = this._getTargetPosition();
             target.addToRef(new Vector3(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb), this._newPosition);
             this.position.copyFrom(this._newPosition);
@@ -668,6 +677,8 @@
         public serialize(): any {
             var serializationObject = super.serialize();
 
+            serializationObject.type = "ArcRotateCamera";
+
             if (this.target instanceof Vector3) {
                 serializationObject.target = this.target.asArray();
             }

+ 0 - 1
src/Cameras/babylon.camera.js

@@ -522,7 +522,6 @@ var BABYLON;
             serializationObject.tags = BABYLON.Tags.GetTags(this);
             serializationObject.id = this.id;
             serializationObject.position = this.position.asArray();
-            serializationObject.type = BABYLON.Tools.GetConstructorName(this);
             // Parent
             if (this.parent) {
                 serializationObject.parentId = this.parent.id;

+ 0 - 2
src/Cameras/babylon.camera.ts

@@ -592,8 +592,6 @@
             serializationObject.id = this.id;
             serializationObject.position = this.position.asArray();
 
-            serializationObject.type = Tools.GetConstructorName(this);
-
             // Parent
             if (this.parent) {
                 serializationObject.parentId = this.parent.id;

+ 5 - 0
src/Cameras/babylon.deviceOrientationCamera.js

@@ -65,6 +65,11 @@ var BABYLON;
             this.cameraDirection.addInPlace(BABYLON.Vector3.TransformCoordinates(direction, this._cameraRotationMatrix));
             _super.prototype._checkInputs.call(this);
         };
+        DeviceOrientationCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "DeviceOrientationCamera";
+            return serializationObject;
+        };
         return DeviceOrientationCamera;
     })(BABYLON.FreeCamera);
     BABYLON.DeviceOrientationCamera = DeviceOrientationCamera;

+ 8 - 0
src/Cameras/babylon.deviceOrientationCamera.ts

@@ -74,5 +74,13 @@ module BABYLON {
 
             super._checkInputs();
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+
+            serializationObject.type = "DeviceOrientationCamera";
+
+            return serializationObject;
+        }
     }
 }

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

@@ -57,6 +57,7 @@ var BABYLON;
         };
         FollowCamera.prototype.serialize = function () {
             var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "FollowCamera";
             serializationObject.radius = this.radius;
             serializationObject.heightOffset = this.heightOffset;
             serializationObject.rotationOffset = this.rotationOffset;
@@ -89,6 +90,7 @@ var BABYLON;
         };
         ArcFollowCamera.prototype.serialize = function () {
             var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "ArcFollowCamera";
             serializationObject.radius = this.radius;
             return serializationObject;
         };

+ 3 - 0
src/Cameras/babylon.followCamera.ts

@@ -62,6 +62,8 @@
 
         public serialize(): any {
             var serializationObject = super.serialize();
+
+            serializationObject.type = "FollowCamera";
        
             serializationObject.radius = this.radius;
             serializationObject.heightOffset = this.heightOffset;
@@ -97,6 +99,7 @@
         public serialize(): any {
             var serializationObject = super.serialize();
 
+            serializationObject.type = "ArcFollowCamera";
             serializationObject.radius = this.radius;
 
             return serializationObject;

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

@@ -224,6 +224,7 @@ var BABYLON;
         };
         FreeCamera.prototype.serialize = function () {
             var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "FreeCamera";
             serializationObject.checkCollisions = this.checkCollisions;
             serializationObject.applyGravity = this.applyGravity;
             serializationObject.ellipsoid = this.ellipsoid.asArray();

+ 1 - 0
src/Cameras/babylon.freeCamera.ts

@@ -267,6 +267,7 @@
         public serialize(): any {
             var serializationObject = super.serialize();
 
+            serializationObject.type = "FreeCamera";
             serializationObject.checkCollisions = this.checkCollisions;
             serializationObject.applyGravity = this.applyGravity;
             serializationObject.ellipsoid = this.ellipsoid.asArray();

+ 5 - 0
src/Cameras/babylon.gamepadCamera.js

@@ -12,6 +12,11 @@ var BABYLON;
             BABYLON.Tools.Warn("Deprecated. Please use Universal Camera instead.");
             _super.call(this, name, position, scene);
         }
+        GamepadCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "GamepadCamera";
+            return serializationObject;
+        };
         return GamepadCamera;
     })(BABYLON.UniversalCamera);
     BABYLON.GamepadCamera = GamepadCamera;

+ 8 - 0
src/Cameras/babylon.gamepadCamera.ts

@@ -5,5 +5,13 @@ module BABYLON {
             Tools.Warn("Deprecated. Please use Universal Camera instead.");
             super(name, position, scene);
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+
+            serializationObject.type = "GamepadCamera";
+
+            return serializationObject;
+        }
     }
 }

+ 30 - 0
src/Cameras/babylon.stereoscopicCameras.js

@@ -12,6 +12,11 @@ var BABYLON;
             this.interaxialDistance = interaxialDistance;
             this.setCameraRigMode(BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
         }
+        AnaglyphFreeCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "AnaglyphFreeCamera";
+            return serializationObject;
+        };
         return AnaglyphFreeCamera;
     })(BABYLON.FreeCamera);
     BABYLON.AnaglyphFreeCamera = AnaglyphFreeCamera;
@@ -21,6 +26,11 @@ var BABYLON;
             _super.call(this, name, alpha, beta, radius, target, scene);
             this.setCameraRigMode(BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
         }
+        AnaglyphArcRotateCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "AnaglyphArcRotateCamera";
+            return serializationObject;
+        };
         return AnaglyphArcRotateCamera;
     })(BABYLON.ArcRotateCamera);
     BABYLON.AnaglyphArcRotateCamera = AnaglyphArcRotateCamera;
@@ -30,6 +40,11 @@ var BABYLON;
             _super.call(this, name, position, scene);
             this.setCameraRigMode(BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
         }
+        AnaglyphGamepadCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "AnaglyphGamepadCamera";
+            return serializationObject;
+        };
         return AnaglyphGamepadCamera;
     })(BABYLON.GamepadCamera);
     BABYLON.AnaglyphGamepadCamera = AnaglyphGamepadCamera;
@@ -39,6 +54,11 @@ var BABYLON;
             _super.call(this, name, position, scene);
             this.setCameraRigMode(isSideBySide ? BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : BABYLON.Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
         }
+        StereoscopicFreeCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "StereoscopicFreeCamera";
+            return serializationObject;
+        };
         return StereoscopicFreeCamera;
     })(BABYLON.FreeCamera);
     BABYLON.StereoscopicFreeCamera = StereoscopicFreeCamera;
@@ -48,6 +68,11 @@ var BABYLON;
             _super.call(this, name, alpha, beta, radius, target, scene);
             this.setCameraRigMode(isSideBySide ? BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : BABYLON.Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
         }
+        StereoscopicArcRotateCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "StereoscopicArcRotateCamera";
+            return serializationObject;
+        };
         return StereoscopicArcRotateCamera;
     })(BABYLON.ArcRotateCamera);
     BABYLON.StereoscopicArcRotateCamera = StereoscopicArcRotateCamera;
@@ -57,6 +82,11 @@ var BABYLON;
             _super.call(this, name, position, scene);
             this.setCameraRigMode(isSideBySide ? BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : BABYLON.Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
         }
+        StereoscopicGamepadCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "StereoscopicGamepadCamera";
+            return serializationObject;
+        };
         return StereoscopicGamepadCamera;
     })(BABYLON.GamepadCamera);
     BABYLON.StereoscopicGamepadCamera = StereoscopicGamepadCamera;

+ 36 - 0
src/Cameras/babylon.stereoscopicCameras.ts

@@ -4,6 +4,12 @@
             super(name, position, scene);
             this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+            serializationObject.type = "AnaglyphFreeCamera";
+            return serializationObject;
+        }
     }
 
     export class AnaglyphArcRotateCamera extends ArcRotateCamera {
@@ -11,6 +17,12 @@
             super(name, alpha, beta, radius, target, scene);
             this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+            serializationObject.type = "AnaglyphArcRotateCamera";
+            return serializationObject;
+        }
     }
 
     export class AnaglyphGamepadCamera extends GamepadCamera {
@@ -18,6 +30,12 @@
             super(name, position, scene);
             this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+            serializationObject.type = "AnaglyphGamepadCamera";
+            return serializationObject;
+        }
     }
     
     export class StereoscopicFreeCamera extends FreeCamera {
@@ -26,6 +44,12 @@
 
             this.setCameraRigMode(isSideBySide ? Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+            serializationObject.type = "StereoscopicFreeCamera";
+            return serializationObject;
+        }
     }
 
     export class StereoscopicArcRotateCamera extends ArcRotateCamera {
@@ -33,6 +57,12 @@
             super(name, alpha, beta, radius, target, scene);
             this.setCameraRigMode(isSideBySide ? Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+            serializationObject.type = "StereoscopicArcRotateCamera";
+            return serializationObject;
+        }
     }
 
     export class StereoscopicGamepadCamera extends GamepadCamera {
@@ -40,5 +70,11 @@
             super(name, position, scene);
             this.setCameraRigMode(isSideBySide ? Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+            serializationObject.type = "StereoscopicGamepadCamera";
+            return serializationObject;
+        }
     }
 } 

+ 1 - 0
src/Cameras/babylon.targetCamera.js

@@ -243,6 +243,7 @@ var BABYLON;
         TargetCamera.prototype.serialize = function () {
             var serializationObject = _super.prototype.serialize.call(this);
             serializationObject.speed = this.speed;
+            serializationObject.type = "TargetCamera";
             if (this.rotation) {
                 serializationObject.rotation = this.rotation.asArray();
             }

+ 1 - 0
src/Cameras/babylon.targetCamera.ts

@@ -300,6 +300,7 @@
         public serialize(): any {
             var serializationObject = super.serialize();
             serializationObject.speed = this.speed;
+            serializationObject.type = "TargetCamera";
 
             if (this.rotation) {
                 serializationObject.rotation = this.rotation.asArray();

+ 5 - 0
src/Cameras/babylon.touchCamera.js

@@ -113,6 +113,11 @@ var BABYLON;
             }
             _super.prototype._checkInputs.call(this);
         };
+        TouchCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "TouchCamera";
+            return serializationObject;
+        };
         return TouchCamera;
     })(BABYLON.FreeCamera);
     BABYLON.TouchCamera = TouchCamera;

+ 8 - 0
src/Cameras/babylon.touchCamera.ts

@@ -145,5 +145,13 @@ module BABYLON {
 
             super._checkInputs();
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+
+            serializationObject.type = "TouchCamera";
+
+            return serializationObject;
+        }
     }
 }

+ 5 - 0
src/Cameras/babylon.universalCamera.js

@@ -51,6 +51,11 @@ var BABYLON;
             this._gamepads.dispose();
             _super.prototype.dispose.call(this);
         };
+        UniversalCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "UniversalCamera";
+            return serializationObject;
+        };
         return UniversalCamera;
     })(BABYLON.TouchCamera);
     BABYLON.UniversalCamera = UniversalCamera;

+ 8 - 0
src/Cameras/babylon.universalCamera.ts

@@ -54,5 +54,13 @@ module BABYLON {
             this._gamepads.dispose();
             super.dispose();
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+
+            serializationObject.type = "UniversalCamera";
+
+            return serializationObject;
+        }
     }
 }

+ 5 - 0
src/Cameras/babylon.virtualJoysticksCamera.js

@@ -45,6 +45,11 @@ var BABYLON;
             this._leftjoystick.releaseCanvas();
             _super.prototype.dispose.call(this);
         };
+        VirtualJoysticksCamera.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            serializationObject.type = "VirtualJoysticksCamera";
+            return serializationObject;
+        };
         return VirtualJoysticksCamera;
     })(BABYLON.FreeCamera);
     BABYLON.VirtualJoysticksCamera = VirtualJoysticksCamera;

+ 8 - 0
src/Cameras/babylon.virtualJoysticksCamera.ts

@@ -46,5 +46,13 @@
             this._leftjoystick.releaseCanvas();
             super.dispose();
         }
+
+        public serialize(): any {
+            var serializationObject = super.serialize();
+
+            serializationObject.type = "VirtualJoysticksCamera";
+
+            return serializationObject;
+        }
     }
 }

+ 3 - 1
src/Materials/Textures/babylon.texture.js

@@ -41,6 +41,8 @@ var BABYLON;
                 }
                 else {
                     this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+                    this._delayedOnLoad = onLoad;
+                    this._delayedOnError = onError;
                 }
             }
             else {
@@ -58,7 +60,7 @@ var BABYLON;
             this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
             this._texture = this._getFromCache(this.url, this._noMipmap, this._samplingMode);
             if (!this._texture) {
-                this._texture = this.getScene().getEngine().createTexture(this.url, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, null, null, this._buffer);
+                this._texture = this.getScene().getEngine().createTexture(this.url, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, this._delayedOnLoad, this._delayedOnError, this._buffer);
                 if (this._deleteBuffer) {
                     delete this._buffer;
                 }

+ 6 - 1
src/Materials/Textures/babylon.texture.ts

@@ -49,6 +49,8 @@
         public _samplingMode: number;
         private _buffer: any;
         private _deleteBuffer: boolean;
+        private _delayedOnLoad: () => void;
+        private _delayedOnError: () => void;
 
         constructor(url: string, scene: Scene, noMipmap?: boolean, invertY?: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null, deleteBuffer: boolean = false) {
             super(scene);
@@ -75,6 +77,9 @@
                     }
                 } else {
                     this.delayLoadState = Engine.DELAYLOADSTATE_NOTLOADED;
+
+                    this._delayedOnLoad = onLoad;
+                    this._delayedOnError = onError;
                 }
             } else {
                 Tools.SetImmediate(() => {
@@ -94,7 +99,7 @@
             this._texture = this._getFromCache(this.url, this._noMipmap, this._samplingMode);
 
             if (!this._texture) {
-                this._texture = this.getScene().getEngine().createTexture(this.url, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, null, null, this._buffer);
+                this._texture = this.getScene().getEngine().createTexture(this.url, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, this._delayedOnLoad, this._delayedOnError, this._buffer);
                 if (this._deleteBuffer) {
                     delete this._buffer;
                 }

+ 37 - 0
src/Materials/babylon.fresnelParameters.js

@@ -0,0 +1,37 @@
+var BABYLON;
+(function (BABYLON) {
+    var FresnelParameters = (function () {
+        function FresnelParameters() {
+            this.isEnabled = true;
+            this.leftColor = BABYLON.Color3.White();
+            this.rightColor = BABYLON.Color3.Black();
+            this.bias = 0;
+            this.power = 1;
+        }
+        FresnelParameters.prototype.clone = function () {
+            var newFresnelParameters = new FresnelParameters();
+            BABYLON.Tools.DeepCopy(this, newFresnelParameters);
+            return new FresnelParameters;
+        };
+        FresnelParameters.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.isEnabled = this.isEnabled;
+            serializationObject.leftColor = this.leftColor;
+            serializationObject.rightColor = this.rightColor;
+            serializationObject.bias = this.bias;
+            serializationObject.power = this.power;
+            return serializationObject;
+        };
+        FresnelParameters.Parse = function (parsedFresnelParameters) {
+            var fresnelParameters = new FresnelParameters();
+            fresnelParameters.isEnabled = parsedFresnelParameters.isEnabled;
+            fresnelParameters.leftColor = BABYLON.Color3.FromArray(parsedFresnelParameters.leftColor);
+            fresnelParameters.rightColor = BABYLON.Color3.FromArray(parsedFresnelParameters.rightColor);
+            fresnelParameters.bias = parsedFresnelParameters.bias;
+            fresnelParameters.power = parsedFresnelParameters.power || 1.0;
+            return fresnelParameters;
+        };
+        return FresnelParameters;
+    })();
+    BABYLON.FresnelParameters = FresnelParameters;
+})(BABYLON || (BABYLON = {}));

+ 41 - 0
src/Materials/babylon.fresnelParameters.ts

@@ -0,0 +1,41 @@
+module BABYLON {
+    export class FresnelParameters {
+        public isEnabled = true;
+        public leftColor = Color3.White();
+        public rightColor = Color3.Black();
+        public bias = 0;
+        public power = 1;
+
+        public clone(): FresnelParameters {
+            var newFresnelParameters = new FresnelParameters();
+
+            Tools.DeepCopy(this, newFresnelParameters);
+
+            return new FresnelParameters;
+        }
+
+        public serialize(): any {
+            var serializationObject: any = {};
+
+            serializationObject.isEnabled = this.isEnabled;
+            serializationObject.leftColor = this.leftColor;
+            serializationObject.rightColor = this.rightColor;
+            serializationObject.bias = this.bias;
+            serializationObject.power = this.power;
+
+            return serializationObject;
+        }
+
+        public static Parse(parsedFresnelParameters: any): FresnelParameters {
+            var fresnelParameters = new FresnelParameters();
+
+            fresnelParameters.isEnabled = parsedFresnelParameters.isEnabled;
+            fresnelParameters.leftColor = Color3.FromArray(parsedFresnelParameters.leftColor);
+            fresnelParameters.rightColor = Color3.FromArray(parsedFresnelParameters.rightColor);
+            fresnelParameters.bias = parsedFresnelParameters.bias;
+            fresnelParameters.power = parsedFresnelParameters.power || 1.0;
+
+            return fresnelParameters;
+        }
+    }
+}

+ 54 - 26
src/Materials/babylon.material.js

@@ -1,3 +1,9 @@
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
 var BABYLON;
 (function (BABYLON) {
     var MaterialDefines = (function () {
@@ -57,10 +63,10 @@ var BABYLON;
             this.alphaMode = BABYLON.Engine.ALPHA_COMBINE;
             this.disableDepthWrite = false;
             this.fogEnabled = true;
-            this._wasPreviouslyReady = false;
-            this._fillMode = Material.TriangleFillMode;
             this.pointSize = 1.0;
             this.zOffset = 0;
+            this._wasPreviouslyReady = false;
+            this._fillMode = Material.TriangleFillMode;
             this.id = name;
             this._scene = scene;
             if (!doNotAdd) {
@@ -230,31 +236,8 @@ var BABYLON;
                 this.onDispose();
             }
         };
-        Material.prototype.copyTo = function (other) {
-            other.checkReadyOnlyOnce = this.checkReadyOnlyOnce;
-            other.checkReadyOnEveryCall = this.checkReadyOnEveryCall;
-            other.alpha = this.alpha;
-            other.fillMode = this.fillMode;
-            other.backFaceCulling = this.backFaceCulling;
-            other.fogEnabled = this.fogEnabled;
-            other.wireframe = this.wireframe;
-            other.zOffset = this.zOffset;
-            other.alphaMode = this.alphaMode;
-            other.sideOrientation = this.sideOrientation;
-            other.disableDepthWrite = this.disableDepthWrite;
-            other.pointSize = this.pointSize;
-            other.pointsCloud = this.pointsCloud;
-        };
         Material.prototype.serialize = function () {
-            var serializationObject = {};
-            serializationObject.name = this.name;
-            serializationObject.alpha = this.alpha;
-            serializationObject.id = this.id;
-            serializationObject.tags = BABYLON.Tags.GetTags(this);
-            serializationObject.backFaceCulling = this.backFaceCulling;
-            serializationObject.checkReadyOnlyOnce = this.checkReadyOnlyOnce;
-            serializationObject.disableDepthWrite = this.disableDepthWrite;
-            return serializationObject;
+            return BABYLON.SerializationHelper.Serialize(this);
         };
         Material.ParseMultiMaterial = function (parsedMultiMaterial, scene) {
             var multiMaterial = new BABYLON.MultiMaterial(parsedMultiMaterial.name, scene);
@@ -284,6 +267,51 @@ var BABYLON;
         Material._PointFillMode = 2;
         Material._ClockWiseSideOrientation = 0;
         Material._CounterClockWiseSideOrientation = 1;
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "id", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "checkReadyOnEveryCall", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "checkReadyOnlyOnce", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "state", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "alpha", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "backFaceCulling", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "sideOrientation", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "alphaMode", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "disableDepthWrite", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "fogEnabled", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "pointSize", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "zOffset", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "wireframe", null);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "pointsCloud", null);
+        __decorate([
+            BABYLON.serialize()
+        ], Material.prototype, "fillMode", null);
         return Material;
     })();
     BABYLON.Material = Material;

+ 33 - 34
src/Materials/babylon.material.ts

@@ -80,32 +80,49 @@
             return Material._CounterClockWiseSideOrientation;
         }
 
+        @serialize()
         public id: string;
+
+        @serialize()
         public checkReadyOnEveryCall = false;
+
+        @serialize()
         public checkReadyOnlyOnce = false;
+
+        @serialize()
         public state = "";
+
+        @serialize()
         public alpha = 1.0;
+
+        @serialize()
         public backFaceCulling = true;
+
+        @serialize()
         public sideOrientation = Material.CounterClockWiseSideOrientation;
+
         public onCompiled: (effect: Effect) => void;
         public onError: (effect: Effect, errors: string) => void;
         public onDispose: () => void;
         public onBind: (material: Material, mesh: Mesh) => void;
         public getRenderTargetTextures: () => SmartArray<RenderTargetTexture>;
+
+        @serialize()
         public alphaMode = Engine.ALPHA_COMBINE;
+
+        @serialize()
         public disableDepthWrite = false;
-        public fogEnabled = true;
 
-        public _effect: Effect;
-        public _wasPreviouslyReady = false;
-        private _scene: Scene;
-        private _fillMode = Material.TriangleFillMode;
-        private _cachedDepthWriteState: boolean;
+        @serialize()
+        public fogEnabled = true;
 
+        @serialize()
         public pointSize = 1.0;
 
+        @serialize()
         public zOffset = 0;
 
+        @serialize()
         public get wireframe(): boolean {
             return this._fillMode === Material.WireFrameFillMode;
         }
@@ -114,6 +131,7 @@
             this._fillMode = (value ? Material.WireFrameFillMode : Material.TriangleFillMode);
         }
 
+        @serialize()
         public get pointsCloud(): boolean {
             return this._fillMode === Material.PointFillMode;
         }
@@ -122,6 +140,7 @@
             this._fillMode = (value ? Material.PointFillMode : Material.TriangleFillMode);
         }
 
+        @serialize()
         public get fillMode(): number {
             return this._fillMode;
         }
@@ -130,6 +149,13 @@
             this._fillMode = value;
         }
 
+        public _effect: Effect;
+        public _wasPreviouslyReady = false;
+        private _scene: Scene;
+        private _fillMode = Material.TriangleFillMode;
+        private _cachedDepthWriteState: boolean;
+
+
         constructor(public name: string, scene: Scene, doNotAdd?: boolean) {
             this.id = name;
 
@@ -263,35 +289,8 @@
             }
         }
 
-        public copyTo(other: Material): void {
-            other.checkReadyOnlyOnce = this.checkReadyOnlyOnce;
-            other.checkReadyOnEveryCall = this.checkReadyOnEveryCall;
-            other.alpha = this.alpha;
-            other.fillMode = this.fillMode;
-            other.backFaceCulling = this.backFaceCulling;
-            other.fogEnabled = this.fogEnabled;
-            other.wireframe = this.wireframe;
-            other.zOffset = this.zOffset;
-            other.alphaMode = this.alphaMode;
-            other.sideOrientation = this.sideOrientation;
-            other.disableDepthWrite = this.disableDepthWrite;
-            other.pointSize = this.pointSize;
-            other.pointsCloud = this.pointsCloud;
-        }
-
         public serialize(): any {
-            var serializationObject: any = {};
-
-            serializationObject.name = this.name;
-            serializationObject.alpha = this.alpha;
-
-            serializationObject.id = this.id;
-            serializationObject.tags = Tags.GetTags(this);
-            serializationObject.backFaceCulling = this.backFaceCulling;
-            serializationObject.checkReadyOnlyOnce = this.checkReadyOnlyOnce;
-            serializationObject.disableDepthWrite = this.disableDepthWrite;
-
-            return serializationObject;
+            return SerializationHelper.Serialize(this);
         }
 
         public static ParseMultiMaterial(parsedMultiMaterial: any, scene: Scene): MultiMaterial {

+ 3 - 3
src/Materials/babylon.shaderMaterial.js

@@ -227,10 +227,10 @@ var BABYLON;
             _super.prototype.dispose.call(this, forceDisposeEffect);
         };
         ShaderMaterial.prototype.serialize = function () {
-            var serializationObject = _super.prototype.serialize.call(this);
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.ShaderMaterial";
             serializationObject.options = this._options;
             serializationObject.shaderPath = this._shaderPath;
-            serializationObject.customType = "BABYLON.ShaderMaterial";
             // Texture
             serializationObject.textures = {};
             for (var name in this._textures) {
@@ -289,7 +289,7 @@ var BABYLON;
             return serializationObject;
         };
         ShaderMaterial.Parse = function (source, scene, rootUrl) {
-            var material = new ShaderMaterial(source.name, scene, source.shaderPath, source.options);
+            var material = BABYLON.SerializationHelper.Parse(function () { return new ShaderMaterial(source.name, scene, source.shaderPath, source.options); }, source, scene, rootUrl);
             // Texture
             for (var name in source.textures) {
                 material.setTexture(name, BABYLON.Texture.Parse(source.textures[name], scene, rootUrl));

+ 5 - 4
src/Materials/babylon.shaderMaterial.ts

@@ -294,11 +294,12 @@
         }
 
         public serialize(): any {
-            var serializationObject = super.serialize();
-            serializationObject.options = this._options;
-            serializationObject.shaderPath = this._shaderPath;
+            var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.ShaderMaterial";
 			
+            serializationObject.options = this._options;
+            serializationObject.shaderPath = this._shaderPath;
+
             // Texture
             serializationObject.textures = {};
             for (var name in this._textures) {
@@ -369,7 +370,7 @@
         }
 
         public static Parse(source: any, scene: Scene, rootUrl: string): ShaderMaterial {
-            var material = new ShaderMaterial(source.name, scene, source.shaderPath, source.options);
+            var material = SerializationHelper.Parse(() => new ShaderMaterial(source.name, scene, source.shaderPath, source.options), source, scene, rootUrl);
 			
             // Texture
             for (var name in source.textures) {

+ 113 - 219
src/Materials/babylon.standardMaterial.js

@@ -3,42 +3,14 @@ var __extends = (this && this.__extends) || function (d, b) {
     function __() { this.constructor = d; }
     d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
 };
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
 var BABYLON;
 (function (BABYLON) {
-    var FresnelParameters = (function () {
-        function FresnelParameters() {
-            this.isEnabled = true;
-            this.leftColor = BABYLON.Color3.White();
-            this.rightColor = BABYLON.Color3.Black();
-            this.bias = 0;
-            this.power = 1;
-        }
-        FresnelParameters.prototype.clone = function () {
-            var newFresnelParameters = new FresnelParameters();
-            BABYLON.Tools.DeepCopy(this, newFresnelParameters);
-            return new FresnelParameters;
-        };
-        FresnelParameters.prototype.serialize = function () {
-            var serializationObject = {};
-            serializationObject.isEnabled = this.isEnabled;
-            serializationObject.leftColor = this.leftColor;
-            serializationObject.rightColor = this.rightColor;
-            serializationObject.bias = this.bias;
-            serializationObject.power = this.power;
-            return serializationObject;
-        };
-        FresnelParameters.Parse = function (parsedFresnelParameters) {
-            var fresnelParameters = new FresnelParameters();
-            fresnelParameters.isEnabled = parsedFresnelParameters.isEnabled;
-            fresnelParameters.leftColor = BABYLON.Color3.FromArray(parsedFresnelParameters.leftColor);
-            fresnelParameters.rightColor = BABYLON.Color3.FromArray(parsedFresnelParameters.rightColor);
-            fresnelParameters.bias = parsedFresnelParameters.bias;
-            fresnelParameters.power = parsedFresnelParameters.power || 1.0;
-            return fresnelParameters;
-        };
-        return FresnelParameters;
-    })();
-    BABYLON.FresnelParameters = FresnelParameters;
     var StandardMaterialDefines = (function (_super) {
         __extends(StandardMaterialDefines, _super);
         function StandardMaterialDefines() {
@@ -125,6 +97,7 @@ var BABYLON;
             this.LOGARITHMICDEPTH = false;
             this.REFRACTION = false;
             this.REFRACTIONMAP_3D = false;
+            this.REFLECTIONOVERALPHA = false;
             this._keys = Object.keys(this);
         }
         return StandardMaterialDefines;
@@ -137,13 +110,14 @@ var BABYLON;
             this.ambientColor = new BABYLON.Color3(0, 0, 0);
             this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             this.specularColor = new BABYLON.Color3(1, 1, 1);
-            this.specularPower = 64;
             this.emissiveColor = new BABYLON.Color3(0, 0, 0);
+            this.specularPower = 64;
             this.useAlphaFromDiffuseTexture = false;
             this.useEmissiveAsIllumination = false;
             this.linkEmissiveWithDiffuse = false;
             this.useReflectionFresnelFromSpecular = false;
             this.useSpecularOverAlpha = false;
+            this.useReflectionOverAlpha = false;
             this.disableLighting = false;
             this.roughness = 0;
             this.indexOfRefraction = 0.98;
@@ -262,6 +236,9 @@ var BABYLON;
                         if (this.roughness > 0) {
                             this._defines.ROUGHNESS = true;
                         }
+                        if (this.useReflectionOverAlpha) {
+                            this._defines.REFLECTIONOVERALPHA = true;
+                        }
                         if (this.reflectionTexture.coordinatesMode === BABYLON.Texture.INVCUBIC_MODE) {
                             this._defines.INVERTCUBICMAP = true;
                         }
@@ -360,9 +337,6 @@ var BABYLON;
             if (this.linkEmissiveWithDiffuse) {
                 this._defines.LINKEMISSIVEWITHDIFFUSE = true;
             }
-            if (this.useReflectionFresnelFromSpecular) {
-                this._defines.REFLECTIONFRESNELFROMSPECULAR = true;
-            }
             if (this.useLogarithmicDepth) {
                 this._defines.LOGARITHMICDEPTH = true;
             }
@@ -392,6 +366,9 @@ var BABYLON;
                     }
                     if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
                         this._defines.REFLECTIONFRESNEL = true;
+                        if (this.useReflectionFresnelFromSpecular) {
+                            this._defines.REFLECTIONFRESNELFROMSPECULAR = true;
+                        }
                     }
                     if (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) {
                         this._defines.REFRACTIONFRESNEL = true;
@@ -730,192 +707,16 @@ var BABYLON;
             _super.prototype.dispose.call(this, forceDisposeEffect);
         };
         StandardMaterial.prototype.clone = function (name) {
-            var newStandardMaterial = new StandardMaterial(name, this.getScene());
-            // Base material
-            this.copyTo(newStandardMaterial);
-            // Standard material
-            if (this.diffuseTexture && this.diffuseTexture.clone) {
-                newStandardMaterial.diffuseTexture = this.diffuseTexture.clone();
-            }
-            if (this.ambientTexture && this.ambientTexture.clone) {
-                newStandardMaterial.ambientTexture = this.ambientTexture.clone();
-            }
-            if (this.opacityTexture && this.opacityTexture.clone) {
-                newStandardMaterial.opacityTexture = this.opacityTexture.clone();
-            }
-            if (this.reflectionTexture && this.reflectionTexture.clone) {
-                newStandardMaterial.reflectionTexture = this.reflectionTexture.clone();
-            }
-            if (this.emissiveTexture && this.emissiveTexture.clone) {
-                newStandardMaterial.emissiveTexture = this.emissiveTexture.clone();
-            }
-            if (this.specularTexture && this.specularTexture.clone) {
-                newStandardMaterial.specularTexture = this.specularTexture.clone();
-            }
-            if (this.bumpTexture && this.bumpTexture.clone) {
-                newStandardMaterial.bumpTexture = this.bumpTexture.clone();
-            }
-            if (this.lightmapTexture && this.lightmapTexture.clone) {
-                newStandardMaterial.lightmapTexture = this.lightmapTexture.clone();
-                newStandardMaterial.useLightmapAsShadowmap = this.useLightmapAsShadowmap;
-            }
-            if (this.refractionTexture && this.refractionTexture.clone) {
-                newStandardMaterial.refractionTexture = this.refractionTexture.clone();
-            }
-            newStandardMaterial.ambientColor = this.ambientColor.clone();
-            newStandardMaterial.diffuseColor = this.diffuseColor.clone();
-            newStandardMaterial.specularColor = this.specularColor.clone();
-            newStandardMaterial.specularPower = this.specularPower;
-            newStandardMaterial.emissiveColor = this.emissiveColor.clone();
-            newStandardMaterial.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
-            newStandardMaterial.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            newStandardMaterial.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
-            newStandardMaterial.useReflectionFresnelFromSpecular = this.useReflectionFresnelFromSpecular;
-            newStandardMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
-            newStandardMaterial.roughness = this.roughness;
-            newStandardMaterial.indexOfRefraction = this.indexOfRefraction;
-            newStandardMaterial.invertRefractionY = this.invertRefractionY;
-            if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.clone) {
-                newStandardMaterial.diffuseFresnelParameters = this.diffuseFresnelParameters.clone();
-            }
-            if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.clone) {
-                newStandardMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
-            }
-            if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.clone) {
-                newStandardMaterial.reflectionFresnelParameters = this.reflectionFresnelParameters.clone();
-            }
-            if (this.refractionFresnelParameters && this.refractionFresnelParameters.clone) {
-                newStandardMaterial.refractionFresnelParameters = this.refractionFresnelParameters.clone();
-            }
-            if (this.opacityFresnelParameters && this.opacityFresnelParameters.clone) {
-                newStandardMaterial.opacityFresnelParameters = this.opacityFresnelParameters.clone();
-            }
-            return newStandardMaterial;
+            var _this = this;
+            return BABYLON.SerializationHelper.Clone(function () { return new StandardMaterial(name, _this.getScene()); }, this);
         };
         StandardMaterial.prototype.serialize = function () {
-            var serializationObject = _super.prototype.serialize.call(this);
-            serializationObject.ambient = this.ambientColor.asArray();
-            serializationObject.diffuse = this.diffuseColor.asArray();
-            serializationObject.specular = this.specularColor.asArray();
-            serializationObject.specularPower = this.specularPower;
-            serializationObject.emissive = this.emissiveColor.asArray();
-            serializationObject.useReflectionFresnelFromSpecular = this.useReflectionFresnelFromSpecular;
-            serializationObject.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            serializationObject.indexOfRefraction = this.indexOfRefraction;
-            serializationObject.invertRefractionY = this.invertRefractionY;
-            if (this.diffuseTexture) {
-                serializationObject.diffuseTexture = this.diffuseTexture.serialize();
-            }
-            if (this.diffuseFresnelParameters) {
-                serializationObject.diffuseFresnelParameters = this.diffuseFresnelParameters.serialize();
-            }
-            if (this.ambientTexture) {
-                serializationObject.ambientTexture = this.ambientTexture.serialize();
-            }
-            if (this.opacityTexture) {
-                serializationObject.opacityTexture = this.opacityTexture.serialize();
-            }
-            if (this.opacityFresnelParameters) {
-                serializationObject.opacityFresnelParameters = this.diffuseFresnelParameters.serialize();
-            }
-            if (this.reflectionTexture) {
-                serializationObject.reflectionTexture = this.reflectionTexture.serialize();
-            }
-            if (this.reflectionFresnelParameters) {
-                serializationObject.reflectionFresnelParameters = this.reflectionFresnelParameters.serialize();
-            }
-            if (this.refractionFresnelParameters) {
-                serializationObject.refractionFresnelParameters = this.refractionFresnelParameters.serialize();
-            }
-            if (this.emissiveTexture) {
-                serializationObject.emissiveTexture = this.emissiveTexture.serialize();
-            }
-            if (this.lightmapTexture) {
-                serializationObject.lightmapTexture = this.lightmapTexture.serialize();
-                serializationObject.useLightmapAsShadowmap = this.useLightmapAsShadowmap;
-            }
-            if (this.emissiveFresnelParameters) {
-                serializationObject.emissiveFresnelParameters = this.emissiveFresnelParameters.serialize();
-            }
-            if (this.specularTexture) {
-                serializationObject.specularTexture = this.specularTexture.serialize();
-            }
-            if (this.bumpTexture) {
-                serializationObject.bumpTexture = this.bumpTexture.serialize();
-            }
-            if (this.refractionTexture) {
-                serializationObject.refractionTexture = this.refractionTexture.serialize();
-            }
-            return serializationObject;
+            return BABYLON.SerializationHelper.Serialize(this);
         };
+        // Statics
         StandardMaterial.Parse = function (source, scene, rootUrl) {
-            var material = new StandardMaterial(source.name, scene);
-            material.ambientColor = BABYLON.Color3.FromArray(source.ambient);
-            material.diffuseColor = BABYLON.Color3.FromArray(source.diffuse);
-            material.specularColor = BABYLON.Color3.FromArray(source.specular);
-            material.specularPower = source.specularPower;
-            material.emissiveColor = BABYLON.Color3.FromArray(source.emissive);
-            material.useReflectionFresnelFromSpecular = source.useReflectionFresnelFromSpecular;
-            material.useEmissiveAsIllumination = source.useEmissiveAsIllumination;
-            material.indexOfRefraction = source.indexOfRefraction;
-            material.invertRefractionY = source.invertRefractionY;
-            material.alpha = source.alpha;
-            material.id = source.id;
-            if (source.disableDepthWrite) {
-                material.disableDepthWrite = source.disableDepthWrite;
-            }
-            BABYLON.Tags.AddTagsTo(material, source.tags);
-            material.backFaceCulling = source.backFaceCulling;
-            material.wireframe = source.wireframe;
-            if (source.diffuseTexture) {
-                material.diffuseTexture = BABYLON.Texture.Parse(source.diffuseTexture, scene, rootUrl);
-            }
-            if (source.diffuseFresnelParameters) {
-                material.diffuseFresnelParameters = FresnelParameters.Parse(source.diffuseFresnelParameters);
-            }
-            if (source.ambientTexture) {
-                material.ambientTexture = BABYLON.Texture.Parse(source.ambientTexture, scene, rootUrl);
-            }
-            if (source.opacityTexture) {
-                material.opacityTexture = BABYLON.Texture.Parse(source.opacityTexture, scene, rootUrl);
-            }
-            if (source.opacityFresnelParameters) {
-                material.opacityFresnelParameters = FresnelParameters.Parse(source.opacityFresnelParameters);
-            }
-            if (source.reflectionTexture) {
-                material.reflectionTexture = BABYLON.Texture.Parse(source.reflectionTexture, scene, rootUrl);
-            }
-            if (source.reflectionFresnelParameters) {
-                material.reflectionFresnelParameters = FresnelParameters.Parse(source.reflectionFresnelParameters);
-            }
-            if (source.refractionFresnelParameters) {
-                material.refractionFresnelParameters = FresnelParameters.Parse(source.refractionFresnelParameters);
-            }
-            if (source.emissiveTexture) {
-                material.emissiveTexture = BABYLON.Texture.Parse(source.emissiveTexture, scene, rootUrl);
-            }
-            if (source.lightmapTexture) {
-                material.lightmapTexture = BABYLON.Texture.Parse(source.lightmapTexture, scene, rootUrl);
-                material.useLightmapAsShadowmap = source.useLightmapAsShadowmap;
-            }
-            if (source.emissiveFresnelParameters) {
-                material.emissiveFresnelParameters = FresnelParameters.Parse(source.emissiveFresnelParameters);
-            }
-            if (source.specularTexture) {
-                material.specularTexture = BABYLON.Texture.Parse(source.specularTexture, scene, rootUrl);
-            }
-            if (source.bumpTexture) {
-                material.bumpTexture = BABYLON.Texture.Parse(source.bumpTexture, scene, rootUrl);
-            }
-            if (source.refractionTexture) {
-                material.refractionTexture = BABYLON.Texture.Parse(source.refractionTexture, scene, rootUrl);
-            }
-            if (source.checkReadyOnlyOnce) {
-                material.checkReadyOnlyOnce = source.checkReadyOnlyOnce;
-            }
-            return material;
+            return BABYLON.SerializationHelper.Parse(function () { return new StandardMaterial(source.name, scene); }, source, scene, rootUrl);
         };
-        // Statics
         // Flags used to enable or disable a type of texture for all Standard Materials
         StandardMaterial.DiffuseTextureEnabled = true;
         StandardMaterial.AmbientTextureEnabled = true;
@@ -927,6 +728,99 @@ var BABYLON;
         StandardMaterial.FresnelEnabled = true;
         StandardMaterial.LightmapTextureEnabled = true;
         StandardMaterial.RefractionTextureEnabled = true;
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "diffuseTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "ambientTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "opacityTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "reflectionTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "emissiveTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "specularTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "bumpTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "lightmapTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsTexture()
+        ], StandardMaterial.prototype, "refractionTexture", void 0);
+        __decorate([
+            BABYLON.serializeAsColor3("ambient")
+        ], StandardMaterial.prototype, "ambientColor", void 0);
+        __decorate([
+            BABYLON.serializeAsColor3("diffuse")
+        ], StandardMaterial.prototype, "diffuseColor", void 0);
+        __decorate([
+            BABYLON.serializeAsColor3("specular")
+        ], StandardMaterial.prototype, "specularColor", void 0);
+        __decorate([
+            BABYLON.serializeAsColor3("emissive")
+        ], StandardMaterial.prototype, "emissiveColor", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "specularPower", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "useAlphaFromDiffuseTexture", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "useEmissiveAsIllumination", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "linkEmissiveWithDiffuse", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "useReflectionFresnelFromSpecular", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "useSpecularOverAlpha", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "useReflectionOverAlpha", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "disableLighting", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "roughness", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "indexOfRefraction", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "invertRefractionY", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "useLightmapAsShadowmap", void 0);
+        __decorate([
+            BABYLON.serializeAsFresnelParameters()
+        ], StandardMaterial.prototype, "diffuseFresnelParameters", void 0);
+        __decorate([
+            BABYLON.serializeAsFresnelParameters()
+        ], StandardMaterial.prototype, "opacityFresnelParameters", void 0);
+        __decorate([
+            BABYLON.serializeAsFresnelParameters()
+        ], StandardMaterial.prototype, "reflectionFresnelParameters", void 0);
+        __decorate([
+            BABYLON.serializeAsFresnelParameters()
+        ], StandardMaterial.prototype, "refractionFresnelParameters", void 0);
+        __decorate([
+            BABYLON.serializeAsFresnelParameters()
+        ], StandardMaterial.prototype, "emissiveFresnelParameters", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], StandardMaterial.prototype, "useGlossinessFromSpecularMapAlpha", void 0);
         return StandardMaterial;
     })(BABYLON.Material);
     BABYLON.StandardMaterial = StandardMaterial;

+ 73 - 271
src/Materials/babylon.standardMaterial.ts

@@ -1,44 +1,4 @@
-module BABYLON {
-    export class FresnelParameters {
-        public isEnabled = true;
-        public leftColor = Color3.White();
-        public rightColor = Color3.Black();
-        public bias = 0;
-        public power = 1;
-
-        public clone(): FresnelParameters {
-            var newFresnelParameters = new FresnelParameters();
-
-            Tools.DeepCopy(this, newFresnelParameters);
-
-            return new FresnelParameters;
-        }
-
-        public serialize(): any {
-            var serializationObject: any = {};
-
-            serializationObject.isEnabled = this.isEnabled;
-            serializationObject.leftColor = this.leftColor;
-            serializationObject.rightColor = this.rightColor;
-            serializationObject.bias = this.bias;
-            serializationObject.power = this.power;
-
-            return serializationObject;
-        }
-
-        public static Parse(parsedFresnelParameters: any): FresnelParameters {
-            var fresnelParameters = new FresnelParameters();
-
-            fresnelParameters.isEnabled = parsedFresnelParameters.isEnabled;
-            fresnelParameters.leftColor = Color3.FromArray(parsedFresnelParameters.leftColor);
-            fresnelParameters.rightColor = Color3.FromArray(parsedFresnelParameters.rightColor);
-            fresnelParameters.bias = parsedFresnelParameters.bias;
-            fresnelParameters.power = parsedFresnelParameters.power || 1.0;
-
-            return fresnelParameters;
-        }
-    }
-
+module BABYLON {   
     class StandardMaterialDefines extends MaterialDefines {
         public DIFFUSE = false;
         public AMBIENT = false;
@@ -122,6 +82,7 @@
         public LOGARITHMICDEPTH = false;
         public REFRACTION = false;
         public REFRACTIONMAP_3D = false;
+        public REFLECTIONOVERALPHA = false;
 
         constructor() {
             super();
@@ -130,41 +91,97 @@
     }
 
     export class StandardMaterial extends Material {
+        @serializeAsTexture()
         public diffuseTexture: BaseTexture;
+
+        @serializeAsTexture()
         public ambientTexture: BaseTexture;
+
+        @serializeAsTexture()
         public opacityTexture: BaseTexture;
+
+        @serializeAsTexture()
         public reflectionTexture: BaseTexture;
+
+        @serializeAsTexture()
         public emissiveTexture: BaseTexture;
+
+        @serializeAsTexture()
         public specularTexture: BaseTexture;
+
+        @serializeAsTexture()
         public bumpTexture: BaseTexture;
+
+        @serializeAsTexture()
         public lightmapTexture: BaseTexture;
+
+        @serializeAsTexture()
         public refractionTexture: BaseTexture;
 
+        @serializeAsColor3("ambient")
         public ambientColor = new Color3(0, 0, 0);
+
+        @serializeAsColor3("diffuse")
         public diffuseColor = new Color3(1, 1, 1);
+
+        @serializeAsColor3("specular")
         public specularColor = new Color3(1, 1, 1);
-        public specularPower = 64;
+
+        @serializeAsColor3("emissive")
         public emissiveColor = new Color3(0, 0, 0);
+
+        @serialize()
+        public specularPower = 64;
+
+        @serialize()
         public useAlphaFromDiffuseTexture = false;
+
+        @serialize()
         public useEmissiveAsIllumination = false;
+
+        @serialize()
         public linkEmissiveWithDiffuse = false;
+
+        @serialize()
         public useReflectionFresnelFromSpecular = false;
+
+        @serialize()
         public useSpecularOverAlpha = false;
+
+        @serialize()
+        public useReflectionOverAlpha = false;
+
+        @serialize()
         public disableLighting = false;
 
+        @serialize()
         public roughness = 0;
 
+        @serialize()
         public indexOfRefraction = 0.98;
+
+        @serialize()
         public invertRefractionY = true;
 
+        @serialize()
         public useLightmapAsShadowmap = false;
 
+        @serializeAsFresnelParameters()
         public diffuseFresnelParameters: FresnelParameters;
+
+        @serializeAsFresnelParameters()
         public opacityFresnelParameters: FresnelParameters;
+
+        @serializeAsFresnelParameters()
         public reflectionFresnelParameters: FresnelParameters;
+
+        @serializeAsFresnelParameters()
         public refractionFresnelParameters: FresnelParameters;
+
+        @serializeAsFresnelParameters()
         public emissiveFresnelParameters: FresnelParameters;
 
+        @serialize()
         public useGlossinessFromSpecularMapAlpha = false;
 
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
@@ -305,6 +322,10 @@
                             this._defines.ROUGHNESS = true;
                         }
 
+                        if (this.useReflectionOverAlpha) {
+                            this._defines.REFLECTIONOVERALPHA = true;
+                        }
+
                         if (this.reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE) {
                             this._defines.INVERTCUBICMAP = true;
                         }
@@ -412,10 +433,6 @@
                 this._defines.LINKEMISSIVEWITHDIFFUSE = true;
             }
 
-            if (this.useReflectionFresnelFromSpecular) {
-                this._defines.REFLECTIONFRESNELFROMSPECULAR = true;
-            }
-
             if (this.useLogarithmicDepth) {
                 this._defines.LOGARITHMICDEPTH = true;
             }
@@ -452,6 +469,10 @@
 
                     if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
                         this._defines.REFLECTIONFRESNEL = true;
+
+                        if (this.useReflectionFresnelFromSpecular) {
+                            this._defines.REFLECTIONFRESNELFROMSPECULAR = true;
+                        }
                     }
 
                     if (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) {
@@ -891,148 +912,18 @@
         }
 
         public clone(name: string): StandardMaterial {
-            var newStandardMaterial = new StandardMaterial(name, this.getScene());
-
-            // Base material
-            this.copyTo(newStandardMaterial);
-
-            // Standard material
-            if (this.diffuseTexture && this.diffuseTexture.clone) {
-                newStandardMaterial.diffuseTexture = this.diffuseTexture.clone();
-            }
-            if (this.ambientTexture && this.ambientTexture.clone) {
-                newStandardMaterial.ambientTexture = this.ambientTexture.clone();
-            }
-            if (this.opacityTexture && this.opacityTexture.clone) {
-                newStandardMaterial.opacityTexture = this.opacityTexture.clone();
-            }
-            if (this.reflectionTexture && this.reflectionTexture.clone) {
-                newStandardMaterial.reflectionTexture = this.reflectionTexture.clone();
-            }
-            if (this.emissiveTexture && this.emissiveTexture.clone) {
-                newStandardMaterial.emissiveTexture = this.emissiveTexture.clone();
-            }
-            if (this.specularTexture && this.specularTexture.clone) {
-                newStandardMaterial.specularTexture = this.specularTexture.clone();
-            }
-            if (this.bumpTexture && this.bumpTexture.clone) {
-                newStandardMaterial.bumpTexture = this.bumpTexture.clone();
-            }
-            if (this.lightmapTexture && this.lightmapTexture.clone) {
-                newStandardMaterial.lightmapTexture = this.lightmapTexture.clone();
-                newStandardMaterial.useLightmapAsShadowmap = this.useLightmapAsShadowmap;
-            }
-            if (this.refractionTexture && this.refractionTexture.clone) {
-                newStandardMaterial.refractionTexture = this.refractionTexture.clone();
-            }
-
-            newStandardMaterial.ambientColor = this.ambientColor.clone();
-            newStandardMaterial.diffuseColor = this.diffuseColor.clone();
-            newStandardMaterial.specularColor = this.specularColor.clone();
-            newStandardMaterial.specularPower = this.specularPower;
-            newStandardMaterial.emissiveColor = this.emissiveColor.clone();
-            newStandardMaterial.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
-            newStandardMaterial.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            newStandardMaterial.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
-            newStandardMaterial.useReflectionFresnelFromSpecular = this.useReflectionFresnelFromSpecular;
-            newStandardMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
-            newStandardMaterial.roughness = this.roughness;
-            newStandardMaterial.indexOfRefraction = this.indexOfRefraction;
-            newStandardMaterial.invertRefractionY = this.invertRefractionY;
-
-            if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.clone) {
-                newStandardMaterial.diffuseFresnelParameters = this.diffuseFresnelParameters.clone();
-            }
-            if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.clone) {
-                newStandardMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
-            }
-            if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.clone) {
-                newStandardMaterial.reflectionFresnelParameters = this.reflectionFresnelParameters.clone();
-            }
-            if (this.refractionFresnelParameters && this.refractionFresnelParameters.clone) {
-                newStandardMaterial.refractionFresnelParameters = this.refractionFresnelParameters.clone();
-            }
-            if (this.opacityFresnelParameters && this.opacityFresnelParameters.clone) {
-                newStandardMaterial.opacityFresnelParameters = this.opacityFresnelParameters.clone();
-            }
-
-            return newStandardMaterial;
+            return SerializationHelper.Clone(() => new StandardMaterial(name, this.getScene()), this);
         }
 
         public serialize(): any {
-            var serializationObject = super.serialize();
-
-            serializationObject.ambient = this.ambientColor.asArray();
-            serializationObject.diffuse = this.diffuseColor.asArray();
-            serializationObject.specular = this.specularColor.asArray();
-            serializationObject.specularPower = this.specularPower;
-            serializationObject.emissive = this.emissiveColor.asArray();
-            serializationObject.useReflectionFresnelFromSpecular = this.useReflectionFresnelFromSpecular;
-            serializationObject.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            serializationObject.indexOfRefraction = this.indexOfRefraction;
-            serializationObject.invertRefractionY = this.invertRefractionY;
-
-            if (this.diffuseTexture) {
-                serializationObject.diffuseTexture = this.diffuseTexture.serialize();
-            }
-
-            if (this.diffuseFresnelParameters) {
-                serializationObject.diffuseFresnelParameters = this.diffuseFresnelParameters.serialize();
-            }
-
-            if (this.ambientTexture) {
-                serializationObject.ambientTexture = this.ambientTexture.serialize();
-            }
-
-            if (this.opacityTexture) {
-                serializationObject.opacityTexture = this.opacityTexture.serialize();
-            }
-
-            if (this.opacityFresnelParameters) {
-                serializationObject.opacityFresnelParameters = this.diffuseFresnelParameters.serialize();
-            }
-
-            if (this.reflectionTexture) {
-                serializationObject.reflectionTexture = this.reflectionTexture.serialize();
-            }
-
-            if (this.reflectionFresnelParameters) {
-                serializationObject.reflectionFresnelParameters = this.reflectionFresnelParameters.serialize();
-            }
-
-            if (this.refractionFresnelParameters) {
-                serializationObject.refractionFresnelParameters = this.refractionFresnelParameters.serialize();
-            }
-
-            if (this.emissiveTexture) {
-                serializationObject.emissiveTexture = this.emissiveTexture.serialize();
-            }
-
-            if (this.lightmapTexture) {
-                serializationObject.lightmapTexture = this.lightmapTexture.serialize();
-                serializationObject.useLightmapAsShadowmap = this.useLightmapAsShadowmap;
-            }
-
-            if (this.emissiveFresnelParameters) {
-                serializationObject.emissiveFresnelParameters = this.emissiveFresnelParameters.serialize();
-            }
-
-            if (this.specularTexture) {
-                serializationObject.specularTexture = this.specularTexture.serialize();
-            }
-
-            if (this.bumpTexture) {
-                serializationObject.bumpTexture = this.bumpTexture.serialize();
-            }
-
-            if (this.refractionTexture) {
-                serializationObject.refractionTexture = this.refractionTexture.serialize();
-            }
-
-            return serializationObject;
+            return SerializationHelper.Serialize(this);
         }
 
         // Statics
+        public static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial {
+            return SerializationHelper.Parse(() => new StandardMaterial(source.name, scene), source, scene, rootUrl);
+        }
+
         // Flags used to enable or disable a type of texture for all Standard Materials
         public static DiffuseTextureEnabled = true;
         public static AmbientTextureEnabled = true;
@@ -1044,94 +935,5 @@
         public static FresnelEnabled = true;
         public static LightmapTextureEnabled = true;
         public static RefractionTextureEnabled = true;
-
-        public static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial {
-            var material = new StandardMaterial(source.name, scene);
-
-            material.ambientColor = Color3.FromArray(source.ambient);
-            material.diffuseColor = Color3.FromArray(source.diffuse);
-            material.specularColor = Color3.FromArray(source.specular);
-            material.specularPower = source.specularPower;
-            material.emissiveColor = Color3.FromArray(source.emissive);
-            material.useReflectionFresnelFromSpecular = source.useReflectionFresnelFromSpecular;
-            material.useEmissiveAsIllumination = source.useEmissiveAsIllumination;
-            material.indexOfRefraction = source.indexOfRefraction;
-            material.invertRefractionY = source.invertRefractionY;
-
-            material.alpha = source.alpha;
-
-            material.id = source.id;
-
-            if (source.disableDepthWrite) {
-                material.disableDepthWrite = source.disableDepthWrite;
-            }
-
-            Tags.AddTagsTo(material, source.tags);
-            material.backFaceCulling = source.backFaceCulling;
-            material.wireframe = source.wireframe;
-
-            if (source.diffuseTexture) {
-                material.diffuseTexture = Texture.Parse(source.diffuseTexture, scene, rootUrl);
-            }
-
-            if (source.diffuseFresnelParameters) {
-                material.diffuseFresnelParameters = FresnelParameters.Parse(source.diffuseFresnelParameters);
-            }
-
-            if (source.ambientTexture) {
-                material.ambientTexture = Texture.Parse(source.ambientTexture, scene, rootUrl);
-            }
-
-            if (source.opacityTexture) {
-                material.opacityTexture = Texture.Parse(source.opacityTexture, scene, rootUrl);
-            }
-
-            if (source.opacityFresnelParameters) {
-                material.opacityFresnelParameters = FresnelParameters.Parse(source.opacityFresnelParameters);
-            }
-
-            if (source.reflectionTexture) {
-                material.reflectionTexture = Texture.Parse(source.reflectionTexture, scene, rootUrl);
-            }
-
-            if (source.reflectionFresnelParameters) {
-                material.reflectionFresnelParameters = FresnelParameters.Parse(source.reflectionFresnelParameters);
-            }
-
-            if (source.refractionFresnelParameters) {
-                material.refractionFresnelParameters = FresnelParameters.Parse(source.refractionFresnelParameters);
-            }
-
-            if (source.emissiveTexture) {
-                material.emissiveTexture = Texture.Parse(source.emissiveTexture, scene, rootUrl);
-            }
-
-            if (source.lightmapTexture) {
-                material.lightmapTexture = Texture.Parse(source.lightmapTexture, scene, rootUrl);
-                material.useLightmapAsShadowmap = source.useLightmapAsShadowmap;
-            }
-
-            if (source.emissiveFresnelParameters) {
-                material.emissiveFresnelParameters = FresnelParameters.Parse(source.emissiveFresnelParameters);
-            }
-
-            if (source.specularTexture) {
-                material.specularTexture = Texture.Parse(source.specularTexture, scene, rootUrl);
-            }
-
-            if (source.bumpTexture) {
-                material.bumpTexture = Texture.Parse(source.bumpTexture, scene, rootUrl);
-            }
-
-            if (source.refractionTexture) {
-                material.refractionTexture = Texture.Parse(source.refractionTexture, scene, rootUrl);
-            }
-
-            if (source.checkReadyOnlyOnce) {
-                material.checkReadyOnlyOnce = source.checkReadyOnlyOnce;
-            }
-
-            return material;
-        }
     }
 } 

+ 1 - 1
src/Math/babylon.math.js

@@ -3146,7 +3146,7 @@ var BABYLON;
         Tmp.Color3 = [Color3.Black(), Color3.Black(), Color3.Black()];
         Tmp.Vector2 = [Vector2.Zero(), Vector2.Zero(), Vector2.Zero()]; // 3 temp Vector2 at once should be enough
         Tmp.Vector3 = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),
-            Vector3.Zero(), Vector3.Zero(), Vector3.Zero()]; // 6 temp Vector3 at once should be enough
+            Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()]; // 9 temp Vector3 at once should be enough
         Tmp.Vector4 = [Vector4.Zero(), Vector4.Zero(), Vector4.Zero()]; // 3 temp Vector4 at once should be enough
         Tmp.Quaternion = [new Quaternion(0, 0, 0, 0)]; // 1 temp Quaternion at once should be enough
         Tmp.Matrix = [Matrix.Zero(), Matrix.Zero(),

+ 2 - 3
src/Math/babylon.math.ts

@@ -3799,8 +3799,8 @@
     export class Tmp {
         public static Color3: Color3[] = [Color3.Black(), Color3.Black(), Color3.Black()];
         public static Vector2: Vector2[] = [Vector2.Zero(), Vector2.Zero(), Vector2.Zero()];  // 3 temp Vector2 at once should be enough
-        public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero()
-            , Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];    // 6 temp Vector3 at once should be enough
+        public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),
+            Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];    // 9 temp Vector3 at once should be enough
         public static Vector4: Vector4[] = [Vector4.Zero(), Vector4.Zero(), Vector4.Zero()];  // 3 temp Vector4 at once should be enough
         public static Quaternion: Quaternion[] = [new Quaternion(0, 0, 0, 0)];                // 1 temp Quaternion at once should be enough
         public static Matrix: Matrix[] = [Matrix.Zero(), Matrix.Zero(),
@@ -3810,4 +3810,3 @@
     }
 }
 
-

+ 40 - 16
src/Mesh/babylon.groundMesh.js

@@ -41,6 +41,7 @@ var BABYLON;
                 return this.position.y;
             }
             if (!this._heightQuads || this._heightQuads.length == 0) {
+                this._initHeightQuads();
                 this._computeHeightQuads();
             }
             var facet = this._getFacetAt(x, z);
@@ -75,6 +76,7 @@ var BABYLON;
                 return;
             }
             if (!this._heightQuads || this._heightQuads.length == 0) {
+                this._initHeightQuads();
                 this._computeHeightQuads();
             }
             var facet = this._getFacetAt(x, z);
@@ -82,6 +84,17 @@ var BABYLON;
             ref.y = facet.y;
             ref.z = facet.z;
         };
+        /**
+        * Force the heights to be recomputed for getHeightAtCoordinates() or getNormalAtCoordinates()
+        * if the ground has been updated.
+        * This can be used in the render loop
+        */
+        GroundMesh.prototype.updateCoordinateHeights = function () {
+            if (!this._heightQuads || this._heightQuads.length == 0) {
+                this._initHeightQuads();
+            }
+            this._computeHeightQuads();
+        };
         // Returns the element "facet" from the heightQuads array relative to (x, z) local coordinates
         GroundMesh.prototype._getFacetAt = function (x, z) {
             // retrieve col and row from x, z coordinates in the ground local system
@@ -97,23 +110,35 @@ var BABYLON;
             }
             return facet;
         };
-        // Populates the heightMap array with "facet" elements :
+        //  Creates and populates the heightMap array with "facet" elements :
         // a quad is two triangular facets separated by a slope, so a "facet" element is 1 slope + 2 facets
         // slope : Vector2(c, h) = 2D diagonal line equation setting appart two triangular facets in a quad : z = cx + h
         // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0
         // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0
-        GroundMesh.prototype._computeHeightQuads = function () {
+        GroundMesh.prototype._initHeightQuads = function () {
             this._heightQuads = new Array();
+            for (var row = 0; row < this._subdivisions; row++) {
+                for (var col = 0; col < this._subdivisions; col++) {
+                    var quad = { slope: BABYLON.Vector2.Zero(), facet1: new BABYLON.Vector4(0, 0, 0, 0), facet2: new BABYLON.Vector4(0, 0, 0, 0) };
+                    this._heightQuads[row * this._subdivisions + col] = quad;
+                }
+            }
+        };
+        // Compute each quad element values and update the the heightMap array :
+        // slope : Vector2(c, h) = 2D diagonal line equation setting appart two triangular facets in a quad : z = cx + h
+        // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0
+        // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0
+        GroundMesh.prototype._computeHeightQuads = function () {
             var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
-            var v1 = BABYLON.Vector3.Zero();
-            var v2 = BABYLON.Vector3.Zero();
-            var v3 = BABYLON.Vector3.Zero();
-            var v4 = BABYLON.Vector3.Zero();
-            var v1v2 = BABYLON.Vector3.Zero();
-            var v1v3 = BABYLON.Vector3.Zero();
-            var v1v4 = BABYLON.Vector3.Zero();
-            var norm1 = BABYLON.Vector3.Zero();
-            var norm2 = BABYLON.Vector3.Zero();
+            var v1 = BABYLON.Tmp.Vector3[0];
+            var v2 = BABYLON.Tmp.Vector3[1];
+            var v3 = BABYLON.Tmp.Vector3[2];
+            var v4 = BABYLON.Tmp.Vector3[3];
+            var v1v2 = BABYLON.Tmp.Vector3[4];
+            var v1v3 = BABYLON.Tmp.Vector3[5];
+            var v1v4 = BABYLON.Tmp.Vector3[6];
+            var norm1 = BABYLON.Tmp.Vector3[7];
+            var norm2 = BABYLON.Tmp.Vector3[8];
             var i = 0;
             var j = 0;
             var k = 0;
@@ -141,7 +166,6 @@ var BABYLON;
                     // 2D slope V1V4
                     cd = (v4.z - v1.z) / (v4.x - v1.x);
                     h = v1.z - cd * v1.x; // v1 belongs to the slope
-                    var slope = new BABYLON.Vector2(cd, h);
                     // facet equations :
                     // we compute each facet normal vector
                     // the equation of the facet plane is : norm.x * x + norm.y * y + norm.z * z + d = 0
@@ -156,10 +180,10 @@ var BABYLON;
                     norm2.normalize();
                     d1 = -(norm1.x * v1.x + norm1.y * v1.y + norm1.z * v1.z);
                     d2 = -(norm2.x * v2.x + norm2.y * v2.y + norm2.z * v2.z);
-                    var facet1 = new BABYLON.Vector4(norm1.x, norm1.y, norm1.z, d1);
-                    var facet2 = new BABYLON.Vector4(norm2.x, norm2.y, norm2.z, d2);
-                    var quad = { slope: slope, facet1: facet1, facet2: facet2 };
-                    this._heightQuads.push(quad);
+                    var quad = this._heightQuads[row * this._subdivisions + col];
+                    quad.slope.copyFromFloats(cd, h);
+                    quad.facet1.copyFromFloats(norm1.x, norm1.y, norm1.z, d1);
+                    quad.facet2.copyFromFloats(norm2.x, norm2.y, norm2.z, d2);
                 }
             }
         };

+ 42 - 16
src/Mesh/babylon.groundMesh.ts

@@ -42,6 +42,7 @@
                 return this.position.y;
             }
             if (!this._heightQuads || this._heightQuads.length == 0) {
+                this._initHeightQuads();
                 this._computeHeightQuads();
             }
             var facet = this._getFacetAt(x, z);
@@ -78,6 +79,7 @@
                 return;
             }
             if (!this._heightQuads || this._heightQuads.length == 0) {
+                this._initHeightQuads();
                 this._computeHeightQuads();
             }
             var facet = this._getFacetAt(x, z);
@@ -86,6 +88,18 @@
             ref.z = facet.z;
         }
 
+        /**
+        * Force the heights to be recomputed for getHeightAtCoordinates() or getNormalAtCoordinates()
+        * if the ground has been updated.
+        * This can be used in the render loop
+        */
+        public updateCoordinateHeights(): void {
+            if (!this._heightQuads || this._heightQuads.length == 0) {
+                this._initHeightQuads();
+            }
+            this._computeHeightQuads();
+        }
+
         // Returns the element "facet" from the heightQuads array relative to (x, z) local coordinates
         private _getFacetAt(x: number, z: number): Vector4 {
             // retrieve col and row from x, z coordinates in the ground local system
@@ -101,23 +115,36 @@
             return facet;
         }
 
-        // Populates the heightMap array with "facet" elements :
+        //  Creates and populates the heightMap array with "facet" elements :
         // a quad is two triangular facets separated by a slope, so a "facet" element is 1 slope + 2 facets
         // slope : Vector2(c, h) = 2D diagonal line equation setting appart two triangular facets in a quad : z = cx + h
         // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0
         // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0
-        private _computeHeightQuads(): void {
+        private _initHeightQuads(): void {
             this._heightQuads = new Array();
+            for (var row = 0; row < this._subdivisions; row++) {
+                for (var col = 0; col < this._subdivisions; col++) {
+                    var quad = { slope: BABYLON.Vector2.Zero(), facet1: new BABYLON.Vector4(0, 0, 0, 0), facet2: new BABYLON.Vector4(0, 0, 0, 0) };
+                    this._heightQuads[row * this._subdivisions + col] = quad;
+                }
+            }
+        }
+
+        // Compute each quad element values and update the the heightMap array :
+        // slope : Vector2(c, h) = 2D diagonal line equation setting appart two triangular facets in a quad : z = cx + h
+        // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0
+        // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0
+        private _computeHeightQuads(): void {
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
-            var v1 = Vector3.Zero();
-            var v2 = Vector3.Zero();
-            var v3 = Vector3.Zero();
-            var v4 = Vector3.Zero();
-            var v1v2 = Vector3.Zero();
-            var v1v3 = Vector3.Zero();
-            var v1v4 = Vector3.Zero();
-            var norm1 = Vector3.Zero();
-            var norm2 = Vector3.Zero();
+            var v1 = Tmp.Vector3[0];
+            var v2 = Tmp.Vector3[1];
+            var v3 = Tmp.Vector3[2];
+            var v4 = Tmp.Vector3[3];
+            var v1v2 = Tmp.Vector3[4];
+            var v1v3 = Tmp.Vector3[5];
+            var v1v4 = Tmp.Vector3[6];
+            var norm1 = Tmp.Vector3[7];
+            var norm2 = Tmp.Vector3[8];
             var i = 0;
             var j = 0;
             var k = 0;
@@ -147,7 +174,6 @@
                     // 2D slope V1V4
                     cd = (v4.z - v1.z) / (v4.x - v1.x);
                     h = v1.z - cd * v1.x;             // v1 belongs to the slope
-                    var slope = new Vector2(cd, h);
 
                     // facet equations :
                     // we compute each facet normal vector
@@ -163,11 +189,11 @@
                     norm2.normalize();
                     d1 = -(norm1.x * v1.x + norm1.y * v1.y + norm1.z * v1.z);
                     d2 = -(norm2.x * v2.x + norm2.y * v2.y + norm2.z * v2.z);
-                    var facet1 = new BABYLON.Vector4(norm1.x, norm1.y, norm1.z, d1);
-                    var facet2 = new BABYLON.Vector4(norm2.x, norm2.y, norm2.z, d2);
 
-                    var quad = { slope: slope, facet1: facet1, facet2: facet2 };
-                    this._heightQuads.push(quad);
+                    var quad = this._heightQuads[row * this._subdivisions + col];
+                    quad.slope.copyFromFloats(cd, h);
+                    quad.facet1.copyFromFloats(norm1.x, norm1.y, norm1.z, d1);
+                    quad.facet2.copyFromFloats(norm2.x, norm2.y, norm2.z, d2);
                 }
             }
         }

+ 21 - 0
src/Mesh/babylon.mesh.vertexData.js

@@ -914,6 +914,27 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
+        VertexData.CreateLineSystem = function (options) {
+            var indices = [];
+            var positions = [];
+            var lines = options.lines;
+            var idx = 0;
+            for (var l = 0; l < lines.length; l++) {
+                var points = lines[l];
+                for (var index = 0; index < points.length; index++) {
+                    positions.push(points[index].x, points[index].y, points[index].z);
+                    if (index > 0) {
+                        indices.push(idx - 1);
+                        indices.push(idx);
+                    }
+                    idx++;
+                }
+            }
+            var vertexData = new VertexData();
+            vertexData.indices = indices;
+            vertexData.positions = positions;
+            return vertexData;
+        };
         VertexData.CreateLines = function (options) {
             var indices = [];
             var positions = [];

+ 24 - 1
src/Mesh/babylon.mesh.vertexData.ts

@@ -1107,6 +1107,30 @@
             return vertexData;
         }
 
+        public static CreateLineSystem(options: { lines: Vector3[][] }): VertexData {
+            var indices = [];
+            var positions = [];
+            var lines = options.lines;
+            var idx = 0;
+
+            for (var l = 0; l < lines.length; l++) {
+                var points = lines[l];
+                for (var index = 0; index < points.length; index++) {
+                    positions.push(points[index].x, points[index].y, points[index].z);
+
+                    if (index > 0) {
+                        indices.push(idx - 1);
+                        indices.push(idx);
+                    }
+                    idx++;
+                }
+            }
+            var vertexData = new VertexData();
+            vertexData.indices = indices;
+            vertexData.positions = positions;
+            return vertexData;
+        }
+
         public static CreateLines(options: { points: Vector3[] }): VertexData {
             var indices = [];
             var positions = [];
@@ -2165,4 +2189,3 @@
         }
     }
 }
-

+ 25 - 0
src/Mesh/babylon.meshBuilder.js

@@ -126,6 +126,31 @@ var BABYLON;
             vertexData.applyToMesh(torusKnot, options.updatable);
             return torusKnot;
         };
+        MeshBuilder.CreateLineSystem = function (name, options, scene) {
+            var instance = options.instance;
+            var lines = options.lines;
+            if (instance) {
+                var positionFunction = function (positions) {
+                    var i = 0;
+                    for (var l = 0; l < lines.length; l++) {
+                        var points = lines[l];
+                        for (var p = 0; p < points.length; p++) {
+                            positions[i] = points[p].x;
+                            positions[i + 1] = points[p].y;
+                            positions[i + 2] = points[p].z;
+                            i += 3;
+                        }
+                    }
+                };
+                instance.updateMeshPositions(positionFunction, false);
+                return instance;
+            }
+            // line system creation
+            var lineSystem = new BABYLON.LinesMesh(name, scene);
+            var vertexData = BABYLON.VertexData.CreateLineSystem(options);
+            vertexData.applyToMesh(lineSystem, options.updatable);
+            return lineSystem;
+        };
         MeshBuilder.CreateLines = function (name, options, scene) {
             var instance = options.instance;
             var points = options.points;

+ 28 - 1
src/Mesh/babylon.meshBuilder.ts

@@ -152,6 +152,34 @@
             return torusKnot;
         }
 
+        public static CreateLineSystem(name: string, options: { lines: Vector3[][], updatable: boolean, instance?: LinesMesh }, scene: Scene): LinesMesh {
+            var instance = options.instance;
+            var lines = options.lines;
+
+            if (instance) { // lines update
+                var positionFunction = positions => {
+                    var i = 0;
+                    for (var l = 0; l < lines.length; l++) {
+                        var points = lines[l];
+                        for (var p = 0; p < points.length; p++) {
+                            positions[i] = points[p].x;
+                            positions[i + 1] = points[p].y;
+                            positions[i + 2] = points[p].z;
+                            i += 3;
+                        }
+                    }
+                };
+                instance.updateMeshPositions(positionFunction, false);
+                return instance;
+            }
+            
+            // line system creation
+            var lineSystem = new LinesMesh(name, scene);
+            var vertexData = VertexData.CreateLineSystem(options);
+            vertexData.applyToMesh(lineSystem, options.updatable);
+            return lineSystem;
+        }
+
         public static CreateLines(name: string, options: { points: Vector3[], updatable?: boolean, instance?: LinesMesh }, scene: Scene): LinesMesh {
             var instance = options.instance;
             var points = options.points;
@@ -816,4 +844,3 @@
         }
     }
 }
-

+ 1 - 0
src/Mesh/babylon.subMesh.js

@@ -51,6 +51,7 @@ var BABYLON;
         };
         // Methods
         SubMesh.prototype.refreshBoundingInfo = function () {
+            this._lastColliderWorldVertices = null;
             if (this.IsGlobal) {
                 return;
             }

+ 2 - 0
src/Mesh/babylon.subMesh.ts

@@ -67,6 +67,8 @@
 
         // Methods
         public refreshBoundingInfo(): void {
+            this._lastColliderWorldVertices = null;
+
             if (this.IsGlobal) {
                 return;
             }

+ 4 - 1
src/Particles/babylon.particleSystem.js

@@ -334,13 +334,13 @@ var BABYLON;
         ParticleSystem.prototype.serialize = function () {
             var serializationObject = {};
             serializationObject.name = this.name;
+            serializationObject.id = this.id;
             // Emitter
             if (this.emitter.position) {
                 serializationObject.emitterId = this.emitter.id;
             }
             else {
                 serializationObject.emitter = this.emitter.asArray();
-                ;
             }
             serializationObject.capacity = this.getCapacity();
             if (this.particleTexture) {
@@ -375,6 +375,9 @@ var BABYLON;
         ParticleSystem.Parse = function (parsedParticleSystem, scene, rootUrl) {
             var name = parsedParticleSystem.name;
             var particleSystem = new ParticleSystem(name, parsedParticleSystem.capacity, scene);
+            if (parsedParticleSystem.id) {
+                particleSystem.id = parsedParticleSystem.id;
+            }
             // Texture
             if (parsedParticleSystem.textureName) {
                 particleSystem.particleTexture = new BABYLON.Texture(rootUrl + parsedParticleSystem.textureName, scene);

+ 6 - 1
src/Particles/babylon.particleSystem.ts

@@ -451,12 +451,13 @@
             var serializationObject: any = {};
 
             serializationObject.name = this.name;
+            serializationObject.id = this.id;
 
             // Emitter
             if (this.emitter.position) {
                 serializationObject.emitterId = this.emitter.id;
             } else {
-                serializationObject.emitter = this.emitter.asArray();;
+                serializationObject.emitter = this.emitter.asArray();
             }
 
             serializationObject.capacity = this.getCapacity();
@@ -498,6 +499,10 @@
             var name = parsedParticleSystem.name;
             var particleSystem = new ParticleSystem(name, parsedParticleSystem.capacity, scene);
 
+            if (parsedParticleSystem.id) {
+                particleSystem.id = parsedParticleSystem.id;
+            }
+
             // Texture
             if (parsedParticleSystem.textureName) {
                 particleSystem.particleTexture = new Texture(rootUrl + parsedParticleSystem.textureName, scene);

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

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

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

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

+ 7 - 0
src/Shaders/ShadersInclude/fresnelFunction.fx

@@ -0,0 +1,7 @@
+#ifdef FRESNEL
+	float computeFresnelTerm(vec3 viewDirection, vec3 worldNormal, float bias, float power)
+	{
+		float fresnelTerm = pow(bias + abs(dot(viewDirection, worldNormal)), power);
+		return clamp(fresnelTerm, 0., 1.);
+	}
+#endif

+ 3 - 0
src/Shaders/ShadersInclude/pointCloudVertex.fx

@@ -0,0 +1,3 @@
+#ifdef POINTSIZE
+	gl_PointSize = pointSize;
+#endif

+ 3 - 0
src/Shaders/ShadersInclude/pointCloudVertexDeclaration.fx

@@ -0,0 +1,3 @@
+#ifdef POINTSIZE
+	uniform float pointSize;
+#endif

+ 61 - 0
src/Shaders/ShadersInclude/reflectionFunction.fx

@@ -0,0 +1,61 @@
+vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
+{
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
+	vec3 direction = normalize(vDirectionW);
+
+	float t = clamp(direction.y * -0.5 + 0.5, 0., 1.0);
+	float s = atan(direction.z, direction.x) * RECIPROCAL_PI2 + 0.5;
+
+	return vec3(s, t, 0);
+#endif
+
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+
+	vec3 cameraToVertex = normalize(worldPos.xyz - vEyePosition);
+	vec3 r = reflect(cameraToVertex, worldNormal);
+	float t = clamp(r.y * -0.5 + 0.5, 0., 1.0);
+	float s = atan(r.z, r.x) * RECIPROCAL_PI2 + 0.5;
+
+	return vec3(s, t, 0);
+#endif
+
+#ifdef REFLECTIONMAP_SPHERICAL
+	vec3 viewDir = normalize(vec3(view * worldPos));
+	vec3 viewNormal = normalize(vec3(view * vec4(worldNormal, 0.0)));
+
+	vec3 r = reflect(viewDir, viewNormal);
+	r.z = r.z - 1.0;
+
+	float m = 2.0 * length(r);
+
+	return vec3(r.x / m + 0.5, 1.0 - r.y / m - 0.5, 0);
+#endif
+
+#ifdef REFLECTIONMAP_PLANAR
+	vec3 viewDir = worldPos.xyz - vEyePosition;
+	vec3 coords = normalize(reflect(viewDir, worldNormal));
+
+	return vec3(reflectionMatrix * vec4(coords, 1));
+#endif
+
+#ifdef REFLECTIONMAP_CUBIC
+	vec3 viewDir = worldPos.xyz - vEyePosition;
+	vec3 coords = reflect(viewDir, worldNormal);
+#ifdef INVERTCUBICMAP
+	coords.y = 1.0 - coords.y;
+#endif
+	return vec3(reflectionMatrix * vec4(coords, 0));
+#endif
+
+#ifdef REFLECTIONMAP_PROJECTION
+	return vec3(reflectionMatrix * (view * worldPos));
+#endif
+
+#ifdef REFLECTIONMAP_SKYBOX
+	return vPositionUVW;
+#endif
+
+#ifdef REFLECTIONMAP_EXPLICIT
+	return vec3(0, 0, 0);
+#endif
+}

+ 6 - 68
src/Shaders/default.fragment.fx

@@ -97,13 +97,7 @@ uniform sampler2D specularSampler;
 #endif
 
 // Fresnel
-#ifdef FRESNEL
-float computeFresnelTerm(vec3 viewDirection, vec3 worldNormal, float bias, float power)
-{
-	float fresnelTerm = pow(bias + abs(dot(viewDirection, worldNormal)), power);
-	return clamp(fresnelTerm, 0., 1.);
-}
-#endif
+#include<fresnelFunction>
 
 #ifdef DIFFUSEFRESNEL
 uniform vec4 diffuseLeftColor;
@@ -141,67 +135,7 @@ uniform mat4 reflectionMatrix;
 #endif
 #endif
 
-vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
-{
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
-	vec3 direction = normalize(vDirectionW);
-
-	float t = clamp(direction.y * -0.5 + 0.5, 0., 1.0);
-	float s = atan(direction.z, direction.x) * RECIPROCAL_PI2 + 0.5;
-
-	return vec3(s, t, 0);
-#endif
-
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR
-
-	vec3 cameraToVertex = normalize(worldPos.xyz - vEyePosition);
-	vec3 r = reflect(cameraToVertex, worldNormal);
-	float t = clamp(r.y * -0.5 + 0.5, 0., 1.0);
-	float s = atan(r.z, r.x) * RECIPROCAL_PI2 + 0.5;
-
-	return vec3(s, t, 0);
-#endif
-
-#ifdef REFLECTIONMAP_SPHERICAL
-	vec3 viewDir = normalize(vec3(view * worldPos));
-	vec3 viewNormal = normalize(vec3(view * vec4(worldNormal, 0.0)));
-
-	vec3 r = reflect(viewDir, viewNormal);
-	r.z = r.z - 1.0;
-
-	float m = 2.0 * length(r);
-
-	return vec3(r.x / m + 0.5, 1.0 - r.y / m - 0.5, 0);
-#endif
-
-#ifdef REFLECTIONMAP_PLANAR
-	vec3 viewDir = worldPos.xyz - vEyePosition;
-	vec3 coords = normalize(reflect(viewDir, worldNormal));
-
-	return vec3(reflectionMatrix * vec4(coords, 1));
-#endif
-
-#ifdef REFLECTIONMAP_CUBIC
-	vec3 viewDir = worldPos.xyz - vEyePosition;
-	vec3 coords = reflect(viewDir, worldNormal);
-#ifdef INVERTCUBICMAP
-	coords.y = 1.0 - coords.y;
-#endif
-	return vec3(reflectionMatrix * vec4(coords, 0));
-#endif
-
-#ifdef REFLECTIONMAP_PROJECTION
-	return vec3(reflectionMatrix * (view * worldPos));
-#endif
-
-#ifdef REFLECTIONMAP_SKYBOX
-	return vPositionUVW;
-#endif
-
-#ifdef REFLECTIONMAP_EXPLICIT
-	return vec3(0, 0, 0);
-#endif
-}
+#include<reflectionFunction>
 
 #ifdef REFLECTIONFRESNEL
 uniform vec4 reflectionLeftColor;
@@ -435,6 +369,10 @@ void main(void) {
 	alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
 #endif
 
+#ifdef REFLECTIONOVERALPHA
+	alpha = clamp(alpha + dot(reflectionColor, vec3(0.3, 0.59, 0.11)), 0., 1.);
+#endif
+
 	// Composition
 #ifdef EMISSIVEASILLUMINATION
 	vec4 color = vec4(clamp(finalDiffuse * baseAmbientColor + finalSpecular + reflectionColor + emissiveColor + refractionColor, 0.0, 1.0), alpha);

+ 2 - 8
src/Shaders/default.vertex.fx

@@ -65,9 +65,7 @@ uniform vec2 vBumpInfos;
 uniform mat4 bumpMatrix;
 #endif
 
-#ifdef POINTSIZE
-uniform float pointSize;
-#endif
+#include<pointCloudVertexDeclaration>
 
 // Output
 varying vec3 vPositionW;
@@ -209,11 +207,7 @@ void main(void) {
 	vColor = color;
 #endif
 
-	// Point size
-#ifdef POINTSIZE
-	gl_PointSize = pointSize;
-#endif
-
+#include<pointCloudVertex>
 #include<logDepthVertex>
 
 }

+ 1 - 7
src/Shaders/legacydefault.fragment.fx

@@ -70,13 +70,7 @@ uniform sampler2D specularSampler;
 #endif
 
 // Fresnel
-#ifdef FRESNEL
-float computeFresnelTerm(vec3 viewDirection, vec3 worldNormal, float bias, float power)
-{
-	float fresnelTerm = pow(bias + abs(dot(viewDirection, worldNormal)), power);
-	return clamp(fresnelTerm, 0., 1.);
-}
-#endif
+#include<fresnelFunction>
 
 #ifdef DIFFUSEFRESNEL
 uniform vec4 diffuseLeftColor;

+ 10 - 0
src/Sprites/babylon.spriteManager.js

@@ -38,6 +38,16 @@ var BABYLON;
             this._effectBase = this._scene.getEngine().createEffect("sprites", ["position", "options", "cellInfo", "color"], ["view", "projection", "textureInfos", "alphaTest"], ["diffuseSampler"], "");
             this._effectFog = this._scene.getEngine().createEffect("sprites", ["position", "options", "cellInfo", "color"], ["view", "projection", "textureInfos", "alphaTest", "vFogInfos", "vFogColor"], ["diffuseSampler"], "#define FOG");
         }
+        Object.defineProperty(SpriteManager.prototype, "texture", {
+            get: function () {
+                return this._spriteTexture;
+            },
+            set: function (value) {
+                this._spriteTexture = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
         SpriteManager.prototype._appendSpriteVertex = function (index, sprite, offsetX, offsetY, rowSize) {
             var arrayOffset = index * 16;
             if (offsetX === 0)

+ 8 - 0
src/Sprites/babylon.spriteManager.ts

@@ -21,6 +21,14 @@
         private _effectBase: Effect;
         private _effectFog: Effect;
 
+        public get texture(): Texture {
+            return this._spriteTexture;
+        }
+
+        public set texture(value: Texture) {
+            this._spriteTexture = value;
+        }
+
         constructor(public name: string, imgUrl: string, capacity: number, public cellSize: number, scene: Scene, epsilon?: number, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
             this._capacity = capacity;
             this._spriteTexture = new Texture(imgUrl, scene, true, false, samplingMode);

+ 116 - 0
src/Tools/babylon.decorators.js

@@ -0,0 +1,116 @@
+var BABYLON;
+(function (BABYLON) {
+    function generateSerializableMember(type, sourceName) {
+        return function (target, propertyKey) {
+            if (!target.__serializableMembers) {
+                target.__serializableMembers = {};
+            }
+            target.__serializableMembers[propertyKey] = { type: type, sourceName: sourceName };
+        };
+    }
+    function serialize(sourceName) {
+        return generateSerializableMember(0, sourceName); // value member
+    }
+    BABYLON.serialize = serialize;
+    function serializeAsTexture(sourceName) {
+        return generateSerializableMember(1, sourceName); // texture member
+    }
+    BABYLON.serializeAsTexture = serializeAsTexture;
+    function serializeAsColor3(sourceName) {
+        return generateSerializableMember(2, sourceName); // color3 member
+    }
+    BABYLON.serializeAsColor3 = serializeAsColor3;
+    function serializeAsFresnelParameters(sourceName) {
+        return generateSerializableMember(3, sourceName); // fresnel parameters member
+    }
+    BABYLON.serializeAsFresnelParameters = serializeAsFresnelParameters;
+    var SerializationHelper = (function () {
+        function SerializationHelper() {
+        }
+        SerializationHelper.Serialize = function (entity, serializationObject) {
+            if (!serializationObject) {
+                serializationObject = {};
+            }
+            // Tags
+            serializationObject.tags = BABYLON.Tags.GetTags(entity);
+            // Properties
+            for (var property in entity.__serializableMembers) {
+                var propertyDescriptor = entity.__serializableMembers[property];
+                var targetPropertyName = propertyDescriptor.sourceName || property;
+                var propertyType = propertyDescriptor.type;
+                var sourceProperty = entity[property];
+                if (sourceProperty !== undefined && sourceProperty !== null) {
+                    switch (propertyType) {
+                        case 0:
+                            serializationObject[targetPropertyName] = sourceProperty;
+                            break;
+                        case 1:
+                            serializationObject[targetPropertyName] = sourceProperty.serialize();
+                            break;
+                        case 2:
+                            serializationObject[targetPropertyName] = sourceProperty.asArray();
+                            break;
+                        case 3:
+                            serializationObject[targetPropertyName] = sourceProperty.serialize();
+                            break;
+                    }
+                }
+            }
+            return serializationObject;
+        };
+        SerializationHelper.Parse = function (creationFunction, source, scene, rootUrl) {
+            var destination = creationFunction();
+            // Tags
+            BABYLON.Tags.AddTagsTo(destination, source.tags);
+            // Properties
+            for (var property in destination.__serializableMembers) {
+                var propertyDescriptor = destination.__serializableMembers[property];
+                var sourceProperty = source[propertyDescriptor.sourceName || property];
+                var propertyType = propertyDescriptor.type;
+                if (sourceProperty !== undefined && sourceProperty !== null) {
+                    switch (propertyType) {
+                        case 0:
+                            destination[property] = sourceProperty;
+                            break;
+                        case 1:
+                            destination[property] = BABYLON.Texture.Parse(sourceProperty, scene, rootUrl);
+                            break;
+                        case 2:
+                            destination[property] = BABYLON.Color3.FromArray(sourceProperty);
+                            break;
+                        case 3:
+                            destination[property] = BABYLON.FresnelParameters.Parse(sourceProperty);
+                            break;
+                    }
+                }
+            }
+            return destination;
+        };
+        SerializationHelper.Clone = function (creationFunction, source) {
+            var destination = creationFunction();
+            // Tags
+            BABYLON.Tags.AddTagsTo(destination, source.tags);
+            // Properties
+            for (var property in destination.__serializableMembers) {
+                var propertyDescriptor = destination.__serializableMembers[property];
+                var sourceProperty = source[property];
+                var propertyType = propertyDescriptor.type;
+                if (sourceProperty !== undefined && sourceProperty !== null) {
+                    switch (propertyType) {
+                        case 0:
+                            destination[property] = sourceProperty;
+                            break;
+                        case 1: // Texture
+                        case 2: // Color3
+                        case 3:
+                            destination[property] = sourceProperty.clone();
+                            break;
+                    }
+                }
+            }
+            return destination;
+        };
+        return SerializationHelper;
+    })();
+    BABYLON.SerializationHelper = SerializationHelper;
+})(BABYLON || (BABYLON = {}));

+ 128 - 0
src/Tools/babylon.decorators.ts

@@ -0,0 +1,128 @@
+module BABYLON {
+    function generateSerializableMember(type: number, sourceName?: string) {
+        return (target: any, propertyKey: string | symbol) => {
+            if (!target.__serializableMembers) {
+                target.__serializableMembers = {};
+            }
+
+            target.__serializableMembers[propertyKey] = { type: type, sourceName: sourceName }; 
+        }
+    }
+
+    export function serialize(sourceName?: string) {
+        return generateSerializableMember(0, sourceName); // value member
+    }
+
+    export function serializeAsTexture(sourceName?: string) {
+        return generateSerializableMember(1, sourceName);// texture member
+    }
+
+    export function serializeAsColor3(sourceName?: string) {
+        return generateSerializableMember(2, sourceName); // color3 member
+    }
+
+    export function serializeAsFresnelParameters(sourceName?: string) {
+        return generateSerializableMember(3, sourceName); // fresnel parameters member
+    }
+
+    export class SerializationHelper {
+
+        public static Serialize<T>(entity: T, serializationObject?: any): any {
+            if (!serializationObject) {
+                serializationObject = {};
+            }
+
+            // Tags
+            serializationObject.tags = Tags.GetTags(entity);
+
+            // Properties
+            for (var property in (<any>entity).__serializableMembers) {
+                var propertyDescriptor = (<any>entity).__serializableMembers[property];
+                var targetPropertyName = propertyDescriptor.sourceName || property;
+                var propertyType = propertyDescriptor.type;
+                var sourceProperty = entity[property];
+
+                if (sourceProperty !== undefined && sourceProperty !== null) {
+                    switch (propertyType) {
+                        case 0:     // Value
+                            serializationObject[targetPropertyName] = sourceProperty;
+                            break;
+                        case 1:     // Texture
+                            serializationObject[targetPropertyName] = sourceProperty.serialize();
+                            break;
+                        case 2:     // Color3
+                            serializationObject[targetPropertyName] = sourceProperty.asArray();
+                            break;
+                        case 3:     // FresnelParameters
+                            serializationObject[targetPropertyName] = sourceProperty.serialize();
+                            break;
+                    }
+                }
+            }
+
+            return serializationObject;
+        }
+
+        public static Parse<T>(creationFunction: () => T, source: any, scene: Scene, rootUrl: string): T {
+            var destination = creationFunction();
+
+            // Tags
+            Tags.AddTagsTo(destination, source.tags);
+
+            // Properties
+            for (var property in (<any>destination).__serializableMembers) {
+                var propertyDescriptor = (<any>destination).__serializableMembers[property];
+                var sourceProperty = source[propertyDescriptor.sourceName || property];
+                var propertyType = propertyDescriptor.type;
+
+                if (sourceProperty !== undefined && sourceProperty !== null) {
+                    switch (propertyType) {
+                        case 0:     // Value
+                            destination[property] = sourceProperty;
+                            break;
+                        case 1:     // Texture
+                            destination[property] = Texture.Parse(sourceProperty, scene, rootUrl);
+                            break;
+                        case 2:     // Color3
+                            destination[property] = Color3.FromArray(sourceProperty);
+                            break;
+                        case 3:     // FresnelParameters
+                            destination[property] = FresnelParameters.Parse(sourceProperty);
+                            break;
+                    }
+                }
+            }
+
+            return destination;
+        }
+
+        public static Clone<T>(creationFunction: () => T, source: T): T {
+            var destination = creationFunction();
+
+            // Tags
+            Tags.AddTagsTo(destination, (<any>source).tags);
+
+            // Properties
+            for (var property in (<any>destination).__serializableMembers) {
+                var propertyDescriptor = (<any>destination).__serializableMembers[property];
+                var sourceProperty = source[property];
+                var propertyType = propertyDescriptor.type;
+
+                if (sourceProperty !== undefined && sourceProperty !== null) {
+                    switch (propertyType) {
+                        case 0:     // Value
+                            destination[property] = sourceProperty;
+                            break;
+                        case 1:     // Texture
+                        case 2:     // Color3
+                        case 3:     // FresnelParameters
+                            destination[property] = sourceProperty.clone();
+                            break;
+                    }
+                }
+            }
+
+            return destination;
+        }
+    }
+}

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

@@ -30,12 +30,6 @@ var BABYLON;
             }
             return fn;
         };
-        Tools.GetConstructorName = function (obj) {
-            var str = (obj.prototype ? obj.prototype.constructor : obj.constructor).toString();
-            var cname = str.match(/function\s(\w*)/)[1];
-            var aliases = ["", "anonymous", "Anonymous"];
-            return aliases.indexOf(cname) > -1 ? "Function" : cname;
-        };
         Tools.ToHex = function (i) {
             var str = i.toString(16);
             if (i <= 15) {
@@ -496,7 +490,7 @@ var BABYLON;
                     var a = window.document.createElement("a");
                     a.href = base64Image;
                     var date = new Date();
-                    var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
+                    var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(-2) + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
                     a.setAttribute("download", "screenshot_" + stringDate + ".png");
                     window.document.body.appendChild(a);
                     a.addEventListener("click", function () {

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

@@ -47,13 +47,6 @@
             return fn;
         }
 
-        public static GetConstructorName(obj) {
-            var str = (obj.prototype ? obj.prototype.constructor : obj.constructor).toString();
-            var cname = str.match(/function\s(\w*)/)[1];
-            var aliases = ["", "anonymous", "Anonymous"];
-            return aliases.indexOf(cname) > -1 ? "Function" : cname;
-        }
-
         public static ToHex(i: number): string {
             var str = i.toString(16);
 
@@ -592,7 +585,7 @@
                     var a = window.document.createElement("a");
                     a.href = base64Image;
                     var date = new Date();
-                    var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
+                    var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(-2) + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
                     a.setAttribute("download", "screenshot_" + stringDate + ".png");
 
                     window.document.body.appendChild(a);
@@ -1013,3 +1006,4 @@
 } 
 
 
+

+ 0 - 0
src/babylon.scene.js


部分文件因为文件数量过多而无法显示