瀏覽代碼

Merge remote-tracking branch 'BabylonJS/master'

MackeyK24 8 年之前
父節點
當前提交
bba8dd88b9
共有 79 個文件被更改,包括 13394 次插入11573 次删除
  1. 8 2
      canvas2D/src/Engine/babylon.prim2dBase.ts
  2. 31 29
      dist/preview release/babylon.core.js
  3. 4359 4201
      dist/preview release/babylon.d.ts
  4. 38 37
      dist/preview release/babylon.js
  5. 2001 678
      dist/preview release/babylon.max.js
  6. 4359 4201
      dist/preview release/babylon.module.d.ts
  7. 38 38
      dist/preview release/babylon.noworker.js
  8. 545 137
      dist/preview release/canvas2D/babylon.canvas2d.js
  9. 12 12
      dist/preview release/canvas2D/babylon.canvas2d.min.js
  10. 3 3
      dist/preview release/inspector/babylon.inspector.bundle.js
  11. 6 0
      dist/preview release/inspector/babylon.inspector.d.ts
  12. 11 0
      dist/preview release/inspector/babylon.inspector.js
  13. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  14. 0 1
      dist/preview release/materialsLibrary/babylon.customMaterial.d.ts
  15. 3 368
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  16. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  17. 0 9
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  18. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  19. 0 9
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  20. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  21. 0 9
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  22. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js
  23. 0 3
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  24. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  25. 0 9
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  26. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js
  27. 0 9
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  28. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.min.js
  29. 0 9
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  30. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  31. 0 9
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  32. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js
  33. 0 9
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  34. 1 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.min.js
  35. 0 9
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  36. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js
  37. 0 9
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  38. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js
  39. 0 9
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  40. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  41. 1 1
      dist/preview release/what's new.md
  42. 87 73
      inspector/src/details/PropertyLine.ts
  43. 1 1
      materialsLibrary/src/custom/Babylon.CustomMaterial.js.map
  44. 3 368
      materialsLibrary/src/custom/babylon.customMaterial.js
  45. 3 442
      materialsLibrary/src/custom/babylon.customMaterial.ts
  46. 0 12
      materialsLibrary/src/fire/babylon.fireMaterial.ts
  47. 0 12
      materialsLibrary/src/fur/babylon.furMaterial.ts
  48. 0 12
      materialsLibrary/src/gradient/babylon.gradientMaterial.ts
  49. 1 5
      materialsLibrary/src/grid/babylon.gridmaterial.ts
  50. 1 13
      materialsLibrary/src/lava/babylon.lavaMaterial.ts
  51. 0 12
      materialsLibrary/src/normal/babylon.normalMaterial.ts
  52. 0 12
      materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts
  53. 1 13
      materialsLibrary/src/simple/babylon.simpleMaterial.ts
  54. 0 12
      materialsLibrary/src/sky/babylon.skyMaterial.ts
  55. 0 12
      materialsLibrary/src/terrain/babylon.terrainMaterial.ts
  56. 1 13
      materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts
  57. 0 12
      materialsLibrary/src/water/babylon.waterMaterial.ts
  58. 4 0
      src/Lights/Shadows/babylon.shadowGenerator.ts
  59. 115 9
      src/Lights/babylon.light.ts
  60. 31 0
      src/Loading/Plugins/babylon.babylonFileLoader.ts
  61. 24 4
      src/Materials/Textures/babylon.baseTexture.ts
  62. 1 1
      src/Materials/Textures/babylon.texture.ts
  63. 6 5
      src/Materials/Textures/babylon.videoTexture.ts
  64. 13 1
      src/Materials/babylon.fresnelParameters.ts
  65. 128 10
      src/Materials/babylon.material.ts
  66. 111 105
      src/Materials/babylon.materialHelper.ts
  67. 0 12
      src/Materials/babylon.pbrMaterial.ts
  68. 1010 499
      src/Materials/babylon.standardMaterial.ts
  69. 182 9
      src/Mesh/babylon.abstractMesh.ts
  70. 4 0
      src/Mesh/babylon.geometry.ts
  71. 23 5
      src/Mesh/babylon.mesh.ts
  72. 15 0
      src/Mesh/babylon.subMesh.ts
  73. 5 1
      src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts
  74. 3 0
      src/Rendering/babylon.renderingGroup.ts
  75. 3 4
      src/Shaders/default.fragment.fx
  76. 3 4
      src/Shaders/pbr.fragment.fx
  77. 5 1
      src/Tools/babylon.smartArray.ts
  78. 78 46
      src/babylon.engine.ts
  79. 101 7
      src/babylon.scene.ts

+ 8 - 2
canvas2D/src/Engine/babylon.prim2dBase.ts

@@ -2529,7 +2529,10 @@
                         return null;
                     }
                     return this.parent.margin;
-                }, () => this._positioningDirty());
+                }, () => {
+                    this._positioningDirty();
+                    this._updatePositioningState();
+                });
                 this._updatePositioningState();
             }
             return this._margin;
@@ -2607,7 +2610,10 @@
          */
         public get marginAlignment(): PrimitiveAlignment {
             if (!this._marginAlignment) {
-                this._marginAlignment = new PrimitiveAlignment(() => this._positioningDirty());
+                this._marginAlignment = new PrimitiveAlignment(() => {
+                    this._positioningDirty();
+                    this._updatePositioningState();
+                });
                 this._updatePositioningState();
             }
             return this._marginAlignment;

文件差異過大導致無法顯示
+ 31 - 29
dist/preview release/babylon.core.js


文件差異過大導致無法顯示
+ 4359 - 4201
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 38 - 37
dist/preview release/babylon.js


文件差異過大導致無法顯示
+ 2001 - 678
dist/preview release/babylon.max.js


文件差異過大導致無法顯示
+ 4359 - 4201
dist/preview release/babylon.module.d.ts


文件差異過大導致無法顯示
+ 38 - 38
dist/preview release/babylon.noworker.js


文件差異過大導致無法顯示
+ 545 - 137
dist/preview release/canvas2D/babylon.canvas2d.js


文件差異過大導致無法顯示
+ 12 - 12
dist/preview release/canvas2D/babylon.canvas2d.min.js


文件差異過大導致無法顯示
+ 3 - 3
dist/preview release/inspector/babylon.inspector.bundle.js


+ 6 - 0
dist/preview release/inspector/babylon.inspector.d.ts

@@ -522,6 +522,8 @@ declare module INSPECTOR {
         private _displayInputHandler;
         /** Handler used to validate the input by pressing 'enter' */
         private _validateInputHandler;
+        /** Handler used to validate the input by pressing 'esc' */
+        private _escapeInputHandler;
         constructor(prop: Property, parent?: PropertyLine, level?: number);
         /**
          * Init the input element and al its handler :
@@ -534,6 +536,10 @@ declare module INSPECTOR {
          * On escape : removes the input
          */
         private _validateInput(e);
+        /**
+         * On escape : removes the input
+         */
+        private _escapeInput(e);
         /** Removes the input without validating the new value */
         private _removeInputWithoutValidating();
         /** Replaces the default display with an input */

+ 11 - 0
dist/preview release/inspector/babylon.inspector.js

@@ -1612,6 +1612,7 @@ var INSPECTOR;
                 this._initInput();
                 this._valueDiv.addEventListener('click', this._displayInputHandler);
                 this._input.addEventListener('keypress', this._validateInputHandler);
+                this._input.addEventListener('keydown', this._escapeInputHandler);
             }
             // Add this property to the scheduler
             INSPECTOR.Scheduler.getInstance().add(this);
@@ -1628,6 +1629,7 @@ var INSPECTOR;
             // if the property is 'simple', add an event listener to create an input
             this._displayInputHandler = this._displayInput.bind(this);
             this._validateInputHandler = this._validateInput.bind(this);
+            this._escapeInputHandler = this._escapeInput.bind(this);
         };
         /**
          * On enter : validates the new value and removes the input
@@ -1649,6 +1651,15 @@ var INSPECTOR;
                 this.update();
             }
         };
+        /**
+         * On escape : removes the input
+         */
+        PropertyLine.prototype._escapeInput = function (e) {
+            if (e.keyCode == 27) {
+                // Esc : remove input
+                this.update();
+            }
+        };
         /** Removes the input without validating the new value */
         PropertyLine.prototype._removeInputWithoutValidating = function () {
             INSPECTOR.Helpers.CleanDiv(this._valueDiv);

文件差異過大導致無法顯示
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


+ 0 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.d.ts

@@ -11,6 +11,5 @@ declare module BABYLON {
         private _diffusePart;
         private _vertexPositionPart;
         constructor(name: string, builder: ICustomMaterialBuilder, scene: Scene);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
     }
 }

+ 3 - 368
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -25,376 +25,11 @@ var BABYLON;
             _this._diffusePart = 'vec3 diffuseColor=vDiffuseColor.rgb;';
             _this._vertexPositionPart = 'gl_Position=viewProjection*finalWorld*vec4(position,1.0);';
             _this.builder = builder;
+            _this.customShaderNameResolve = function (shaderName) {
+                return _this.builder(new CustomShaderHelper(), shaderName, _this._mainPart, _this._diffusePart, _this._vertexPositionPart);
+            };
             return _this;
         }
-        CustomMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady) {
-                    return true;
-                }
-            }
-            var scene = this.getScene();
-            var engine = scene.getEngine();
-            var needUVs = false;
-            var needNormals = false;
-            this._defines.reset();
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
-            }
-            if (!this.checkReadyOnEveryCall) {
-                if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
-                }
-            }
-            // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
-                    }
-                }
-                if (this.ambientTexture && BABYLON.StandardMaterial.AmbientTextureEnabled) {
-                    if (!this.ambientTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.AMBIENT = true;
-                    }
-                }
-                if (this.opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) {
-                    if (!this.opacityTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.OPACITY = true;
-                        if (this.opacityTexture.getAlphaFromRGB) {
-                            this._defines.OPACITYRGB = true;
-                        }
-                    }
-                }
-                if (this.reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) {
-                    if (!this.reflectionTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needNormals = true;
-                        this._defines.REFLECTION = true;
-                        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;
-                        }
-                        this._defines.REFLECTIONMAP_3D = this.reflectionTexture.isCube;
-                        switch (this.reflectionTexture.coordinatesMode) {
-                            case BABYLON.Texture.CUBIC_MODE:
-                            case BABYLON.Texture.INVCUBIC_MODE:
-                                this._defines.REFLECTIONMAP_CUBIC = true;
-                                break;
-                            case BABYLON.Texture.EXPLICIT_MODE:
-                                this._defines.REFLECTIONMAP_EXPLICIT = true;
-                                break;
-                            case BABYLON.Texture.PLANAR_MODE:
-                                this._defines.REFLECTIONMAP_PLANAR = true;
-                                break;
-                            case BABYLON.Texture.PROJECTION_MODE:
-                                this._defines.REFLECTIONMAP_PROJECTION = true;
-                                break;
-                            case BABYLON.Texture.SKYBOX_MODE:
-                                this._defines.REFLECTIONMAP_SKYBOX = true;
-                                break;
-                            case BABYLON.Texture.SPHERICAL_MODE:
-                                this._defines.REFLECTIONMAP_SPHERICAL = true;
-                                break;
-                            case BABYLON.Texture.EQUIRECTANGULAR_MODE:
-                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
-                                break;
-                            case BABYLON.Texture.FIXED_EQUIRECTANGULAR_MODE:
-                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
-                                break;
-                        }
-                    }
-                }
-                if (this.emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) {
-                    if (!this.emissiveTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.EMISSIVE = true;
-                    }
-                }
-                if (this.lightmapTexture && BABYLON.StandardMaterial.LightmapTextureEnabled) {
-                    if (!this.lightmapTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.LIGHTMAP = true;
-                        this._defines.USELIGHTMAPASSHADOWMAP = this.useLightmapAsShadowmap;
-                    }
-                }
-                if (this.specularTexture && BABYLON.StandardMaterial.SpecularTextureEnabled) {
-                    if (!this.specularTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.SPECULAR = true;
-                        this._defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
-                    }
-                }
-                if (scene.getEngine().getCaps().standardDerivatives && this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
-                    if (!this.bumpTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.BUMP = true;
-                        if (this.useParallax) {
-                            this._defines.PARALLAX = true;
-                            if (this.useParallaxOcclusion) {
-                                this._defines.PARALLAXOCCLUSION = true;
-                            }
-                        }
-                        if (this.invertNormalMapX) {
-                            this._defines.INVERTNORMALMAPX = true;
-                        }
-                        if (this.invertNormalMapY) {
-                            this._defines.INVERTNORMALMAPY = true;
-                        }
-                        if (scene._mirroredCameraPosition) {
-                            this._defines.INVERTNORMALMAPX = !this._defines.INVERTNORMALMAPX;
-                            this._defines.INVERTNORMALMAPY = !this._defines.INVERTNORMALMAPY;
-                        }
-                    }
-                }
-                if (this.refractionTexture && BABYLON.StandardMaterial.RefractionTextureEnabled) {
-                    if (!this.refractionTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.REFRACTION = true;
-                        this._defines.REFRACTIONMAP_3D = this.refractionTexture.isCube;
-                    }
-                }
-                if (this.cameraColorGradingTexture && BABYLON.StandardMaterial.ColorGradingTextureEnabled) {
-                    if (!this.cameraColorGradingTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        this._defines.CAMERACOLORGRADING = true;
-                    }
-                }
-            }
-            // Effect
-            if (scene.clipPlane) {
-                this._defines.CLIPPLANE = true;
-            }
-            if (engine.getAlphaTesting()) {
-                this._defines.ALPHATEST = true;
-            }
-            if (this._shouldUseAlphaFromDiffuseTexture()) {
-                this._defines.ALPHAFROMDIFFUSE = true;
-            }
-            if (this.useEmissiveAsIllumination) {
-                this._defines.EMISSIVEASILLUMINATION = true;
-            }
-            if (this.linkEmissiveWithDiffuse) {
-                this._defines.LINKEMISSIVEWITHDIFFUSE = true;
-            }
-            if (this.useLogarithmicDepth) {
-                this._defines.LOGARITHMICDEPTH = true;
-            }
-            if (this.cameraColorCurves) {
-                this._defines.CAMERACOLORCURVES = true;
-            }
-            // Point size
-            if (this.pointsCloud || scene.forcePointsCloud) {
-                this._defines.POINTSIZE = true;
-            }
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            if (BABYLON.StandardMaterial.FresnelEnabled) {
-                // Fresnel
-                if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled ||
-                    this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled ||
-                    this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled ||
-                    this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled ||
-                    this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._defines.DIFFUSEFRESNEL = true;
-                    }
-                    if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
-                        this._defines.OPACITYFRESNEL = true;
-                    }
-                    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;
-                    }
-                    if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
-                        this._defines.EMISSIVEFRESNEL = true;
-                    }
-                    needNormals = true;
-                    this._defines.FRESNEL = true;
-                }
-            }
-            if (this._defines.SPECULARTERM && this.useSpecularOverAlpha) {
-                this._defines.SPECULAROVERALPHA = true;
-            }
-            // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
-            // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
-                scene.resetCachedMaterial();
-                // Fallbacks
-                var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.REFLECTION) {
-                    fallbacks.addFallback(0, "REFLECTION");
-                }
-                if (this._defines.SPECULAR) {
-                    fallbacks.addFallback(0, "SPECULAR");
-                }
-                if (this._defines.BUMP) {
-                    fallbacks.addFallback(0, "BUMP");
-                }
-                if (this._defines.PARALLAX) {
-                    fallbacks.addFallback(1, "PARALLAX");
-                }
-                if (this._defines.PARALLAXOCCLUSION) {
-                    fallbacks.addFallback(0, "PARALLAXOCCLUSION");
-                }
-                if (this._defines.SPECULAROVERALPHA) {
-                    fallbacks.addFallback(0, "SPECULAROVERALPHA");
-                }
-                if (this._defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-                if (this._defines.POINTSIZE) {
-                    fallbacks.addFallback(0, "POINTSIZE");
-                }
-                if (this._defines.LOGARITHMICDEPTH) {
-                    fallbacks.addFallback(0, "LOGARITHMICDEPTH");
-                }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
-                if (this._defines.SPECULARTERM) {
-                    fallbacks.addFallback(0, "SPECULARTERM");
-                }
-                if (this._defines.DIFFUSEFRESNEL) {
-                    fallbacks.addFallback(1, "DIFFUSEFRESNEL");
-                }
-                if (this._defines.OPACITYFRESNEL) {
-                    fallbacks.addFallback(2, "OPACITYFRESNEL");
-                }
-                if (this._defines.REFLECTIONFRESNEL) {
-                    fallbacks.addFallback(3, "REFLECTIONFRESNEL");
-                }
-                if (this._defines.EMISSIVEFRESNEL) {
-                    fallbacks.addFallback(4, "EMISSIVEFRESNEL");
-                }
-                if (this._defines.FRESNEL) {
-                    fallbacks.addFallback(4, "FRESNEL");
-                }
-                //Attributes
-                var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
-                    attribs.push(BABYLON.VertexBuffer.NormalKind);
-                }
-                if (this._defines.UV1) {
-                    attribs.push(BABYLON.VertexBuffer.UVKind);
-                }
-                if (this._defines.UV2) {
-                    attribs.push(BABYLON.VertexBuffer.UV2Kind);
-                }
-                if (this._defines.VERTEXCOLOR) {
-                    attribs.push(BABYLON.VertexBuffer.ColorKind);
-                }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
-                var shaderName = "default";
-                if (this.builder) {
-                    shaderName = this.builder(new CustomShaderHelper(), shaderName, this._mainPart, this._diffusePart, this._vertexPositionPart);
-                }
-                var join = this._defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
-                    "mBones",
-                    "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix", "refractionMatrix",
-                    "depthValues",
-                    "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
-                    "logarithmicDepthConstant"
-                ];
-                var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"];
-                if (this._defines.CAMERACOLORCURVES) {
-                    BABYLON.ColorCurves.PrepareUniforms(uniforms);
-                }
-                if (this._defines.CAMERACOLORGRADING) {
-                    BABYLON.ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers);
-                }
-                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
-            }
-            if (!this._effect.isReady()) {
-                return false;
-            }
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new BABYLON.StandardMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-            return true;
-        };
         return CustomMaterial;
     }(BABYLON.StandardMaterial));
     BABYLON.CustomMaterial = CustomMaterial;

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -68,9 +68,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         FireMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -180,12 +177,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new FireMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         FireMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -108,9 +108,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         FurMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -253,12 +250,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new FurMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         FurMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -111,9 +111,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         GradientMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -233,12 +230,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new GradientMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         GradientMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js


+ 0 - 3
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -80,9 +80,6 @@ var BABYLON;
             if (!mesh) {
                 return true;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         GridMaterial.prototype.isReady = function (mesh, useInstances) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -108,9 +108,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         LavaMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -241,12 +238,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new LavaMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         LavaMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -102,9 +102,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         NormalMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -234,12 +231,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new NormalMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         NormalMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -61,9 +61,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         ShadowOnlyMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -148,12 +145,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new ShadowOnlyMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         ShadowOnlyMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -70,9 +70,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         SimpleMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -197,12 +194,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new SimpleMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         SimpleMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.skyMaterial.js

@@ -66,9 +66,6 @@ var BABYLON;
             if (!mesh) {
                 return true;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         SkyMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -136,12 +133,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new SkyMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         SkyMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.skyMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -74,9 +74,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         TerrainMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -211,12 +208,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new TerrainMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         TerrainMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -77,9 +77,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         TriPlanarMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -212,12 +209,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new TriPlanarMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         TriPlanarMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js


+ 0 - 9
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -184,9 +184,6 @@ var BABYLON;
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
             return false;
         };
         WaterMaterial.prototype.isReady = function (mesh, useInstances) {
@@ -339,12 +336,6 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new WaterMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
             return true;
         };
         WaterMaterial.prototype.bindOnlyWorldMatrix = function (world) {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


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

@@ -13,7 +13,7 @@
  - New `VideoTexture.CreateFromWebCam` to generate video texture using WebRTC. [Demo](https://www.babylonjs-playground.com#1R77YT#2) - (Sebastien Vandenberghe)(https://github.com/sebavanmicrosoft) / ([deltakosh](https://github.com/deltakosh))
  - New Facet Data feature ([jerome](https://github.com/jbousquie))
  - babylon.fontTexture.ts was moved from babylon.js to canvas2D ([nockawa](https://github.com/nockawa))
- - Multi-platform Compressed Textures for Desktops & Mobile Devices with fall back.  Batch (dos) scripts to convert entire directories of .jpg's & .png's ([jcpalmer](https://github.com/Palmer-JC))
+ - Multi-platform Compressed Textures for Desktops & Mobile Devices with fall back.  Batch (dos) scripts to convert entire directories of .jpg's & .png's [Doc](http://doc.babylonjs.com/tutorials/multi-platform_compressed_textures) ([jcpalmer](https://github.com/Palmer-JC))
  - All deprecated functions and properties were removed ([deltakosh](https://github.com/deltakosh))
 
 ### Updates

+ 87 - 73
inspector/src/details/PropertyLine.ts

@@ -5,14 +5,14 @@ module INSPECTOR {
         /**
          * Format the value of the given property of the given object.
          */
-        public static format(obj: any, prop:string) : string {
+        public static format(obj: any, prop: string): string {
             // Get original value;
             let value = obj[prop];
             // test if type PrimitiveAlignment is available (only included in canvas2d)
-            if (BABYLON.PrimitiveAlignment) {                
+            if (BABYLON.PrimitiveAlignment) {
                 if (obj instanceof BABYLON.PrimitiveAlignment) {
                     if (prop === 'horizontal') {
-                        switch(value) {
+                        switch (value) {
                             case BABYLON.PrimitiveAlignment.AlignLeft:
                                 return 'left';
                             case BABYLON.PrimitiveAlignment.AlignRight:
@@ -23,7 +23,7 @@ module INSPECTOR {
                                 return 'stretch';
                         }
                     } else if (prop === 'vertical') {
-                        switch(value) {
+                        switch (value) {
                             case BABYLON.PrimitiveAlignment.AlignTop:
                                 return 'top';
                             case BABYLON.PrimitiveAlignment.AlignBottom:
@@ -54,66 +54,69 @@ module INSPECTOR {
      * 
      */
     export class PropertyLine {
-        
+
         // The property can be of any type (Property internally can have any type), relative to this._obj
-        private _property : Property;    
+        private _property: Property;
         //The HTML element corresponding to this line
-        private _div : HTMLElement;
+        private _div: HTMLElement;
         // The div containing the value to display. Used to update dynamically the property
-        private _valueDiv : HTMLElement;
+        private _valueDiv: HTMLElement;
         // If the type is complex, this property will have child to update
-        private _children : Array<PropertyLine> = [];        
+        private _children: Array<PropertyLine> = [];
         // Array representing the simple type. All others are considered 'complex'
         private static _SIMPLE_TYPE = ['number', 'string', 'boolean'];
         // The number of pixel at each children step
         private static _MARGIN_LEFT = 15;
         // The margin-left used to display to row
-        private _level : number;
+        private _level: number;
         /** The list of viewer element displayed at the end of the line (color, texture...) */
-        private _elements : Array<BasicElement> = [];
+        private _elements: Array<BasicElement> = [];
         /** The property parent of this one. Used to update the value of this property and to retrieve the correct object */
-        private _parent : PropertyLine;
+        private _parent: PropertyLine;
         /** The input element to display if this property is 'simple' in order to update it */
-        private _input : HTMLInputElement;
+        private _input: HTMLInputElement;
         /** Display input handler (stored to be removed afterwards) */
-        private _displayInputHandler : EventListener;
+        private _displayInputHandler: EventListener;
         /** Handler used to validate the input by pressing 'enter' */
-        private _validateInputHandler : EventListener;
-        
-        constructor(prop : Property, parent?: PropertyLine, level:number=0) {
+        private _validateInputHandler: EventListener;
+        /** Handler used to validate the input by pressing 'esc' */
+        private _escapeInputHandler: EventListener;
+
+        constructor(prop: Property, parent?: PropertyLine, level: number = 0) {
             this._property = prop;
-            this._level    = level;       
-            this._parent   = parent;   
-                         
+            this._level = level;
+            this._parent = parent;
+
             this._div = Helpers.CreateDiv('row');
             this._div.style.marginLeft = `${this._level}px`;
-            
+
             // Property name
-            let propName : HTMLElement = Helpers.CreateDiv('prop-name', this._div);
+            let propName: HTMLElement = Helpers.CreateDiv('prop-name', this._div);
             propName.textContent = `${this.name}`;
 
             // Value
             this._valueDiv = Helpers.CreateDiv('prop-value', this._div);
             this._valueDiv.textContent = this._displayValueContent() || '-'; // Init value text node
-            
+
             this._createElements();
-            
+
             for (let elem of this._elements) {
                 this._valueDiv.appendChild(elem.toHtml());
             }
-            
+
             this._updateValue();
 
             // If the property type is not simple, add click event to unfold its children
-            if (!this._isSimple()) { 
+            if (!this._isSimple()) {
                 this._valueDiv.classList.add('clickable');
                 this._valueDiv.addEventListener('click', this._addDetails.bind(this));
             } else {
                 this._initInput();
                 this._valueDiv.addEventListener('click', this._displayInputHandler);
                 this._input.addEventListener('keypress', this._validateInputHandler);
+                this._input.addEventListener('keydown', this._escapeInputHandler);
             }
-            
+
             // Add this property to the scheduler
             Scheduler.getInstance().add(this);
         }
@@ -124,21 +127,22 @@ module INSPECTOR {
          * - enters updates the property
          */
         private _initInput() {
-            
+
             // Create the input element
             this._input = document.createElement('input') as HTMLInputElement;
             this._input.setAttribute('type', 'text');
 
             // if the property is 'simple', add an event listener to create an input
-            this._displayInputHandler  = this._displayInput.bind(this);
+            this._displayInputHandler = this._displayInput.bind(this);
             this._validateInputHandler = this._validateInput.bind(this);
+            this._escapeInputHandler = this._escapeInput.bind(this);
         }
 
         /** 
          * On enter : validates the new value and removes the input
          * On escape : removes the input
          */
-        private _validateInput(e : KeyboardEvent) {
+        private _validateInput(e: KeyboardEvent) {
             if (e.keyCode == 13) {
                 // Enter : validate the new value
                 let newValue = this._input.value;
@@ -148,8 +152,18 @@ module INSPECTOR {
                 this.update();
                 // resume scheduler
                 Scheduler.getInstance().pause = false;
-                
-            } else if (e.keyCode == 27) { 
+
+            } else if (e.keyCode == 27) {
+                // Esc : remove input
+                this.update();
+            }
+        }
+
+        /** 
+         * On escape : removes the input
+         */
+        private _escapeInput(e: KeyboardEvent) {
+            if (e.keyCode == 27) {
                 // Esc : remove input
                 this.update();
             }
@@ -162,7 +176,7 @@ module INSPECTOR {
             // restore elements
             for (let elem of this._elements) {
                 this._valueDiv.appendChild(elem.toHtml());
-            }            
+            }
             this._valueDiv.addEventListener('click', this._displayInputHandler);
         }
 
@@ -176,7 +190,7 @@ module INSPECTOR {
             this._valueDiv.textContent = "";
             this._input.value = valueTxt;
             this._valueDiv.appendChild(this._input);
-            
+
             // Pause the scheduler
             Scheduler.getInstance().pause = true;
         }
@@ -190,76 +204,76 @@ module INSPECTOR {
             if (this._parent) {
                 this._property.obj = this._parent.updateObject();
             }
-            return this._property.value;            
+            return this._property.value;
         }
 
         // Returns the property name
-        public get name() : string {
+        public get name(): string {
             return this._property.name;
         }
 
         // Returns the value of the property
-        public get value() : any {
+        public get value(): any {
             return PropertyFormatter.format(this._property.obj, this._property.name);
         }
 
         // Returns the type of the property
-        public get type() : string {
+        public get type(): string {
             return this._property.type;
         }
-        
+
         /**
          * Creates elements that wil be displayed on a property line, depending on the
          * type of the property.
          */
         private _createElements() {
-            
+
             // Colors
-            if (this.type == 'Color3' ||this.type == 'Color4') {
+            if (this.type == 'Color3' || this.type == 'Color4') {
                 this._elements.push(new ColorElement(this.value));
-            } 
+            }
             // Texture
             if (this.type == 'Texture') {
                 this._elements.push(new TextureElement(this.value));
-            }   
+            }
             // HDR Texture
             if (this.type == 'HDRCubeTexture') {
                 this._elements.push(new HDRCubeTextureElement(this.value));
-            }      
+            }
             if (this.type == 'CubeTexture') {
                 this._elements.push(new CubeTextureElement(this.value));
-            }      
+            }
         }
 
         // Returns the text displayed on the left of the property name : 
         // - If the type is simple, display its value
         // - If the type is complex, but instance of Vector2, Size, display the type and its tostring
         // - If the type is another one, display the Type
-        private _displayValueContent () {
-            
+        private _displayValueContent() {
+
             let value = this.value;
             // If the value is a number, truncate it if needed
             if (typeof value === 'number') {
-                return Helpers.Trunc(value);                
-            } 
+                return Helpers.Trunc(value);
+            }
             // If it's a string or a boolean, display its value
             if (typeof value === 'string' || typeof value === 'boolean') {
-                return value;          
-            } 
+                return value;
+            }
             return PROPERTIES.format(value);
-            
+
         }
-        
+
         /** Delete properly this property line. 
          * Removes itself from the scheduler.
          * Dispose all viewer element (color, texture...)
          */
         public dispose() {
             // console.log('delete properties', this.name);
-            Scheduler.getInstance().remove(this); 
+            Scheduler.getInstance().remove(this);
             for (let child of this._children) {
                 // console.log('delete properties', child.name);
-                Scheduler.getInstance().remove(child); 
+                Scheduler.getInstance().remove(child);
             }
             for (let elem of this._elements) {
                 elem.dispose();
@@ -281,20 +295,20 @@ module INSPECTOR {
                 elem.update(this.value);
             }
         }
-        
+
         /**
          * Update the property division with the new property value. 
          * If this property is complex, update its child, otherwise update its text content
          */
-        public update() {            
-           this._removeInputWithoutValidating();
-           this._updateValue();
+        public update() {
+            this._removeInputWithoutValidating();
+            this._updateValue();
         }
-        
+
         /**
          * Returns true if the given instance is a simple type  
          */
-        private static _IS_TYPE_SIMPLE(inst:any) {
+        private static _IS_TYPE_SIMPLE(inst: any) {
             let type = Helpers.GET_TYPE(inst);
             return PropertyLine._SIMPLE_TYPE.indexOf(type) != -1;
         }
@@ -303,21 +317,21 @@ module INSPECTOR {
          * Returns true if the type of this property is simple, false otherwise.
          * Returns true if the value is null
          */
-        private _isSimple() : boolean {
+        private _isSimple(): boolean {
             if (this.value != null && this.type !== 'type_not_defined') {
                 if (PropertyLine._SIMPLE_TYPE.indexOf(this.type) == -1) {
                     // complex type : return the type name
                     return false;
                 } else {
                     // simple type : return value
-                    return true; 
+                    return true;
                 }
             } else {
                 return true;
             }
         }
 
-        public toHtml() : HTMLElement {
+        public toHtml(): HTMLElement {
             return this._div;
         }
 
@@ -325,7 +339,7 @@ module INSPECTOR {
          * Add sub properties in case of a complex type
          */
         private _addDetails() {
-            if (this._div.classList.contains('unfolded')) {            
+            if (this._div.classList.contains('unfolded')) {
                 // Remove class unfolded
                 this._div.classList.remove('unfolded');
                 // remove html children
@@ -335,23 +349,23 @@ module INSPECTOR {
             } else {
                 // if children does not exists, generate it
                 this._div.classList.toggle('unfolded');
-                if (this._children.length ==0) {                    
+                if (this._children.length == 0) {
                     let objToDetail = this.value;
                     let propToDisplay = PROPERTIES[Helpers.GET_TYPE(objToDetail)].properties.reverse();
                     let propertyLine = null;
-                    
+
                     for (let prop of propToDisplay) {
                         let infos = new Property(prop, this._property.value);
-                        let child = new PropertyLine(infos, this, this._level+PropertyLine._MARGIN_LEFT);
+                        let child = new PropertyLine(infos, this, this._level + PropertyLine._MARGIN_LEFT);
                         this._children.push(child);
                     }
-                } 
+                }
                 // otherwise display it                    
                 for (let child of this._children) {
                     this._div.parentNode.insertBefore(child.toHtml(), this._div.nextSibling);
                 }
-            }            
-        }        
-    } 
-    
+            }
+        }
+    }
+
 }

文件差異過大導致無法顯示
+ 1 - 1
materialsLibrary/src/custom/Babylon.CustomMaterial.js.map


+ 3 - 368
materialsLibrary/src/custom/babylon.customMaterial.js

@@ -25,376 +25,11 @@ var BABYLON;
             _this._diffusePart = 'vec3 diffuseColor=vDiffuseColor.rgb;';
             _this._vertexPositionPart = 'gl_Position=viewProjection*finalWorld*vec4(position,1.0);';
             _this.builder = builder;
+            _this.customShaderNameResolve = function (shaderName) {
+                return _this.builder(new CustomShaderHelper(), shaderName, _this._mainPart, _this._diffusePart, _this._vertexPositionPart);
+            };
             return _this;
         }
-        CustomMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady) {
-                    return true;
-                }
-            }
-            var scene = this.getScene();
-            var engine = scene.getEngine();
-            var needUVs = false;
-            var needNormals = false;
-            this._defines.reset();
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
-            }
-            if (!this.checkReadyOnEveryCall) {
-                if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
-                }
-            }
-            // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
-                    }
-                }
-                if (this.ambientTexture && BABYLON.StandardMaterial.AmbientTextureEnabled) {
-                    if (!this.ambientTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.AMBIENT = true;
-                    }
-                }
-                if (this.opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) {
-                    if (!this.opacityTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.OPACITY = true;
-                        if (this.opacityTexture.getAlphaFromRGB) {
-                            this._defines.OPACITYRGB = true;
-                        }
-                    }
-                }
-                if (this.reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) {
-                    if (!this.reflectionTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needNormals = true;
-                        this._defines.REFLECTION = true;
-                        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;
-                        }
-                        this._defines.REFLECTIONMAP_3D = this.reflectionTexture.isCube;
-                        switch (this.reflectionTexture.coordinatesMode) {
-                            case BABYLON.Texture.CUBIC_MODE:
-                            case BABYLON.Texture.INVCUBIC_MODE:
-                                this._defines.REFLECTIONMAP_CUBIC = true;
-                                break;
-                            case BABYLON.Texture.EXPLICIT_MODE:
-                                this._defines.REFLECTIONMAP_EXPLICIT = true;
-                                break;
-                            case BABYLON.Texture.PLANAR_MODE:
-                                this._defines.REFLECTIONMAP_PLANAR = true;
-                                break;
-                            case BABYLON.Texture.PROJECTION_MODE:
-                                this._defines.REFLECTIONMAP_PROJECTION = true;
-                                break;
-                            case BABYLON.Texture.SKYBOX_MODE:
-                                this._defines.REFLECTIONMAP_SKYBOX = true;
-                                break;
-                            case BABYLON.Texture.SPHERICAL_MODE:
-                                this._defines.REFLECTIONMAP_SPHERICAL = true;
-                                break;
-                            case BABYLON.Texture.EQUIRECTANGULAR_MODE:
-                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
-                                break;
-                            case BABYLON.Texture.FIXED_EQUIRECTANGULAR_MODE:
-                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
-                                break;
-                        }
-                    }
-                }
-                if (this.emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) {
-                    if (!this.emissiveTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.EMISSIVE = true;
-                    }
-                }
-                if (this.lightmapTexture && BABYLON.StandardMaterial.LightmapTextureEnabled) {
-                    if (!this.lightmapTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.LIGHTMAP = true;
-                        this._defines.USELIGHTMAPASSHADOWMAP = this.useLightmapAsShadowmap;
-                    }
-                }
-                if (this.specularTexture && BABYLON.StandardMaterial.SpecularTextureEnabled) {
-                    if (!this.specularTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.SPECULAR = true;
-                        this._defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
-                    }
-                }
-                if (scene.getEngine().getCaps().standardDerivatives && this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
-                    if (!this.bumpTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.BUMP = true;
-                        if (this.useParallax) {
-                            this._defines.PARALLAX = true;
-                            if (this.useParallaxOcclusion) {
-                                this._defines.PARALLAXOCCLUSION = true;
-                            }
-                        }
-                        if (this.invertNormalMapX) {
-                            this._defines.INVERTNORMALMAPX = true;
-                        }
-                        if (this.invertNormalMapY) {
-                            this._defines.INVERTNORMALMAPY = true;
-                        }
-                        if (scene._mirroredCameraPosition) {
-                            this._defines.INVERTNORMALMAPX = !this._defines.INVERTNORMALMAPX;
-                            this._defines.INVERTNORMALMAPY = !this._defines.INVERTNORMALMAPY;
-                        }
-                    }
-                }
-                if (this.refractionTexture && BABYLON.StandardMaterial.RefractionTextureEnabled) {
-                    if (!this.refractionTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.REFRACTION = true;
-                        this._defines.REFRACTIONMAP_3D = this.refractionTexture.isCube;
-                    }
-                }
-                if (this.cameraColorGradingTexture && BABYLON.StandardMaterial.ColorGradingTextureEnabled) {
-                    if (!this.cameraColorGradingTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        this._defines.CAMERACOLORGRADING = true;
-                    }
-                }
-            }
-            // Effect
-            if (scene.clipPlane) {
-                this._defines.CLIPPLANE = true;
-            }
-            if (engine.getAlphaTesting()) {
-                this._defines.ALPHATEST = true;
-            }
-            if (this._shouldUseAlphaFromDiffuseTexture()) {
-                this._defines.ALPHAFROMDIFFUSE = true;
-            }
-            if (this.useEmissiveAsIllumination) {
-                this._defines.EMISSIVEASILLUMINATION = true;
-            }
-            if (this.linkEmissiveWithDiffuse) {
-                this._defines.LINKEMISSIVEWITHDIFFUSE = true;
-            }
-            if (this.useLogarithmicDepth) {
-                this._defines.LOGARITHMICDEPTH = true;
-            }
-            if (this.cameraColorCurves) {
-                this._defines.CAMERACOLORCURVES = true;
-            }
-            // Point size
-            if (this.pointsCloud || scene.forcePointsCloud) {
-                this._defines.POINTSIZE = true;
-            }
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            if (BABYLON.StandardMaterial.FresnelEnabled) {
-                // Fresnel
-                if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled ||
-                    this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled ||
-                    this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled ||
-                    this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled ||
-                    this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._defines.DIFFUSEFRESNEL = true;
-                    }
-                    if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
-                        this._defines.OPACITYFRESNEL = true;
-                    }
-                    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;
-                    }
-                    if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
-                        this._defines.EMISSIVEFRESNEL = true;
-                    }
-                    needNormals = true;
-                    this._defines.FRESNEL = true;
-                }
-            }
-            if (this._defines.SPECULARTERM && this.useSpecularOverAlpha) {
-                this._defines.SPECULAROVERALPHA = true;
-            }
-            // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
-            // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
-                scene.resetCachedMaterial();
-                // Fallbacks
-                var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.REFLECTION) {
-                    fallbacks.addFallback(0, "REFLECTION");
-                }
-                if (this._defines.SPECULAR) {
-                    fallbacks.addFallback(0, "SPECULAR");
-                }
-                if (this._defines.BUMP) {
-                    fallbacks.addFallback(0, "BUMP");
-                }
-                if (this._defines.PARALLAX) {
-                    fallbacks.addFallback(1, "PARALLAX");
-                }
-                if (this._defines.PARALLAXOCCLUSION) {
-                    fallbacks.addFallback(0, "PARALLAXOCCLUSION");
-                }
-                if (this._defines.SPECULAROVERALPHA) {
-                    fallbacks.addFallback(0, "SPECULAROVERALPHA");
-                }
-                if (this._defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-                if (this._defines.POINTSIZE) {
-                    fallbacks.addFallback(0, "POINTSIZE");
-                }
-                if (this._defines.LOGARITHMICDEPTH) {
-                    fallbacks.addFallback(0, "LOGARITHMICDEPTH");
-                }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
-                if (this._defines.SPECULARTERM) {
-                    fallbacks.addFallback(0, "SPECULARTERM");
-                }
-                if (this._defines.DIFFUSEFRESNEL) {
-                    fallbacks.addFallback(1, "DIFFUSEFRESNEL");
-                }
-                if (this._defines.OPACITYFRESNEL) {
-                    fallbacks.addFallback(2, "OPACITYFRESNEL");
-                }
-                if (this._defines.REFLECTIONFRESNEL) {
-                    fallbacks.addFallback(3, "REFLECTIONFRESNEL");
-                }
-                if (this._defines.EMISSIVEFRESNEL) {
-                    fallbacks.addFallback(4, "EMISSIVEFRESNEL");
-                }
-                if (this._defines.FRESNEL) {
-                    fallbacks.addFallback(4, "FRESNEL");
-                }
-                //Attributes
-                var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
-                    attribs.push(BABYLON.VertexBuffer.NormalKind);
-                }
-                if (this._defines.UV1) {
-                    attribs.push(BABYLON.VertexBuffer.UVKind);
-                }
-                if (this._defines.UV2) {
-                    attribs.push(BABYLON.VertexBuffer.UV2Kind);
-                }
-                if (this._defines.VERTEXCOLOR) {
-                    attribs.push(BABYLON.VertexBuffer.ColorKind);
-                }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
-                var shaderName = "default";
-                if (this.builder) {
-                    shaderName = this.builder(new CustomShaderHelper(), shaderName, this._mainPart, this._diffusePart, this._vertexPositionPart);
-                }
-                var join = this._defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
-                    "mBones",
-                    "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix", "refractionMatrix",
-                    "depthValues",
-                    "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
-                    "logarithmicDepthConstant"
-                ];
-                var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"];
-                if (this._defines.CAMERACOLORCURVES) {
-                    BABYLON.ColorCurves.PrepareUniforms(uniforms);
-                }
-                if (this._defines.CAMERACOLORGRADING) {
-                    BABYLON.ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers);
-                }
-                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
-            }
-            if (!this._effect.isReady()) {
-                return false;
-            }
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new BABYLON.StandardMaterialDefines();
-                }
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-            return true;
-        };
         return CustomMaterial;
     }(BABYLON.StandardMaterial));
     BABYLON.CustomMaterial = CustomMaterial;

+ 3 - 442
materialsLibrary/src/custom/babylon.customMaterial.ts

@@ -20,455 +20,16 @@ module BABYLON {
         constructor (name: string, builder:ICustomMaterialBuilder, scene: Scene) {
             super(name, scene);  
             this.builder = builder;             
-        }   
- 
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady) {
-                    return true;
-                }
-            }
-
-            var scene = this.getScene();
-            var engine = scene.getEngine();
-            var needUVs = false;
-            var needNormals = false;
-
-            this._defines.reset();
-
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
-            }
-
-            if (!this.checkReadyOnEveryCall) {
-                if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
-                }
-            }
-
-            // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
-                    }
-                }
-
-                if (this.ambientTexture && StandardMaterial.AmbientTextureEnabled) {
-                    if (!this.ambientTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.AMBIENT = true;
-                    }
-                }
-
-                if (this.opacityTexture && StandardMaterial.OpacityTextureEnabled) {
-                    if (!this.opacityTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.OPACITY = true;
-
-                        if (this.opacityTexture.getAlphaFromRGB) {
-                            this._defines.OPACITYRGB = true;
-                        }
-                    }
-                }
-
-                if (this.reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
-                    if (!this.reflectionTexture.isReady()) {
-                        return false;
-                    } else {
-                        needNormals = true;
-                        this._defines.REFLECTION = true;
-
-                        if (this.roughness > 0) {
-                            this._defines.ROUGHNESS = true;
-                        }
-
-                        if (this.useReflectionOverAlpha) {
-                            this._defines.REFLECTIONOVERALPHA = true;
-                        }
-
-                        if (this.reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE) {
-                            this._defines.INVERTCUBICMAP = true;
-                        }
-
-                        this._defines.REFLECTIONMAP_3D = this.reflectionTexture.isCube;
-
-                        switch (this.reflectionTexture.coordinatesMode) {
-                            case Texture.CUBIC_MODE:
-                            case Texture.INVCUBIC_MODE:
-                                this._defines.REFLECTIONMAP_CUBIC = true;
-                                break;
-                            case Texture.EXPLICIT_MODE:
-                                this._defines.REFLECTIONMAP_EXPLICIT = true;
-                                break;
-                            case Texture.PLANAR_MODE:
-                                this._defines.REFLECTIONMAP_PLANAR = true;
-                                break;
-                            case Texture.PROJECTION_MODE:
-                                this._defines.REFLECTIONMAP_PROJECTION = true;
-                                break;
-                            case Texture.SKYBOX_MODE:
-                                this._defines.REFLECTIONMAP_SKYBOX = true;
-                                break;
-                            case Texture.SPHERICAL_MODE:
-                                this._defines.REFLECTIONMAP_SPHERICAL = true;
-                                break;
-                            case Texture.EQUIRECTANGULAR_MODE:
-                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
-                                break;
-                            case Texture.FIXED_EQUIRECTANGULAR_MODE:
-                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
-                                break;
-                        }
-                    }
-                }
-
-                if (this.emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
-                    if (!this.emissiveTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.EMISSIVE = true;
-                    }
-                }
-
-                if (this.lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
-                    if (!this.lightmapTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.LIGHTMAP = true;
-                        this._defines.USELIGHTMAPASSHADOWMAP = this.useLightmapAsShadowmap;
-                    }
-                }
-
-                if (this.specularTexture && StandardMaterial.SpecularTextureEnabled) {
-                    if (!this.specularTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.SPECULAR = true;
-                        this._defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
-                    }
-                }
-
-                if (scene.getEngine().getCaps().standardDerivatives && this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
-                    if (!this.bumpTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.BUMP = true;
-
-                        if (this.useParallax) {
-                            this._defines.PARALLAX = true;
-                            if (this.useParallaxOcclusion) {
-                                this._defines.PARALLAXOCCLUSION = true;
-                            }
-                        }
-
-                        if (this.invertNormalMapX) {
-                            this._defines.INVERTNORMALMAPX = true;
-                        }
-
-                        if (this.invertNormalMapY) {
-                            this._defines.INVERTNORMALMAPY = true;
-                        }
-
-                        if (scene._mirroredCameraPosition) {
-                            this._defines.INVERTNORMALMAPX = !this._defines.INVERTNORMALMAPX;
-                            this._defines.INVERTNORMALMAPY = !this._defines.INVERTNORMALMAPY;
-                        }
-                    }
-                }
-
-                if (this.refractionTexture && StandardMaterial.RefractionTextureEnabled) {
-                    if (!this.refractionTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.REFRACTION = true;
-
-                        this._defines.REFRACTIONMAP_3D = this.refractionTexture.isCube;
-                    }
-                }
-
-                if (this.cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
-                    if (!this.cameraColorGradingTexture.isReady()) {
-                        return false;
-                    } else {
-                        this._defines.CAMERACOLORGRADING = true;
-                    }
-                }
-            }
-
-            // Effect
-            if (scene.clipPlane) {
-                this._defines.CLIPPLANE = true;
-            }
-
-            if (engine.getAlphaTesting()) {
-                this._defines.ALPHATEST = true;
-            }
-
-            if (this._shouldUseAlphaFromDiffuseTexture()) {
-                this._defines.ALPHAFROMDIFFUSE = true;
-            }
-
-            if (this.useEmissiveAsIllumination) {
-                this._defines.EMISSIVEASILLUMINATION = true;
-            }
-
-            if (this.linkEmissiveWithDiffuse) {
-                this._defines.LINKEMISSIVEWITHDIFFUSE = true;
-            }
-
-            if (this.useLogarithmicDepth) {
-                this._defines.LOGARITHMICDEPTH = true;
-            }
-            
-            if (this.cameraColorCurves) {
-                this._defines.CAMERACOLORCURVES = true;
-            }
-
-            // Point size
-            if (this.pointsCloud || scene.forcePointsCloud) {
-                this._defines.POINTSIZE = true;
-            }
-
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-
-            if (StandardMaterial.FresnelEnabled) {
-                // Fresnel
-                if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled ||
-                    this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled ||
-                    this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled ||
-                    this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled ||
-                    this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
 
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._defines.DIFFUSEFRESNEL = true;
-                    }
-
-                    if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
-                        this._defines.OPACITYFRESNEL = true;
-                    }
-
-                    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;
-                    }
-
-                    if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
-                        this._defines.EMISSIVEFRESNEL = true;
-                    }
-
-                    needNormals = true;
-                    this._defines.FRESNEL = true;
-                }
-            }
-
-            if (this._defines.SPECULARTERM && this.useSpecularOverAlpha) {
-                this._defines.SPECULAROVERALPHA = true;
-            }
-
-            // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
-
-            // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
-
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (this._defines.REFLECTION) {
-                    fallbacks.addFallback(0, "REFLECTION");
-                }
-
-                if (this._defines.SPECULAR) {
-                    fallbacks.addFallback(0, "SPECULAR");
-                }
-
-                if (this._defines.BUMP) {
-                    fallbacks.addFallback(0, "BUMP");
-                }
-
-                if (this._defines.PARALLAX) {
-                    fallbacks.addFallback(1, "PARALLAX");
-                }
-
-                if (this._defines.PARALLAXOCCLUSION) {
-                    fallbacks.addFallback(0, "PARALLAXOCCLUSION");
-                }
-
-                if (this._defines.SPECULAROVERALPHA) {
-                    fallbacks.addFallback(0, "SPECULAROVERALPHA");
-                }
-
-                if (this._defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                if (this._defines.POINTSIZE) {
-                    fallbacks.addFallback(0, "POINTSIZE");
-                }
-
-                if (this._defines.LOGARITHMICDEPTH) {
-                    fallbacks.addFallback(0, "LOGARITHMICDEPTH");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
-
-                if (this._defines.SPECULARTERM) {
-                    fallbacks.addFallback(0, "SPECULARTERM");
-                }
-
-                if (this._defines.DIFFUSEFRESNEL) {
-                    fallbacks.addFallback(1, "DIFFUSEFRESNEL");
-                }
-
-                if (this._defines.OPACITYFRESNEL) {
-                    fallbacks.addFallback(2, "OPACITYFRESNEL");
-                }
-
-                if (this._defines.REFLECTIONFRESNEL) {
-                    fallbacks.addFallback(3, "REFLECTIONFRESNEL");
-                }
-
-                if (this._defines.EMISSIVEFRESNEL) {
-                    fallbacks.addFallback(4, "EMISSIVEFRESNEL");
-                }
-
-                if (this._defines.FRESNEL) {
-                    fallbacks.addFallback(4, "FRESNEL");
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (this._defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (this._defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (this._defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (this._defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
-                
-                var shaderName = "default";
-               
-                if (this.builder) {
- 
-                     shaderName = this.builder(
+            this.customShaderNameResolve = (shaderName) => {
+                return this.builder(
                          new CustomShaderHelper(),
                          shaderName, 
                          this._mainPart,
                          this._diffusePart, 
                          this._vertexPositionPart ); 
-               }
-
-                var join = this._defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
-                    "mBones",
-                    "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix", "refractionMatrix",
-                    "depthValues",
-                    "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
-                    "logarithmicDepthConstant"
-                ];
-
-                var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"]
-
-                if (this._defines.CAMERACOLORCURVES) {
-                    ColorCurves.PrepareUniforms(uniforms);
-                }
-                if (this._defines.CAMERACOLORGRADING) {
-                    ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers);
-                }
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
-
-                this._effect = scene.getEngine().createEffect(shaderName,
-                    attribs, uniforms, samplers,
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
             }
-            if (!this._effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new StandardMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
-            return true;
-        }
-    
+        }           
     }
 }
      

+ 0 - 12
materialsLibrary/src/fire/babylon.fireMaterial.ts

@@ -74,10 +74,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -216,14 +212,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new FireMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 0 - 12
materialsLibrary/src/fur/babylon.furMaterial.ts

@@ -137,10 +137,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -315,14 +311,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new FurMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 0 - 12
materialsLibrary/src/gradient/babylon.gradientMaterial.ts

@@ -118,10 +118,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -274,14 +270,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new GradientMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 1 - 5
materialsLibrary/src/grid/babylon.gridmaterial.ts

@@ -80,11 +80,7 @@ module BABYLON {
             if (!mesh) {
                 return true;
             }
-
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
+            
             return false;
         }
 

+ 1 - 13
materialsLibrary/src/lava/babylon.lavaMaterial.ts

@@ -123,10 +123,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -287,15 +283,7 @@ module BABYLON {
 
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new LavaMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
+            
             return true;
         }
 

+ 0 - 12
materialsLibrary/src/normal/babylon.normalMaterial.ts

@@ -100,10 +100,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -264,14 +260,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new NormalMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 0 - 12
materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts

@@ -54,10 +54,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -168,14 +164,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new ShadowOnlyMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 1 - 13
materialsLibrary/src/simple/babylon.simpleMaterial.ts

@@ -69,11 +69,7 @@ module BABYLON {
             if (this._defines.INSTANCES !== useInstances) {
                 return false;
             }
-
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
+            
             return false;
         }
 
@@ -229,14 +225,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new SimpleMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 0 - 12
materialsLibrary/src/sky/babylon.skyMaterial.ts

@@ -75,10 +75,6 @@ module BABYLON {
             if (!mesh) {
                 return true;
             }
-            
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
 
             return false;
         }
@@ -170,14 +166,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new SkyMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 0 - 12
materialsLibrary/src/terrain/babylon.terrainMaterial.ts

@@ -97,10 +97,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -267,14 +263,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new TerrainMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

+ 1 - 13
materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts

@@ -104,10 +104,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -270,15 +266,7 @@ module BABYLON {
 
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
-
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new TriPlanarMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
+            
             return true;
         }
 

+ 0 - 12
materialsLibrary/src/water/babylon.waterMaterial.ts

@@ -209,10 +209,6 @@ module BABYLON {
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 		
@@ -405,14 +401,6 @@ module BABYLON {
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new WaterMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
 		}
         

+ 4 - 0
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -102,6 +102,8 @@
                 this._shadowMap.anisotropicFilteringLevel = 1;
                 this._shadowMap.updateSamplingMode(Texture.NEAREST_SAMPLINGMODE);
             }
+
+            this._light._markMeshesAsLightDirty();
         }
 
         public get useVarianceShadowMap(): boolean {
@@ -187,6 +189,7 @@
             this._mapSize = mapSize;
 
             light._shadowGenerator = this;
+            light._markMeshesAsLightDirty();
 
             // Texture type fallback from float to int if not supported.
             var textureType: number;
@@ -512,6 +515,7 @@
             }
 
             this._light._shadowGenerator = null;
+            this._light._markMeshesAsLightDirty();
         }
         /**
          * Serializes the ShadowGenerator and returns a serializationObject.  

+ 115 - 9
src/Lights/babylon.light.ts

@@ -1,6 +1,6 @@
 module BABYLON {
 
-    export interface IShadowLight {
+    export interface IShadowLight extends Light {
         id: string;
         position: Vector3;
         transformedPosition: Vector3;
@@ -70,17 +70,61 @@
         @serialize()
         public range = Number.MAX_VALUE;
 
-        @serialize()
-        public includeOnlyWithLayerMask = 0;
+        private _includedOnlyMeshes: AbstractMesh[];
+        public get includedOnlyMeshes(): AbstractMesh[] {
+            return this._includedOnlyMeshes;
+        }
 
-        public includedOnlyMeshes = new Array<AbstractMesh>();
-        public excludedMeshes = new Array<AbstractMesh>();
+        public set includedOnlyMeshes(value: AbstractMesh[]) {
+            this._includedOnlyMeshes = value;
+            this._hookArray(value);
+        }
 
-        @serialize()
-        public excludeWithLayerMask = 0;
+        private _excludedMeshes: AbstractMesh[];
+        public get excludedMeshes(): AbstractMesh[] {
+            return this._excludedMeshes;
+        }
+        public set excludedMeshes(value: AbstractMesh[]) {
+            this._excludedMeshes = value;
+            this._hookArray(value);
+        }        
 
-        @serialize()
-        public lightmapMode = 0;
+        @serialize("excludeWithLayerMask")
+        private _excludeWithLayerMask = 0;
+        public get excludeWithLayerMask(): number {
+            return this._excludeWithLayerMask;
+        }
+
+        public set excludeWithLayerMask(value: number) {
+            this._excludeWithLayerMask = value;
+            this._resyncMeshes();
+        }        
+
+        @serialize("includeOnlyWithLayerMask")
+        private _includeOnlyWithLayerMask = 0;
+        public get includeOnlyWithLayerMask(): number {
+            return this._includeOnlyWithLayerMask;
+        }
+
+        public set includeOnlyWithLayerMask(value: number) {
+            this._includeOnlyWithLayerMask = value;
+            this._resyncMeshes();
+        }          
+
+        @serialize("lightmapMode")
+        private _lightmapMode = 0;
+        public get lightmapMode(): number {
+            return this._lightmapMode;
+        }
+
+        public set lightmapMode(value: number) {
+            if (this._lightmapMode === value) {
+                return;
+            }
+            
+            this._lightmapMode = value;
+            this._markMeshesAsLightDirty();
+        }    
 
         // PBR Properties.
         @serialize()
@@ -98,6 +142,11 @@
         constructor(name: string, scene: Scene) {
             super(name, scene);
             this.getScene().addLight(this);
+
+            this.includedOnlyMeshes = new Array<AbstractMesh>();
+            this.excludedMeshes = new Array<AbstractMesh>();
+
+            this._resyncMeshes();
         }
         /**
          * Returns the string "Light".  
@@ -121,6 +170,19 @@
             }
             return ret;
         } 
+
+
+        /**
+         * Set the enabled state of this node.
+         * @param {boolean} value - the new enabled state
+         * @see isEnabled
+         */
+        public setEnabled(value: boolean): void {
+            super.setEnabled(value);
+
+            this._resyncMeshes();
+        }
+
         /**
          * Returns the Light associated shadow generator.  
          */
@@ -203,6 +265,12 @@
 
             // Animations
             this.getScene().stopAnimation(this);
+
+            // Remove from meshes
+            for (var mesh of this.getScene().meshes) {
+                mesh._removeLightSource(this);
+            }
+
             // Remove from scene
             this.getScene().removeLight(this);
             super.dispose();
@@ -311,5 +379,43 @@
 
             return light;
         }
+
+        private _hookArray(array: AbstractMesh[]): void {
+            var oldPush = array.push;
+            array.push = (...items: AbstractMesh[]) => {
+                var result = oldPush.apply(array, items);
+
+                for (var item of items) {
+                    item._resyncLighSource(this);
+                }
+
+                return result;
+            }
+
+            var oldSplice = array.splice;
+            array.splice = (index: number, deleteCount?: number) => {
+                var deleted = oldSplice.apply(array, [index, deleteCount]);
+
+                for (var item of deleted) {
+                    item._resyncLighSource(this);
+                }
+
+                return deleted;
+            }
+        }
+
+        private _resyncMeshes() {
+            for (var mesh of this.getScene().meshes) {
+                mesh._resyncLighSource(this);
+            }
+        }
+
+        public _markMeshesAsLightDirty() {
+            for (var mesh of this.getScene().meshes) {
+                if (mesh._lightSources.indexOf(this) !== -1) {
+                    mesh._markSubMeshesAsLightDirty();
+                }
+            }
+        }
     }
 }

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

@@ -191,6 +191,7 @@
                         }
                     }
                 }
+
                 return true;
 
             } catch (err) {
@@ -501,6 +502,36 @@
                         ShadowGenerator.Parse(parsedShadowGenerator, scene);
                     }
                 }
+                
+                // Lights exclusions / inclusions
+                for (index = 0, cache = scene.lights.length; index < cache; index++) {
+                    var light = scene.lights[index];
+                    // 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 = [];
+                    }
+                }
     
                 // Actions (scene)
                 if (parsedData.actions) {

+ 24 - 4
src/Materials/Textures/babylon.baseTexture.ts

@@ -3,8 +3,18 @@
         @serialize()
         public name: string;
 
-        @serialize()
-        public hasAlpha = false;
+        @serialize("hasAlpha")
+        private _hasAlpha = false;
+        public set hasAlpha(value : boolean) {
+            if (this._hasAlpha === value) {
+                return;
+            }
+            this._hasAlpha = value;
+            this._scene.markAllMaterialsAsDirty(Material.TextureDirtyFlag);
+        }
+        public get hasAlpha(): boolean {
+            return this._hasAlpha;
+        }    
 
         @serialize()
         public getAlphaFromRGB = false;
@@ -15,8 +25,18 @@
         @serialize()
         public coordinatesIndex = 0;
 
-        @serialize()
-        public coordinatesMode = Texture.EXPLICIT_MODE;
+        @serialize("coordinatesMode")
+        private _coordinatesMode = Texture.EXPLICIT_MODE;
+        public set coordinatesMode(value : number) {
+            if (this._coordinatesMode === value) {
+                return;
+            }
+            this._coordinatesMode = value;
+            this._scene.markAllMaterialsAsDirty(Material.TextureDirtyFlag);
+        }
+        public get coordinatesMode(): number {
+            return this._coordinatesMode;
+        }            
 
         @serialize()
         public wrapU = Texture.WRAP_ADDRESSMODE;

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

@@ -74,7 +74,7 @@
         private _delayedOnError: () => void;
         private _onLoadObservarble: Observable<boolean>;
 
-        constructor(url: string, scene: Scene, noMipmap: boolean = false, invertY: boolean = true, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null, deleteBuffer: boolean = false, format: number = Engine.TEXTUREFORMAT_RGBA) {
+        constructor(url: string, scene: Scene, noMipmap: boolean = false, invertY: boolean = true, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null, deleteBuffer: boolean = false, format?: number) {
             super(scene);
 
             this.name = url;

+ 6 - 5
src/Materials/Textures/babylon.videoTexture.ts

@@ -44,7 +44,7 @@
             }
 
             if (urls) {
-                this.video.addEventListener("canplaythrough", () => {
+                this.video.addEventListener("canplay", () => {
                     this._createTexture();
                 });
                 urls.forEach(url => {
@@ -61,15 +61,17 @@
 
         private _createTexture(): void {
             this._texture = this.getScene().getEngine().createDynamicTexture(this.video.videoWidth, this.video.videoHeight, this._generateMipMaps, this._samplingMode);
-            this._texture.isReady = true;
-        }
 
-        public update(): boolean {
             if (this._autoLaunch) {
                 this._autoLaunch = false;
                 this.video.play();
             }
+            this.video.addEventListener("playing", () => {
+                this._texture.isReady = true;
+            });
+        }
 
+        public update(): boolean {
             var now = Tools.Now;
 
             if (now - this._lastUpdate < 15 || this.video.readyState !== this.video.HAVE_ENOUGH_DATA) {
@@ -99,7 +101,6 @@
 		    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
 		    window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
 
-
 		    if (navigator.getUserMedia) {
 			    navigator.getUserMedia({                     
                     video: {

+ 13 - 1
src/Materials/babylon.fresnelParameters.ts

@@ -1,6 +1,18 @@
 module BABYLON {
     export class FresnelParameters {
-        public isEnabled = true;
+        private _isEnabled = true;
+        public get isEnabled(): boolean {
+            return this._isEnabled;
+        }
+        public set isEnabled(value: boolean) {
+            if (this._isEnabled === value) {
+                return;
+            }
+
+            this._isEnabled = value;
+            Engine.MarkAllMaterialsAsDirty(Material.FresnelDirtyFlag);
+        }   
+
         public leftColor = Color3.White();
         public rightColor = Color3.Black();
         public bias = 0;

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

@@ -1,12 +1,62 @@
 module BABYLON {
     export class MaterialDefines {
         _keys: string[];
+        _isDirty = true;
+        _trackIsDirty = false;    
+
+        public _renderId: number;
+        public _areLightsDirty = true;
+        public _areAttributesDirty = true;
+        public _needNormals = false;
+        public _needUVs = false;
+
+        constructor(trackIsDirty?: boolean) {
+            this._trackIsDirty = trackIsDirty;
+        }
+
+        private _reBind(key: string): void {
+            this["_" + key] = this[key]; 
+
+            Object.defineProperty(this, key, {
+                get: function () {
+                    return this["_" + key];
+                },
+                set: function (value) {
+                    if (this["_" + key] === value) {
+                        return;
+                    }
+                    this["_" + key] = value;
+                    this._isDirty = true;
+                },
+                enumerable: true,
+                configurable: true
+            });
+        }
 
         public rebuild() {
             if (this._keys) {
                 delete this._keys;
             }
-            this._keys = Object.keys(this);
+
+            this._keys = [];
+
+            for (var key of Object.keys(this)) {
+                if (key[0] === "_") {
+                    continue;
+                }
+
+                this._keys.push(key);
+
+                if (!this._trackIsDirty) {
+                    continue;
+                }
+            
+                if (Object.getOwnPropertyDescriptor(this, key).get) {
+                    continue;
+                }
+
+                this._reBind(key);
+            }
         } 
 
         public isEqual(other: MaterialDefines): boolean {
@@ -54,11 +104,12 @@
             var result = "";
             for (var index = 0; index < this._keys.length; index++) {
                 var prop = this._keys[index];
+                var value = this[prop];
 
-                if (typeof (this[prop]) === "number") {
+                if (typeof (value) === "number") {
                     result += "#define " + prop + " " + this[prop] + "\n";
 
-                } else if (this[prop]) {
+                } else if (value) {
                     result += "#define " + prop + "\n";
                 }
             }
@@ -95,6 +146,32 @@
             return Material._CounterClockWiseSideOrientation;
         }
 
+        private static _TextureDirtyFlag = 0;
+        private static _LightDirtyFlag = 1;
+        private static _FresnelDirtyFlag = 2;
+        private static _AttributesDirtyFlag = 4;
+        private static _MiscDirtyFlag = 8;
+
+        public static get TextureDirtyFlag(): number {
+            return Material._TextureDirtyFlag;
+        }
+
+        public static get LightDirtyFlag(): number {
+            return Material._LightDirtyFlag;
+        }
+
+        public static get FresnelDirtyFlag(): number {
+            return Material._FresnelDirtyFlag;
+        }
+
+        public static get AttributesDirtyFlag(): number {
+            return Material._AttributesDirtyFlag;
+        }
+
+        public static get MiscDirtyFlag(): number {
+            return Material._MiscDirtyFlag;
+        }
+
         @serialize()
         public id: string;
 
@@ -113,8 +190,18 @@
         @serialize()
         public alpha = 1.0;
 
-        @serialize()
-        public backFaceCulling = true;
+        @serialize("backFaceCulling")
+        protected _backFaceCulling = true;
+        public set backFaceCulling(value : boolean) {
+            if (this._backFaceCulling === value) {
+                return;
+            }
+            this._backFaceCulling = value;
+            this.markAsDirty(Material.TextureDirtyFlag);
+        }
+        public get backFaceCulling(): boolean {
+            return this._backFaceCulling;
+        }          
 
         @serialize()
         public sideOrientation: number;
@@ -125,6 +212,8 @@
 
         public doNotSerialize = false;
 
+        public storeEffectOnSubMeshes = false;
+
         /**
         * An event triggered when the material is disposed.
         * @type {BABYLON.Observable}
@@ -166,8 +255,18 @@
         @serialize()
         public disableDepthWrite = false;
 
-        @serialize()
-        public fogEnabled = true;
+        @serialize("fogEnabled")
+        private _fogEnabled = true;
+        public set fogEnabled(value : boolean) {
+            if (this._fogEnabled === value) {
+                return;
+            }
+            this._fogEnabled = value;
+            this.markAsDirty(Material.MiscDirtyFlag);
+        }
+        public get fogEnabled(): boolean {
+            return this._fogEnabled;
+        }         
 
         @serialize()
         public pointSize = 1.0;
@@ -190,7 +289,7 @@
         }
 
         public set pointsCloud(value: boolean) {
-            this._fillMode = (value ? Material.PointFillMode : Material.TriangleFillMode);
+            this._fillMode = (value ? Material.PointFillMode : Material.TriangleFillMode);            
         }
 
         @serialize()
@@ -199,7 +298,12 @@
         }
 
         public set fillMode(value: number) {
+            if (this._fillMode === value) {
+                return;
+            }
+
             this._fillMode = value;
+            this.markAsDirty(Material.MiscDirtyFlag);
         }
 
         public _effect: Effect;
@@ -236,6 +340,13 @@
             }
             return ret;
         } 
+
+        /**
+         * Child classes can use it to update shaders         
+         */
+        public markAsDirty(flag: number): void {
+
+        }
         
         public getClassName(): string {
             return "Material";
@@ -257,6 +368,10 @@
             return true;
         }
 
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+            return false;            
+        }
+
         public getEffect(): Effect {
             return this._effect;
         }
@@ -281,12 +396,12 @@
             this._wasPreviouslyReady = false;
         }
 
-        public _preBind(): void {
+        public _preBind(effect?: Effect): void {
             var engine = this._scene.getEngine();
 
             var reverse = this.sideOrientation === Material.ClockWiseSideOrientation;
 
-            engine.enableEffect(this._effect);
+            engine.enableEffect(effect ? effect : this._effect);
             engine.setState(this.backFaceCulling, this.zOffset, false, reverse);
         }
 
@@ -302,6 +417,9 @@
             }
         }
 
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        }
+
         public bindOnlyWorldMatrix(world: Matrix): void {
         }
 

+ 111 - 105
src/Materials/babylon.materialHelper.ts

@@ -1,146 +1,152 @@
 module BABYLON {
     export class MaterialHelper {
-        public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, maxSimultaneousLights = 4): boolean {
+        public static PrepareDefinesForAttributes(mesh: AbstractMesh, defines: MaterialDefines, useInstances: boolean): void {
+            if (!defines._areAttributesDirty) {
+                return;
+            }
+
+            defines["NORMAL"] = (defines._needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
+
+            if (defines._needUVs) {
+                defines["UV1"] = mesh.isVerticesDataPresent(VertexBuffer.UVKind);
+                defines["UV2"] = mesh.isVerticesDataPresent(VertexBuffer.UV2Kind);
+            } else {
+                defines["UV1"] = false;
+                defines["UV2"] = false;
+            }
+
+            defines["VERTEXCOLOR"] = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
+
+            defines["VERTEXALPHA"] = mesh.hasVertexAlpha;
+
+            if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
+                defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
+            } else {
+                defines["NUM_BONE_INFLUENCERS"] = 0;
+                defines["BonesPerMesh"] = 0;
+            }           
+        }
+
+        public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, maxSimultaneousLights = 4, disableLighting = false): boolean {
+            if (!defines._areLightsDirty) {
+                return defines._needNormals;
+            }
+
             var lightIndex = 0;
             var needNormals = false;
             var needRebuild = false;
             var needShadows = false;
             var lightmapMode = false;
 
-            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 (scene.lightsEnabled && !disableLighting) {
+                for (var light of mesh._lightSources) {
+                    needNormals = true;
 
-                        if (excludedMesh) {
-                            light.excludedMeshes.push(excludedMesh);
-                        }
+                    if (defines["LIGHT" + lightIndex] === undefined) {
+                        needRebuild = true;
+                    }
+                    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;
                     }
 
-                    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);
-                        }
+                    if (!needRebuild && defines[type] === undefined) {
+                        needRebuild = true;
                     }
 
-                    light._includedOnlyMeshesIds = [];
-                }
+                    defines[type] = true;
 
-                if (!light.canAffectMesh(mesh)) {
-                    continue;
-                }
-                needNormals = true;
+                    // Specular
+                    defines["SPECULARTERM"] = (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined);
 
-                if (defines["LIGHT" + lightIndex] === undefined) {
-                    needRebuild = true;
-                }
+                    // Shadows
+                    var shadowEnabled = false;
+                    if (scene.shadowsEnabled) {
+                        var shadowGenerator = <ShadowGenerator>light.getShadowGenerator();
+                        if (mesh && mesh.receiveShadows && shadowGenerator) {
+                            if (!needRebuild && defines["SHADOW" + lightIndex] === undefined) {
+                                needRebuild = true;
+                            }
+                            defines["SHADOW" + lightIndex] = true;
 
-                defines["LIGHT" + lightIndex] = true;
+                            shadowEnabled = 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;
-                }
+                            if (shadowGenerator.usePoissonSampling) {
+                                if (!needRebuild && defines["SHADOWPCF" + lightIndex] === undefined) {
+                                    needRebuild = true;
+                                }
 
-                if (defines[type] === undefined) {
-                    needRebuild = true;
-                }
+                                defines["SHADOWPCF" + lightIndex] = true;
+                            } 
+                            else if (shadowGenerator.useExponentialShadowMap || shadowGenerator.useBlurExponentialShadowMap) {
+                                if (!needRebuild && defines["SHADOWESM" + lightIndex] === undefined) {
+                                    needRebuild = true;
+                                }
 
-                defines[type] = true;
-
-                // Specular
-                if (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined) {
-                    defines["SPECULARTERM"] = true;
-                }
+                                defines["SHADOWESM" + lightIndex] = true;
+                            }
 
-                // Shadows
-                if (scene.shadowsEnabled) {
-                    var shadowGenerator = <ShadowGenerator>light.getShadowGenerator();
-                    if (mesh && mesh.receiveShadows && shadowGenerator) {
-                        if (defines["SHADOW" + lightIndex] === undefined) {
-                            needRebuild = true;
+                            needShadows = true;
+                        } else {
+                            defines["SHADOW" + lightIndex] = false;
                         }
-                        defines["SHADOW" + lightIndex] = true;
-
-                        defines["SHADOWS"] = true;
-
-                        if (shadowGenerator.usePoissonSampling) {
-                            if (defines["SHADOWPCF" + lightIndex] === undefined) {
-                                needRebuild = true;
-                            }
+                    }
 
-                            defines["SHADOWPCF" + lightIndex] = true;
-                        } 
-                        else if (shadowGenerator.useExponentialShadowMap || shadowGenerator.useBlurExponentialShadowMap) {
-                            if (defines["SHADOWESM" + lightIndex] === undefined) {
-                                needRebuild = true;
-                            }
+                    defines["SHADOWS"] = shadowEnabled;
 
-                            defines["SHADOWESM" + lightIndex] = true;
+                    if (light.lightmapMode != Light.LIGHTMAP_DEFAULT ) {
+                        lightmapMode = true;
+                        if (!needRebuild && defines["LIGHTMAPEXCLUDED" + lightIndex] === undefined) {
+                            needRebuild = true;
                         }
-
-                        needShadows = true;
+                        if (!needRebuild && defines["LIGHTMAPNOSPECULAR" + lightIndex] === undefined) {
+                            needRebuild = true;
+                        }
+                        defines["LIGHTMAPEXCLUDED" + lightIndex] = true;
+                        defines["LIGHTMAPNOSPECULAR" + lightIndex] = (light.lightmapMode == Light.LIGHTMAP_SHADOWSONLY);
+                    } else {
+                        defines["LIGHTMAPEXCLUDED" + lightIndex] = false;
+                        defines["LIGHTMAPNOSPECULAR" + lightIndex] = false;
                     }
-                }
 
-                if (light.lightmapMode != Light.LIGHTMAP_DEFAULT ) {
-                    lightmapMode = true;
-                    if (defines["LIGHTMAPEXCLUDED" + lightIndex] === undefined) {
-                        needRebuild = true;
-                    }
-                    if (defines["LIGHTMAPNOSPECULAR" + lightIndex] === undefined) {
-                        needRebuild = true;
-                    }
-                    defines["LIGHTMAPEXCLUDED" + lightIndex] = true;
-                    if (light.lightmapMode == Light.LIGHTMAP_SHADOWSONLY) {
-                        defines["LIGHTMAPNOSPECULAR" + lightIndex] = true;
-                    }
+                    lightIndex++;
+                    if (lightIndex === maxSimultaneousLights)
+                        break;
                 }
-
-                lightIndex++;
-                if (lightIndex === maxSimultaneousLights)
-                    break;
             }
 
-            let caps = scene.getEngine().getCaps();
-            if (needShadows && caps.textureFloat && caps.textureFloatLinearFiltering && caps.textureFloatRender) {
-                if (defines["SHADOWFULLFLOAT"] === undefined) {
-                    needRebuild = true;
+            // Resetting all other lights if any
+            for (var index = lightIndex; index < maxSimultaneousLights; index++) {
+                if (defines["LIGHT" + index] !== undefined) {
+                    defines["LIGHT" + index] = false;
                 }
-
-                defines["SHADOWFULLFLOAT"] = true;
             }
 
-            if (defines["LIGHTMAPEXCLUDED"] === undefined) {
+            let caps = scene.getEngine().getCaps();
+            if (!needRebuild && defines["SHADOWFULLFLOAT"] === undefined) {
                 needRebuild = true;
             }
-            if (lightmapMode) {
-                defines["LIGHTMAPEXCLUDED"] = true;
+
+            defines["SHADOWFULLFLOAT"] = (needShadows && caps.textureFloat && caps.textureFloatLinearFiltering && caps.textureFloatRender);
+
+            if (!needRebuild && defines["LIGHTMAPEXCLUDED"] === undefined) {
+                needRebuild = true;
             }
 
+            defines["LIGHTMAPEXCLUDED"] = lightmapMode;
+
             if (needRebuild) {
                 defines.rebuild();
-            }
+            }        
 
             return needNormals;
         }

+ 0 - 12
src/Materials/babylon.pbrMaterial.ts

@@ -576,10 +576,6 @@
                 return false;
             }
 
-            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
-                return true;
-            }
-
             return false;
         }
 
@@ -1127,14 +1123,6 @@
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
-            if (mesh) {
-                if (!mesh._materialDefines) {
-                    mesh._materialDefines = new PBRMaterialDefines();
-                }
-
-                this._defines.cloneTo(mesh._materialDefines);
-            }
-
             return true;
         }
 

文件差異過大導致無法顯示
+ 1010 - 499
src/Materials/babylon.standardMaterial.ts


+ 182 - 9
src/Mesh/babylon.abstractMesh.ts

@@ -128,20 +128,110 @@
         public showSubMeshesBoundingBox = false;
         public isBlocker = false;
         public renderingGroupId = 0;
-        public material: Material;
-        public receiveShadows = false;
+        private _material: Material
+        public get material(): Material {
+            return this._material;
+        }
+        public set material(value: Material) {
+            if (this._material === value) {
+                return;
+            }
+
+            this._material = value;
+            if (!this.subMeshes) {
+                return;
+            }
+            
+            for (var subMesh of this.subMeshes) {
+                subMesh.setEffect(null);
+            }
+        }
+
+        private _receiveShadows = false;
+        public get receiveShadows(): boolean {
+            return this._receiveShadows;
+        }
+        public set receiveShadows(value: boolean) {
+            if (this._receiveShadows === value) {
+                return;
+            }
+
+            this._receiveShadows = value;
+            this._markSubMeshesAsLightDirty();
+        }
+
         public renderOutline = false;
         public outlineColor = Color3.Red();
         public outlineWidth = 0.02;
         public renderOverlay = false;
         public overlayColor = Color3.Red();
         public overlayAlpha = 0.5;
-        public hasVertexAlpha = false;
-        public useVertexColors = true;
-        public applyFog = true;
-        public computeBonesUsingShaders = true;
+        private _hasVertexAlpha = false;
+        public get hasVertexAlpha(): boolean {
+            return this._hasVertexAlpha;
+        }
+        public set hasVertexAlpha(value: boolean) {
+            if (this._hasVertexAlpha === value) {
+                return;
+            }
+
+            this._hasVertexAlpha = value;
+            this._markSubMeshesAsAttributesDirty();
+        }        
+
+        private _useVertexColors = true;
+        public get useVertexColors(): boolean {
+            return this._useVertexColors;
+        }
+        public set useVertexColors(value: boolean) {
+            if (this._useVertexColors === value) {
+                return;
+            }
+
+            this._useVertexColors = value;
+            this._markSubMeshesAsAttributesDirty();
+        }         
+
+        private _computeBonesUsingShaders = true;
+        public get computeBonesUsingShaders(): boolean {
+            return this._computeBonesUsingShaders;
+        }
+        public set computeBonesUsingShaders(value: boolean) {
+            if (this._computeBonesUsingShaders === value) {
+                return;
+            }
+
+            this._computeBonesUsingShaders = value;
+            this._markSubMeshesAsAttributesDirty();
+        }                
+
+        private _numBoneInfluencers = 4;
+        public get numBoneInfluencers(): number {
+            return this._numBoneInfluencers;
+        }
+        public set numBoneInfluencers(value: number) {
+            if (this._numBoneInfluencers === value) {
+                return;
+            }
+
+            this._numBoneInfluencers = value;
+            this._markSubMeshesAsAttributesDirty();
+        }           
+
+        private _applyFog = true;
+        public get applyFog(): boolean {
+            return this._applyFog;
+        }
+        public set applyFog(value: boolean) {
+            if (this._applyFog === value) {
+                return;
+            }
+
+            this._applyFog = value;
+            this._markSubMeshesAsMiscDirty();
+        }  
+
         public scalingDeterminant = 1;
-        public numBoneInfluencers = 4;
 
         public useOctreeForRenderingSelection = true;
         public useOctreeForPicking = true;
@@ -207,7 +297,6 @@
         public _positions: Vector3[];
         private _isDirty = false;
         public _masterMesh: AbstractMesh;
-        public _materialDefines: MaterialDefines;
 
         public _boundingInfo: BoundingInfo;
         private _pivotMatrix = Matrix.Identity();
@@ -224,6 +313,8 @@
 
         public _poseMatrix: Matrix;
 
+        public _lightSources = new Array<Light>();
+
         // Loading properties
         public _waitingActions: any;
         public _waitingFreezeWorldMatrix: boolean;
@@ -246,6 +337,8 @@
             if (!this._skeleton) {
                 this._bonesTransformMatrices = null;
             }
+
+            this._markSubMeshesAsAttributesDirty();
         }
 
         public get skeleton(): Skeleton {
@@ -257,6 +350,8 @@
             super(name, scene);
 
             this.getScene().addMesh(this);
+
+            this._resyncLightSources();
         }
 
         /**
@@ -282,6 +377,84 @@
             return ret;
         }
 
+        public _resyncLightSources(): void {
+            this._lightSources.length = 0;
+
+            for (var light of this.getScene().lights) {
+                if (!light.isEnabled()) {
+                    continue;
+                }
+
+                if (light.canAffectMesh(this)) {
+                    this._lightSources.push(light);
+                }
+            }
+
+            this._markSubMeshesAsLightDirty();
+        }
+
+        public _resyncLighSource(light: Light): void {
+            var isIn = light.isEnabled() && light.canAffectMesh(this);
+
+            var index = this._lightSources.indexOf(light);
+
+            if (index === -1) {
+                if (!isIn) {
+                    return;
+                }
+                this._lightSources.push(light);
+            } else {
+                if (isIn) {
+                    return;
+                }
+                this._lightSources.splice(index, 1);            
+            }
+
+            this._markSubMeshesAsLightDirty();
+        }
+
+        public _removeLightSource(light: Light): void {
+            var index = this._lightSources.indexOf(light);
+
+            if (index === -1) {
+                return;
+            }
+            this._lightSources.slice(index, 1);       
+        }
+
+        private _markSubMeshesAsDirty(func: (defines: MaterialDefines) => void) {
+            if (!this.subMeshes) {
+                return;
+            }
+            
+            for (var subMesh of this.subMeshes) {
+                if (subMesh._materialDefines) {
+                    func(subMesh._materialDefines);
+                }
+            }
+        }
+
+        public _markSubMeshesAsLightDirty() {
+            this._markSubMeshesAsDirty(defines => defines._areLightsDirty = true);
+        }
+
+        public _markSubMeshesAsAttributesDirty() {
+            this._markSubMeshesAsDirty(defines => defines._areAttributesDirty = true);
+        }
+
+        public _markSubMeshesAsMiscDirty() {
+            if (!this.subMeshes) {
+                return;
+            }
+            
+            for (var subMesh of this.subMeshes) {
+                var material = subMesh.getMaterial();
+                if (material) {
+                    material.markAsDirty(Material.MiscDirtyFlag);
+                }
+            }
+        }
+
         /**
          * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z. 
          * If rotation quaternion is set, this Vector3 will (almost always) be the Zero vector!
@@ -814,7 +987,7 @@
                 return this._worldMatrix;
             }
 
-            if (!force && ((this._currentRenderId === this.getScene().getRenderId() && this.isSynchronized(true)))) {
+            if (!force && this.isSynchronized(true)) {
                 this._currentRenderId = this.getScene().getRenderId();
                 return this._worldMatrix;
             }

+ 4 - 0
src/Mesh/babylon.geometry.ts

@@ -433,6 +433,10 @@
             if (this.onGeometryUpdated) {
                 this.onGeometryUpdated(this, kind);
             }
+
+            for (var mesh of this._meshes) {
+                mesh._markSubMeshesAsAttributesDirty();
+            }
         }
 
         public load(scene: Scene, onLoaded?: () => void): void {

+ 23 - 5
src/Mesh/babylon.mesh.ts

@@ -1096,7 +1096,15 @@
             // Material
             var effectiveMaterial = subMesh.getMaterial();
 
-            if (!effectiveMaterial || !effectiveMaterial.isReady(this, hardwareInstancedRendering)) {
+            if (!effectiveMaterial) {
+                return this;
+            }
+
+            if (effectiveMaterial.storeEffectOnSubMeshes) {
+                if (!effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
+                    return this;
+                }
+            } else if (!effectiveMaterial.isReady(this, hardwareInstancedRendering)) {
                 return this;
             }
 
@@ -1108,16 +1116,26 @@
                 engine.setDepthWrite(savedDepthWrite);
             }
 
-            effectiveMaterial._preBind();
-            var effect = effectiveMaterial.getEffect();
+            var effect: Effect;
+            if (effectiveMaterial.storeEffectOnSubMeshes) {
+                effect = subMesh.effect;
+            } else {
+                effect = effectiveMaterial.getEffect();
+            }
+
+            effectiveMaterial._preBind(effect);
 
             // Bind
             var fillMode = scene.forcePointsCloud ? Material.PointFillMode : (scene.forceWireframe ? Material.WireFrameFillMode : effectiveMaterial.fillMode);
             this._bind(subMesh, effect, fillMode);
 
             var world = this.getWorldMatrix();
-
-            effectiveMaterial.bind(world, this);
+            
+            if (effectiveMaterial.storeEffectOnSubMeshes) {
+                effectiveMaterial.bindForSubMesh(world, this, subMesh);
+            } else {
+                effectiveMaterial.bind(world, this);
+            }
 
             // Alpha mode
             if (enableAlphaMode) {

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

@@ -15,6 +15,21 @@
         public _distanceToCamera: number;
         public _id: number;
 
+        public _materialDefines: MaterialDefines;
+        private _materialEffect: Effect;
+
+        public get effect(): Effect {
+            return this._materialEffect;
+        }
+
+        public setEffect(effect: Effect, defines?: MaterialDefines) {
+            if (this._materialEffect === effect) {
+                return;
+            }
+            this._materialDefines = defines;
+            this._materialEffect = effect;
+        }
+
         constructor(public materialIndex: number, public verticesStart: number, public verticesCount: number, public indexStart, public indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox: boolean = true) {
             this._mesh = mesh;
             this._renderingMesh = renderingMesh || <Mesh>mesh;

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

@@ -275,7 +275,11 @@
                 if (this.isReady(subMesh, hardwareInstancedRendering)) {
                     var effect: Effect = this._volumetricLightScatteringPass;
                     if (mesh === this.mesh) {
-                        effect = subMesh.getMaterial().getEffect();
+                        if (subMesh.effect) {
+                            effect = subMesh.effect;
+                        } else {
+                            effect = subMesh.getMaterial().getEffect();
+                        }
                     }
 
                     engine.enableEffect(effect);

+ 3 - 0
src/Rendering/babylon.renderingGroup.ts

@@ -103,6 +103,8 @@
                 engine.setAlphaTesting(false);
             }
 
+            var stencilState = engine.getStencilBuffer();
+            engine.setStencilBuffer(false);
             // Sprites
             if (renderSprites) {
                 this._renderSprites();
@@ -122,6 +124,7 @@
                 this._renderTransparent(this._transparentSubMeshes);
                 engine.setAlphaMode(Engine.ALPHA_DISABLE);
             }
+            engine.setStencilBuffer(stencilState);
         }
 
         /**

+ 3 - 4
src/Shaders/default.fragment.fx

@@ -372,14 +372,13 @@ void main(void) {
 
 #ifdef SPECULARTERM
 	vec3 finalSpecular = specularBase * specularColor;
+	#ifdef SPECULAROVERALPHA
+		alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
+	#endif
 #else
 	vec3 finalSpecular = vec3(0.0);
 #endif
 
-#ifdef SPECULAROVERALPHA
-	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

+ 3 - 4
src/Shaders/pbr.fragment.fx

@@ -618,14 +618,13 @@ void main(void) {
 
 #ifdef SPECULARTERM
 	vec3 finalSpecular = lightSpecularContribution * surfaceReflectivityColor;
+	#ifdef SPECULAROVERALPHA
+		alpha = clamp(alpha + getLuminance(finalSpecular), 0., 1.);
+	#endif
 #else
 	vec3 finalSpecular = vec3(0.0);
 #endif
 
-#ifdef SPECULAROVERALPHA
-	alpha = clamp(alpha + getLuminance(finalSpecular), 0., 1.);
-#endif
-
 #ifdef RADIANCEOVERALPHA
 	alpha = clamp(alpha + getLuminance(environmentRadiance), 0., 1.);
 #endif

+ 5 - 1
src/Tools/babylon.smartArray.ts

@@ -80,7 +80,7 @@
             }
         }
 
-        public indexOf(value): number {
+        public indexOf(value: T): number {
             var position = this.data.indexOf(value);
 
             if (position >= this.length) {
@@ -90,6 +90,10 @@
             return position;
         }
 
+        public contains(value: T): boolean {
+            return this.data.indexOf(value) !== -1;
+        }
+
         // Statics
         private static _GlobalId = 0;
     }

+ 78 - 46
src/babylon.engine.ts

@@ -170,7 +170,6 @@
         public etc1: any; //WEBGL_compressed_texture_etc1;
         public etc2: any; //WEBGL_compressed_texture_etc;
         public astc: any; //WEBGL_compressed_texture_astc;
-        public atc: any; //WEBGL_compressed_texture_atc;
         public textureFloat: boolean;
         public vertexArrayObject: boolean;
         public textureAnisotropicFilterExtension: EXT_texture_filter_anisotropic;
@@ -223,6 +222,19 @@
             return lastCreatedEngine.scenes[lastCreatedEngine.scenes.length - 1];
         }
 
+        /**
+         * Will flag all materials in all scenes in all engines as dirty to trigger new shader compilation
+         */
+        public static MarkAllMaterialsAsDirty(flag:number, predicate?: (mat: Material) => boolean): void {
+            for (var engineIndex = 0; engineIndex < Engine.Instances.length; engineIndex++) {
+                var engine = Engine.Instances[engineIndex];
+
+                for (var sceneIndex = 0; sceneIndex < engine.scenes.length; sceneIndex++) {
+                    engine.scenes[sceneIndex].markAllMaterialsAsDirty(flag, predicate);
+                }
+            }
+        }
+
         // Const statics
         private static _ALPHA_DISABLE = 0;
         private static _ALPHA_ADD = 1;
@@ -641,10 +653,9 @@
             this._caps.astc = this._gl.getExtension('WEBGL_compressed_texture_astc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_astc');
             this._caps.s3tc = this._gl.getExtension('WEBGL_compressed_texture_s3tc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');
             this._caps.pvrtc = this._gl.getExtension('WEBGL_compressed_texture_pvrtc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
-            this._caps.etc1 = this._gl.getExtension('WEBGL_compressed_texture_etc1') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc1');
-            this._caps.etc2 = this._gl.getExtension('WEBGL_compressed_texture_etc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc') ||
-                this._gl.getExtension('WEBGL_compressed_texture_es3_0'); // also a requirement of OpenGL ES 3
-            this._caps.atc = this._gl.getExtension('WEBGL_compressed_texture_atc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_atc');
+            this._caps.etc1  = this._gl.getExtension('WEBGL_compressed_texture_etc1' ) || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc1' );
+            this._caps.etc2  = this._gl.getExtension('WEBGL_compressed_texture_etc'  ) || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc'  ) ||
+                               this._gl.getExtension('WEBGL_compressed_texture_es3_0'); // also a requirement of OpenGL ES 3
 
             this._caps.textureAnisotropicFilterExtension = this._gl.getExtension('EXT_texture_filter_anisotropic') || this._gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic') || this._gl.getExtension('MOZ_EXT_texture_filter_anisotropic');
             this._caps.maxAnisotropy = this._caps.textureAnisotropicFilterExtension ? this._gl.getParameter(this._caps.textureAnisotropicFilterExtension.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 0;
@@ -702,13 +713,11 @@
             // Next PVRTC & DXT, which are probably superior to ETC1/2.  
             // Likely no hardware which supports both PVR & DXT, so order matters little.
             // ETC2 is newer and handles ETC1 (no alpha capability), so check for first.
-            // ATC before ETC1, since both old (widely supported), but ATC supports alpha, but ETC1 does not
-            if (this._caps.astc) this.texturesSupported.push('-astc.ktx');
-            if (this._caps.s3tc) this.texturesSupported.push('-dxt.ktx');
+            if (this._caps.astc ) this.texturesSupported.push('-astc.ktx');
+            if (this._caps.s3tc ) this.texturesSupported.push('-dxt.ktx');
             if (this._caps.pvrtc) this.texturesSupported.push('-pvrtc.ktx');
-            if (this._caps.etc2) this.texturesSupported.push('-etc2.ktx');
-            if (this._caps.atc) this.texturesSupported.push('-atc.ktx');
-            if (this._caps.etc1) this.texturesSupported.push('-etc1.ktx');
+            if (this._caps.etc2 ) this.texturesSupported.push('-etc2.ktx');
+            if (this._caps.etc1 ) this.texturesSupported.push('-etc1.ktx');
 
             if (this._gl.getShaderPrecisionFormat) {
                 var highp = this._gl.getShaderPrecisionFormat(this._gl.FRAGMENT_SHADER, this._gl.HIGH_FLOAT);
@@ -2109,7 +2118,7 @@
          * @param {Array<string>} formatsAvailable- The list of those format families you have created
          * on your server.  Syntax: '-' + format family + '.ktx'.  (Case and order do not matter.)
          * 
-         * Current families are astc, dxt, pvrtc, etc2, atc, & etc1.
+         * Current families are astc, dxt, pvrtc, etc2, & etc1.
          * @returns The extension selected.
          */
         public setTextureFormatToUse(formatsAvailable: Array<string>): string {
@@ -2125,35 +2134,48 @@
             return this._textureFormatInUse = null;
         }
 
-        public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null, fallBack?: WebGLTexture, format?: number): WebGLTexture {
+        /**
+         * Usually called from BABYLON.Texture.ts.  Passed information to create a WebGLTexture.
+         * @param {string} urlArg- This contains one of the following:
+         *                         1. A conventional http URL, e.g. 'http://...' or 'file://...'
+         *                         2. A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
+         *                         3. An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
+         *
+         * @param {boolean} noMipmap- When true, no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file.
+         * @param {boolean} invertY- When true, image is flipped when loaded.  You probably want true. Ignored for compressed textures.  Must be flipped in the file.
+         * @param {Scene} scene- Needed for loading to the correct scene.
+         * @param {number} samplingMode- Mode with should be used sample / access the texture.  Default: TRILINEAR
+         * @param {callback} onLoad- Optional callback to be called upon successful completion.
+         * @param {callback} onError- Optional callback to be called upon failure.
+         * @param {ArrayBuffer | HTMLImageElement} buffer- A source of a file previously fetched as either an ArrayBuffer (compressed or image format) or HTMLImageElement (image format)
+         * @param {WebGLTexture} fallback- An internal argument in case the function must be called again, due to etc1 not having alpha capabilities.
+         * @param {number} format-  Internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures.
+         * 
+         * @returns {WebGLTexture} for assignment back into BABYLON.Texture
+         */
+        public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: ArrayBuffer | HTMLImageElement = null, fallBack?: WebGLTexture, format?: number): WebGLTexture {
             var texture = fallBack ? fallBack : this._gl.createTexture();
 
-            var extension: string;
-            var isKTX = false;
-            var fromData: any = false;
-            var url = String(urlArg);
-            if (url.substr(0, 5) === "data:") {
-                fromData = true;
-            }
-
-            if (!fromData) {
-                var lastDot = url.lastIndexOf('.')
-                extension = url.substring(lastDot).toLowerCase();
-                if (this._textureFormatInUse && !fromData && !fallBack) {
-                    extension = this._textureFormatInUse;
-                    url = url.substring(0, lastDot) + this._textureFormatInUse;
-                    isKTX = true;
 
-                }
-            } else {
-                var oldUrl = url;
-                fromData = oldUrl.split(':');
-                url = oldUrl;
-                extension = fromData[1].substr(fromData[1].length - 4, 4).toLowerCase();
-            }
+            var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
+            var fromData = url.substr(0, 5) === "data:";
+            var isBase64 = fromData && url.indexOf("base64") !== -1;
 
+            // establish the file extension, if possible
+            var lastDot = url.lastIndexOf('.');
+            var extension = (lastDot > 0) ? url.substring(lastDot).toLowerCase() : "";
             var isDDS = this.getCaps().s3tc && (extension === ".dds");
+            if (isDDS) {
+                BABYLON.Tools.Warn("DDS files deprecated since 3.0, use KTX files");
+            }
             var isTGA = (extension === ".tga");
+            
+            // determine if a ktx file should be substituted
+            var isKTX = false;
+            if (this._textureFormatInUse && !isBase64 && !fallBack) {
+                url = url.substring(0, lastDot) + this._textureFormatInUse;
+                isKTX = true;
+            }
 
             scene._addPendingData(texture);
             texture.url = url;
@@ -2161,6 +2183,7 @@
             texture.references = 1;
             texture.samplingMode = samplingMode;
             texture.onLoadedCallbacks = [];
+            
             if (onLoad) {
                 texture.onLoadedCallbacks.push(onLoad);
             }
@@ -2171,12 +2194,15 @@
 
                 // fallback for when compressed file not found to try again.  For instance, etc1 does not have an alpha capable type
                 if (isKTX) {
-                    this.createTexture(urlArg, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer, texture);
+                    this.createTexture(urlArg, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
                 } else if (onError) {
                     onError();
                 }
             };
+            
             var callback: (arrayBuffer: any) => void;
+
+            // processing for non-image formats
             if (isKTX || isTGA || isDDS) {
                 if (isKTX) {
                     callback = (data) => {
@@ -2209,13 +2235,14 @@
                     };
                 }
 
-                if (!(fromData instanceof Array))
-                    Tools.LoadFile(url, data => {
-                        callback(data);
-                    }, null, scene.database, true, onerror);
-                else
-                    callback(buffer);
-
+            if (!buffer) {
+                Tools.LoadFile(url, data => {
+                    callback(data);
+                }, null, scene.database, true, onerror);
+            } else {
+                callback(buffer);
+            }
+            // image format processing
             } else {
                 var onload = (img) => {
                     prepareWebGLTexture(texture, this._gl, scene, img.width, img.height, invertY, noMipmap, false, (potWidth, potHeight) => {
@@ -2244,16 +2271,18 @@
                             }
                         }
 
-                        let internalFormat = format ? this._getInternalFormat(format) : this._gl.RGBA;
+                        let internalFormat = format ? this._getInternalFormat(format) : ((extension === ".jpg") ? this._gl.RGB :this._gl.RGBA);
                         this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, internalFormat, this._gl.UNSIGNED_BYTE, isPot ? img : this._workingCanvas);
                     }, samplingMode);
                 };
 
 
-                if (!(fromData instanceof Array))
+                if (!fromData || isBase64)
                     Tools.LoadImage(url, onload, onerror, scene.database);
-                else
+                else if (buffer instanceof Array || typeof buffer === "string")
                     Tools.LoadImage(buffer, onload, onerror, scene.database);
+                else
+                    onload(buffer);                
             }
 
             return texture;
@@ -2707,6 +2736,9 @@
                 isKTX = true;
             }
             var isDDS = this.getCaps().s3tc && (extension === ".dds");
+            if (isDDS) {
+                BABYLON.Tools.Warn("DDS files deprecated since 3.0, use KTX files");
+            }
 
             if (isKTX) {
                 Tools.LoadFile(rootUrl, data => {

+ 101 - 7
src/babylon.scene.ts

@@ -190,7 +190,18 @@
         public ambientColor = new Color3(0, 0, 0);
 
         public forceWireframe = false;
-        public forcePointsCloud = false;
+        private _forcePointsCloud = false;
+        public set forcePointsCloud(value : boolean) {
+            if (this._forcePointsCloud === value) {
+                return;
+            }
+            this._forcePointsCloud = value;
+            this.markAllMaterialsAsDirty(Material.MiscDirtyFlag);
+        }
+        public get forcePointsCloud(): boolean {
+            return this._forcePointsCloud;
+        }   
+
         public forceShowBoundingBoxes = false;
         public clipPlane: Plane;
         public animationsEnabled = true;
@@ -395,6 +406,7 @@
         private _previousStartingPointerPosition = new Vector2(0, 0);
         private _startingPointerTime = 0;
         private _previousStartingPointerTime = 0;
+        
         // Mirror
         public _mirroredCameraPosition: Vector3;
 
@@ -407,8 +419,30 @@
         * is fog enabled on this scene.
         * @type {boolean}
         */
-        public fogEnabled = true;
-        public fogMode = Scene.FOGMODE_NONE;
+        private _fogEnabled = true;
+        public set fogEnabled(value : boolean) {
+            if (this._fogEnabled === value) {
+                return;
+            }
+            this._fogEnabled = value;
+            this.markAllMaterialsAsDirty(Material.MiscDirtyFlag);
+        }
+        public get fogEnabled(): boolean {
+            return this._fogEnabled;
+        }   
+
+        private _fogMode = Scene.FOGMODE_NONE;
+        public set fogMode(value : number) {
+            if (this._fogMode === value) {
+                return;
+            }
+            this._fogMode = value;
+            this.markAllMaterialsAsDirty(Material.MiscDirtyFlag);
+        }
+        public get fogMode(): number {
+            return this._fogMode;
+        }  
+
         public fogColor = new Color3(0.2, 0.2, 0.3);
         public fogDensity = 0.1;
         public fogStart = 0;
@@ -419,12 +453,35 @@
         * is shadow enabled on this scene.
         * @type {boolean}
         */
-        public shadowsEnabled = true;
+        private _shadowsEnabled = true;
+        public set shadowsEnabled(value : boolean) {
+            if (this._shadowsEnabled === value) {
+                return;
+            }
+            this._shadowsEnabled = value;
+            this.markAllMaterialsAsDirty(Material.LightDirtyFlag);
+        }
+        public get shadowsEnabled(): boolean {
+            return this._shadowsEnabled;
+        }       
+
         /**
         * is light enabled on this scene.
         * @type {boolean}
         */
-        public lightsEnabled = true;
+        private _lightsEnabled = true;
+        public set lightsEnabled(value : boolean) {
+            if (this._lightsEnabled === value) {
+                return;
+            }
+            this._lightsEnabled = value;
+            this.markAllMaterialsAsDirty(Material.LightDirtyFlag);
+        }
+
+        public get lightsEnabled(): boolean {
+            return this._lightsEnabled;
+        }    
+
         /**
         * All of the lights added to this scene.
         * @see BABYLON.Light
@@ -466,7 +523,19 @@
         }
 
         // Textures
-        public texturesEnabled = true;
+        private _texturesEnabled = true;
+        public set texturesEnabled(value : boolean) {
+            if (this._texturesEnabled === value) {
+                return;
+            }
+            this._texturesEnabled = value;
+            this.markAllMaterialsAsDirty(Material.TextureDirtyFlag);
+        }
+
+        public get texturesEnabled(): boolean {
+            return this._texturesEnabled;
+        }     
+
         public textures = new Array<BaseTexture>();
 
         // Particles
@@ -482,7 +551,19 @@
         public highlightLayers = new Array<HighlightLayer>();
 
         // Skeletons
-        public skeletonsEnabled = true;
+        private _skeletonsEnabled = true;
+        public set skeletonsEnabled(value : boolean) {
+            if (this._skeletonsEnabled === value) {
+                return;
+            }
+            this._skeletonsEnabled = value;
+            this.markAllMaterialsAsDirty(Material.AttributesDirtyFlag);
+        }
+
+        public get skeletonsEnabled(): boolean {
+            return this._skeletonsEnabled;
+        }       
+
         public skeletons = new Array<Skeleton>();
 
         // Lens flares
@@ -3465,5 +3546,18 @@
             stencil = true): void {
             this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil, depth, stencil);
         }
+
+        /**
+         * Will flag all materials as dirty to trigger new shader compilation
+         * @param predicate If not null, it will be used to specifiy if a material has to be marked as dirty
+         */
+        public markAllMaterialsAsDirty(flag: number, predicate?: (mat: Material) => boolean): void {
+            for (var material of this.materials) {
+                if (predicate && !predicate(material)) {
+                    continue;
+                }
+                material.markAsDirty(flag);
+            }
+        }
     }
 }