瀏覽代碼

Moved effect and defines to submeshes

David Catuhe 8 年之前
父節點
當前提交
42376a4aaf

+ 136 - 129
dist/preview release/babylon.d.ts

@@ -4369,6 +4369,58 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
+    interface ISceneLoaderPluginExtensions {
+        [extension: string]: {
+            isBinary: boolean;
+        };
+    }
+    interface ISceneLoaderPlugin {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    interface ISceneLoaderPluginAsync {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => void;
+        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static readonly NO_LOGGING: number;
+        static readonly MINIMAL_LOGGING: number;
+        static readonly SUMMARY_LOGGING: number;
+        static readonly DETAILED_LOGGING: number;
+        private static _loggingLevel;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        static loggingLevel: number;
+        private static _registeredPlugins;
+        private static _getDefaultPlugin();
+        private static _getPluginForExtension(extension);
+        private static _getPluginForFilename(sceneFilename);
+        private static _getDirectLoad(sceneFilename);
+        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
     class DirectionalLight extends Light implements IShadowLight {
         position: Vector3;
         position: Vector3;
         direction: Vector3;
         direction: Vector3;
@@ -4751,58 +4803,6 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
-    interface ISceneLoaderPluginExtensions {
-        [extension: string]: {
-            isBinary: boolean;
-        };
-    }
-    interface ISceneLoaderPlugin {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    interface ISceneLoaderPluginAsync {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => void;
-        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static readonly NO_LOGGING: number;
-        static readonly MINIMAL_LOGGING: number;
-        static readonly SUMMARY_LOGGING: number;
-        static readonly DETAILED_LOGGING: number;
-        private static _loggingLevel;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        static loggingLevel: number;
-        private static _registeredPlugins;
-        private static _getDefaultPlugin();
-        private static _getPluginForExtension(extension);
-        private static _getPluginForFilename(sceneFilename);
-        private static _getDirectLoad(sceneFilename);
-        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
-        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-    }
-}
-
-declare module BABYLON {
     /**
     /**
      * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
      * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
      * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
      * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
@@ -5182,6 +5182,7 @@ declare module BABYLON {
         onError: (effect: Effect, errors: string) => void;
         onError: (effect: Effect, errors: string) => void;
         getRenderTargetTextures: () => SmartArray<RenderTargetTexture>;
         getRenderTargetTextures: () => SmartArray<RenderTargetTexture>;
         doNotSerialize: boolean;
         doNotSerialize: boolean;
+        storeEffectOnSubMeshes: boolean;
         /**
         /**
         * An event triggered when the material is disposed.
         * An event triggered when the material is disposed.
         * @type {BABYLON.Observable}
         * @type {BABYLON.Observable}
@@ -5229,14 +5230,16 @@ declare module BABYLON {
         freeze(): void;
         freeze(): void;
         unfreeze(): void;
         unfreeze(): void;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         getEffect(): Effect;
         getEffect(): Effect;
         getScene(): Scene;
         getScene(): Scene;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
         markDirty(): void;
         markDirty(): void;
-        _preBind(): void;
+        _preBind(effect?: Effect): void;
         bind(world: Matrix, mesh?: Mesh): void;
         bind(world: Matrix, mesh?: Mesh): void;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         unbind(): void;
         unbind(): void;
         clone(name: string): Material;
         clone(name: string): Material;
@@ -5784,28 +5787,30 @@ declare module BABYLON {
         protected _worldViewProjectionMatrix: Matrix;
         protected _worldViewProjectionMatrix: Matrix;
         protected _globalAmbientColor: Color3;
         protected _globalAmbientColor: Color3;
         protected _renderId: number;
         protected _renderId: number;
-        protected _defines: StandardMaterialDefines;
         protected _useLogarithmicDepth: boolean;
         protected _useLogarithmicDepth: boolean;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
+        private _activeEffect;
         getClassName(): string;
         getClassName(): string;
         useLogarithmicDepth: boolean;
         useLogarithmicDepth: boolean;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         protected _shouldUseAlphaFromDiffuseTexture(): boolean;
         protected _shouldUseAlphaFromDiffuseTexture(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        protected _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean;
         /**
         /**
          * Child classes can use it to update shaders
          * Child classes can use it to update shaders
          */
          */
         markAsDirty(): void;
         markAsDirty(): void;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         unbind(): void;
         unbind(): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         bind(world: Matrix, mesh?: Mesh): void;
         bind(world: Matrix, mesh?: Mesh): void;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
         dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
         clone(name: string): StandardMaterial;
         clone(name: string): StandardMaterial;
         serialize(): any;
         serialize(): any;
+        private _markAllSubMeshesAsTextureDirty();
         static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial;
         static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial;
         static _DiffuseTextureEnabled: boolean;
         static _DiffuseTextureEnabled: boolean;
         static DiffuseTextureEnabled: boolean;
         static DiffuseTextureEnabled: boolean;
@@ -7968,7 +7973,6 @@ declare module BABYLON {
         _positions: Vector3[];
         _positions: Vector3[];
         private _isDirty;
         private _isDirty;
         _masterMesh: AbstractMesh;
         _masterMesh: AbstractMesh;
-        _materialDefines: MaterialDefines;
         _boundingInfo: BoundingInfo;
         _boundingInfo: BoundingInfo;
         private _pivotMatrix;
         private _pivotMatrix;
         _isDisposed: boolean;
         _isDisposed: boolean;
@@ -10747,6 +10751,9 @@ declare module BABYLON {
         _alphaIndex: number;
         _alphaIndex: number;
         _distanceToCamera: number;
         _distanceToCamera: number;
         _id: number;
         _id: number;
+        _materialDefines: MaterialDefines;
+        private _materialEffect;
+        effect: Effect;
         constructor(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: any, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox?: boolean);
         constructor(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: any, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox?: boolean);
         readonly IsGlobal: boolean;
         readonly IsGlobal: boolean;
         /**
         /**
@@ -12672,6 +12679,76 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
+declare module BABYLON {
+    class Sprite {
+        name: string;
+        position: Vector3;
+        color: Color4;
+        width: number;
+        height: number;
+        angle: number;
+        cellIndex: number;
+        invertU: number;
+        invertV: number;
+        disposeWhenFinishedAnimating: boolean;
+        animations: Animation[];
+        isPickable: boolean;
+        actionManager: ActionManager;
+        private _animationStarted;
+        private _loopAnimation;
+        private _fromIndex;
+        private _toIndex;
+        private _delay;
+        private _direction;
+        private _frameCount;
+        private _manager;
+        private _time;
+        private _onAnimationEnd;
+        size: number;
+        constructor(name: string, manager: SpriteManager);
+        playAnimation(from: number, to: number, loop: boolean, delay: number, onAnimationEnd: () => void): void;
+        stopAnimation(): void;
+        _animate(deltaTime: number): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class SpriteManager {
+        name: string;
+        sprites: Sprite[];
+        renderingGroupId: number;
+        layerMask: number;
+        fogEnabled: boolean;
+        isPickable: boolean;
+        cellWidth: number;
+        cellHeight: number;
+        /**
+        * An event triggered when the manager is disposed.
+        * @type {BABYLON.Observable}
+        */
+        onDisposeObservable: Observable<SpriteManager>;
+        private _onDisposeObserver;
+        onDispose: () => void;
+        private _capacity;
+        private _spriteTexture;
+        private _epsilon;
+        private _scene;
+        private _vertexData;
+        private _buffer;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effectBase;
+        private _effectFog;
+        texture: Texture;
+        constructor(name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number);
+        private _appendSpriteVertex(index, sprite, offsetX, offsetY, rowSize);
+        intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): PickingInfo;
+        render(): void;
+        dispose(): void;
+    }
+}
+
 declare module BABYLON.Internals {
 declare module BABYLON.Internals {
     class _AlphaState {
     class _AlphaState {
         private _isAlphaBlendDirty;
         private _isAlphaBlendDirty;
@@ -12749,76 +12826,6 @@ declare module BABYLON.Internals {
     }
     }
 }
 }
 
 
-declare module BABYLON {
-    class Sprite {
-        name: string;
-        position: Vector3;
-        color: Color4;
-        width: number;
-        height: number;
-        angle: number;
-        cellIndex: number;
-        invertU: number;
-        invertV: number;
-        disposeWhenFinishedAnimating: boolean;
-        animations: Animation[];
-        isPickable: boolean;
-        actionManager: ActionManager;
-        private _animationStarted;
-        private _loopAnimation;
-        private _fromIndex;
-        private _toIndex;
-        private _delay;
-        private _direction;
-        private _frameCount;
-        private _manager;
-        private _time;
-        private _onAnimationEnd;
-        size: number;
-        constructor(name: string, manager: SpriteManager);
-        playAnimation(from: number, to: number, loop: boolean, delay: number, onAnimationEnd: () => void): void;
-        stopAnimation(): void;
-        _animate(deltaTime: number): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class SpriteManager {
-        name: string;
-        sprites: Sprite[];
-        renderingGroupId: number;
-        layerMask: number;
-        fogEnabled: boolean;
-        isPickable: boolean;
-        cellWidth: number;
-        cellHeight: number;
-        /**
-        * An event triggered when the manager is disposed.
-        * @type {BABYLON.Observable}
-        */
-        onDisposeObservable: Observable<SpriteManager>;
-        private _onDisposeObserver;
-        onDispose: () => void;
-        private _capacity;
-        private _spriteTexture;
-        private _epsilon;
-        private _scene;
-        private _vertexData;
-        private _buffer;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effectBase;
-        private _effectFog;
-        texture: Texture;
-        constructor(name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number);
-        private _appendSpriteVertex(index, sprite, offsetX, offsetY, rowSize);
-        intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): PickingInfo;
-        render(): void;
-        dispose(): void;
-    }
-}
-
 declare module BABYLON.Internals {
 declare module BABYLON.Internals {
     class AndOrNotEvaluator {
     class AndOrNotEvaluator {
         static Eval(query: string, evaluateCallback: (val: any) => boolean): boolean;
         static Eval(query: string, evaluateCallback: (val: any) => boolean): boolean;
@@ -14513,6 +14520,9 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
+declare module BABYLON.Internals {
+}
+
 declare module BABYLON {
 declare module BABYLON {
     interface IShadowGenerator {
     interface IShadowGenerator {
         getShadowMap(): RenderTargetTexture;
         getShadowMap(): RenderTargetTexture;
@@ -14625,9 +14635,6 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
 declare module BABYLON {
     class BaseTexture {
     class BaseTexture {
         name: string;
         name: string;

+ 136 - 129
dist/preview release/babylon.module.d.ts

@@ -4369,6 +4369,58 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
+    interface ISceneLoaderPluginExtensions {
+        [extension: string]: {
+            isBinary: boolean;
+        };
+    }
+    interface ISceneLoaderPlugin {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    interface ISceneLoaderPluginAsync {
+        extensions: string | ISceneLoaderPluginExtensions;
+        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => void;
+        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static readonly NO_LOGGING: number;
+        static readonly MINIMAL_LOGGING: number;
+        static readonly SUMMARY_LOGGING: number;
+        static readonly DETAILED_LOGGING: number;
+        private static _loggingLevel;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        static loggingLevel: number;
+        private static _registeredPlugins;
+        private static _getDefaultPlugin();
+        private static _getPluginForExtension(extension);
+        private static _getPluginForFilename(sceneFilename);
+        private static _getDirectLoad(sceneFilename);
+        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
     class DirectionalLight extends Light implements IShadowLight {
         position: Vector3;
         position: Vector3;
         direction: Vector3;
         direction: Vector3;
@@ -4751,58 +4803,6 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
-    interface ISceneLoaderPluginExtensions {
-        [extension: string]: {
-            isBinary: boolean;
-        };
-    }
-    interface ISceneLoaderPlugin {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    interface ISceneLoaderPluginAsync {
-        extensions: string | ISceneLoaderPluginExtensions;
-        importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onerror?: () => void) => void;
-        loadAsync: (scene: Scene, data: string, rootUrl: string, onsuccess: () => void, onerror: () => void) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static readonly NO_LOGGING: number;
-        static readonly MINIMAL_LOGGING: number;
-        static readonly SUMMARY_LOGGING: number;
-        static readonly DETAILED_LOGGING: number;
-        private static _loggingLevel;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        static loggingLevel: number;
-        private static _registeredPlugins;
-        private static _getDefaultPlugin();
-        private static _getPluginForExtension(extension);
-        private static _getPluginForFilename(sceneFilename);
-        private static _getDirectLoad(sceneFilename);
-        static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
-        static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, message: string, exception?: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-    }
-}
-
-declare module BABYLON {
     /**
     /**
      * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
      * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
      * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
      * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
@@ -5182,6 +5182,7 @@ declare module BABYLON {
         onError: (effect: Effect, errors: string) => void;
         onError: (effect: Effect, errors: string) => void;
         getRenderTargetTextures: () => SmartArray<RenderTargetTexture>;
         getRenderTargetTextures: () => SmartArray<RenderTargetTexture>;
         doNotSerialize: boolean;
         doNotSerialize: boolean;
+        storeEffectOnSubMeshes: boolean;
         /**
         /**
         * An event triggered when the material is disposed.
         * An event triggered when the material is disposed.
         * @type {BABYLON.Observable}
         * @type {BABYLON.Observable}
@@ -5229,14 +5230,16 @@ declare module BABYLON {
         freeze(): void;
         freeze(): void;
         unfreeze(): void;
         unfreeze(): void;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         getEffect(): Effect;
         getEffect(): Effect;
         getScene(): Scene;
         getScene(): Scene;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
         markDirty(): void;
         markDirty(): void;
-        _preBind(): void;
+        _preBind(effect?: Effect): void;
         bind(world: Matrix, mesh?: Mesh): void;
         bind(world: Matrix, mesh?: Mesh): void;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         unbind(): void;
         unbind(): void;
         clone(name: string): Material;
         clone(name: string): Material;
@@ -5784,28 +5787,30 @@ declare module BABYLON {
         protected _worldViewProjectionMatrix: Matrix;
         protected _worldViewProjectionMatrix: Matrix;
         protected _globalAmbientColor: Color3;
         protected _globalAmbientColor: Color3;
         protected _renderId: number;
         protected _renderId: number;
-        protected _defines: StandardMaterialDefines;
         protected _useLogarithmicDepth: boolean;
         protected _useLogarithmicDepth: boolean;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
+        private _activeEffect;
         getClassName(): string;
         getClassName(): string;
         useLogarithmicDepth: boolean;
         useLogarithmicDepth: boolean;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         protected _shouldUseAlphaFromDiffuseTexture(): boolean;
         protected _shouldUseAlphaFromDiffuseTexture(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        protected _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean;
         /**
         /**
          * Child classes can use it to update shaders
          * Child classes can use it to update shaders
          */
          */
         markAsDirty(): void;
         markAsDirty(): void;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         unbind(): void;
         unbind(): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         bind(world: Matrix, mesh?: Mesh): void;
         bind(world: Matrix, mesh?: Mesh): void;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
         dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
         clone(name: string): StandardMaterial;
         clone(name: string): StandardMaterial;
         serialize(): any;
         serialize(): any;
+        private _markAllSubMeshesAsTextureDirty();
         static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial;
         static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial;
         static _DiffuseTextureEnabled: boolean;
         static _DiffuseTextureEnabled: boolean;
         static DiffuseTextureEnabled: boolean;
         static DiffuseTextureEnabled: boolean;
@@ -7968,7 +7973,6 @@ declare module BABYLON {
         _positions: Vector3[];
         _positions: Vector3[];
         private _isDirty;
         private _isDirty;
         _masterMesh: AbstractMesh;
         _masterMesh: AbstractMesh;
-        _materialDefines: MaterialDefines;
         _boundingInfo: BoundingInfo;
         _boundingInfo: BoundingInfo;
         private _pivotMatrix;
         private _pivotMatrix;
         _isDisposed: boolean;
         _isDisposed: boolean;
@@ -10747,6 +10751,9 @@ declare module BABYLON {
         _alphaIndex: number;
         _alphaIndex: number;
         _distanceToCamera: number;
         _distanceToCamera: number;
         _id: number;
         _id: number;
+        _materialDefines: MaterialDefines;
+        private _materialEffect;
+        effect: Effect;
         constructor(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: any, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox?: boolean);
         constructor(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: any, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox?: boolean);
         readonly IsGlobal: boolean;
         readonly IsGlobal: boolean;
         /**
         /**
@@ -12672,6 +12679,76 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
+declare module BABYLON {
+    class Sprite {
+        name: string;
+        position: Vector3;
+        color: Color4;
+        width: number;
+        height: number;
+        angle: number;
+        cellIndex: number;
+        invertU: number;
+        invertV: number;
+        disposeWhenFinishedAnimating: boolean;
+        animations: Animation[];
+        isPickable: boolean;
+        actionManager: ActionManager;
+        private _animationStarted;
+        private _loopAnimation;
+        private _fromIndex;
+        private _toIndex;
+        private _delay;
+        private _direction;
+        private _frameCount;
+        private _manager;
+        private _time;
+        private _onAnimationEnd;
+        size: number;
+        constructor(name: string, manager: SpriteManager);
+        playAnimation(from: number, to: number, loop: boolean, delay: number, onAnimationEnd: () => void): void;
+        stopAnimation(): void;
+        _animate(deltaTime: number): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class SpriteManager {
+        name: string;
+        sprites: Sprite[];
+        renderingGroupId: number;
+        layerMask: number;
+        fogEnabled: boolean;
+        isPickable: boolean;
+        cellWidth: number;
+        cellHeight: number;
+        /**
+        * An event triggered when the manager is disposed.
+        * @type {BABYLON.Observable}
+        */
+        onDisposeObservable: Observable<SpriteManager>;
+        private _onDisposeObserver;
+        onDispose: () => void;
+        private _capacity;
+        private _spriteTexture;
+        private _epsilon;
+        private _scene;
+        private _vertexData;
+        private _buffer;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effectBase;
+        private _effectFog;
+        texture: Texture;
+        constructor(name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number);
+        private _appendSpriteVertex(index, sprite, offsetX, offsetY, rowSize);
+        intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): PickingInfo;
+        render(): void;
+        dispose(): void;
+    }
+}
+
 declare module BABYLON.Internals {
 declare module BABYLON.Internals {
     class _AlphaState {
     class _AlphaState {
         private _isAlphaBlendDirty;
         private _isAlphaBlendDirty;
@@ -12749,76 +12826,6 @@ declare module BABYLON.Internals {
     }
     }
 }
 }
 
 
-declare module BABYLON {
-    class Sprite {
-        name: string;
-        position: Vector3;
-        color: Color4;
-        width: number;
-        height: number;
-        angle: number;
-        cellIndex: number;
-        invertU: number;
-        invertV: number;
-        disposeWhenFinishedAnimating: boolean;
-        animations: Animation[];
-        isPickable: boolean;
-        actionManager: ActionManager;
-        private _animationStarted;
-        private _loopAnimation;
-        private _fromIndex;
-        private _toIndex;
-        private _delay;
-        private _direction;
-        private _frameCount;
-        private _manager;
-        private _time;
-        private _onAnimationEnd;
-        size: number;
-        constructor(name: string, manager: SpriteManager);
-        playAnimation(from: number, to: number, loop: boolean, delay: number, onAnimationEnd: () => void): void;
-        stopAnimation(): void;
-        _animate(deltaTime: number): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class SpriteManager {
-        name: string;
-        sprites: Sprite[];
-        renderingGroupId: number;
-        layerMask: number;
-        fogEnabled: boolean;
-        isPickable: boolean;
-        cellWidth: number;
-        cellHeight: number;
-        /**
-        * An event triggered when the manager is disposed.
-        * @type {BABYLON.Observable}
-        */
-        onDisposeObservable: Observable<SpriteManager>;
-        private _onDisposeObserver;
-        onDispose: () => void;
-        private _capacity;
-        private _spriteTexture;
-        private _epsilon;
-        private _scene;
-        private _vertexData;
-        private _buffer;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effectBase;
-        private _effectFog;
-        texture: Texture;
-        constructor(name: string, imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon?: number, samplingMode?: number);
-        private _appendSpriteVertex(index, sprite, offsetX, offsetY, rowSize);
-        intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): PickingInfo;
-        render(): void;
-        dispose(): void;
-    }
-}
-
 declare module BABYLON.Internals {
 declare module BABYLON.Internals {
     class AndOrNotEvaluator {
     class AndOrNotEvaluator {
         static Eval(query: string, evaluateCallback: (val: any) => boolean): boolean;
         static Eval(query: string, evaluateCallback: (val: any) => boolean): boolean;
@@ -14513,6 +14520,9 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
+declare module BABYLON.Internals {
+}
+
 declare module BABYLON {
 declare module BABYLON {
     interface IShadowGenerator {
     interface IShadowGenerator {
         getShadowMap(): RenderTargetTexture;
         getShadowMap(): RenderTargetTexture;
@@ -14625,9 +14635,6 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
 declare module BABYLON {
     class BaseTexture {
     class BaseTexture {
         name: string;
         name: string;

+ 11 - 2
src/Materials/babylon.material.ts

@@ -170,6 +170,8 @@
 
 
         public doNotSerialize = false;
         public doNotSerialize = false;
 
 
+        public storeEffectOnSubMeshes = false;
+
         /**
         /**
         * An event triggered when the material is disposed.
         * An event triggered when the material is disposed.
         * @type {BABYLON.Observable}
         * @type {BABYLON.Observable}
@@ -309,6 +311,10 @@
             return true;
             return true;
         }
         }
 
 
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+            return false;            
+        }
+
         public getEffect(): Effect {
         public getEffect(): Effect {
             return this._effect;
             return this._effect;
         }
         }
@@ -333,12 +339,12 @@
             this._wasPreviouslyReady = false;
             this._wasPreviouslyReady = false;
         }
         }
 
 
-        public _preBind(): void {
+        public _preBind(effect?: Effect): void {
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
 
 
             var reverse = this.sideOrientation === Material.ClockWiseSideOrientation;
             var reverse = this.sideOrientation === Material.ClockWiseSideOrientation;
 
 
-            engine.enableEffect(this._effect);
+            engine.enableEffect(effect ? effect : this._effect);
             engine.setState(this.backFaceCulling, this.zOffset, false, reverse);
             engine.setState(this.backFaceCulling, this.zOffset, false, reverse);
         }
         }
 
 
@@ -354,6 +360,9 @@
             }
             }
         }
         }
 
 
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        }
+
         public bindOnlyWorldMatrix(world: Matrix): void {
         public bindOnlyWorldMatrix(world: Matrix): void {
         }
         }
 
 

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

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

+ 245 - 216
src/Materials/babylon.standardMaterial.ts

@@ -60,7 +60,7 @@ module BABYLON {
         public CAMERACOLORGRADING = false;
         public CAMERACOLORGRADING = false;
         public CAMERACOLORCURVES = false;
         public CAMERACOLORCURVES = false;
 
 
-        public _areTexturesDirty = false;
+        public _areTexturesDirty = true;
         public _needUVs = false;
         public _needUVs = false;
 
 
         constructor() {
         constructor() {
@@ -91,7 +91,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._diffuseTexture = value;
             this._diffuseTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get diffuseTexture(): BaseTexture {
         public get diffuseTexture(): BaseTexture {
@@ -106,7 +106,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._ambientTexture = value;
             this._ambientTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get ambientTexture(): BaseTexture {
         public get ambientTexture(): BaseTexture {
@@ -121,7 +121,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._opacityTexture = value;
             this._opacityTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get opacityTexture(): BaseTexture {
         public get opacityTexture(): BaseTexture {
@@ -136,7 +136,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._reflectionTexture = value;
             this._reflectionTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get reflectionTexture(): BaseTexture {
         public get reflectionTexture(): BaseTexture {
@@ -151,7 +151,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._emissiveTexture = value;
             this._emissiveTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get emissiveTexture(): BaseTexture {
         public get emissiveTexture(): BaseTexture {
@@ -166,7 +166,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._specularTexture = value;
             this._specularTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get specularTexture(): BaseTexture {
         public get specularTexture(): BaseTexture {
@@ -181,7 +181,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._bumpTexture = value;
             this._bumpTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get bumpTexture(): BaseTexture {
         public get bumpTexture(): BaseTexture {
@@ -196,7 +196,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._lightmapTexture = value;
             this._lightmapTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get lightmapTexture(): BaseTexture {
         public get lightmapTexture(): BaseTexture {
@@ -211,7 +211,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._refractionTexture = value;
             this._refractionTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get refractionTexture(): BaseTexture {
         public get refractionTexture(): BaseTexture {
@@ -326,7 +326,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
             this._cameraColorGradingTexture = value;
             this._cameraColorGradingTexture = value;
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public get cameraColorGradingTexture(): BaseTexture {
         public get cameraColorGradingTexture(): BaseTexture {
@@ -347,12 +347,11 @@ module BABYLON {
         protected _globalAmbientColor = new Color3(0, 0, 0);
         protected _globalAmbientColor = new Color3(0, 0, 0);
         protected _renderId: number;
         protected _renderId: number;
 
 
-        protected _defines = new StandardMaterialDefines();
-
         protected _useLogarithmicDepth: boolean;
         protected _useLogarithmicDepth: boolean;
 
 
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
+            this.storeEffectOnSubMeshes = true;
 
 
             this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
             this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
                 this._renderTargets.reset();
                 this._renderTargets.reset();
@@ -369,6 +368,8 @@ module BABYLON {
             }
             }
         }
         }
 
 
+        private _activeEffect: Effect;
+
         public getClassName(): string {
         public getClassName(): string {
             return "StandardMaterial";
             return "StandardMaterial";
         }        
         }        
@@ -398,86 +399,84 @@ module BABYLON {
             return this.diffuseTexture;
             return this.diffuseTexture;
         }
         }
 
 
-        // Methods   
-        protected _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
         /**
         /**
          * Child classes can use it to update shaders
          * Child classes can use it to update shaders
          */
          */
         public markAsDirty() {
         public markAsDirty() {
-            this._defines._areTexturesDirty = true;
+            this._markAllSubMeshesAsTextureDirty();
         }
         }
 
 
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
+            if (!mesh) {
+                return false;
+            }
+
+            return this.isReadyForSubMesh(mesh, mesh.subMeshes[0], useInstances);
+        }
+
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {            
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady) {
                 if (this._wasPreviouslyReady) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new StandardMaterialDefines();
+            }
+
+            var defines = <StandardMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             var engine = scene.getEngine();
             var engine = scene.getEngine();
             var needNormals = false;
             var needNormals = false;
 
 
             // Lights
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, this.maxSimultaneousLights);
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, this.maxSimultaneousLights);
             }
             }
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             // Textures
             // Textures
-            if (this._defines._areTexturesDirty) {
-                this._defines._needUVs = false;
+            if (defines._areTexturesDirty) {
+                defines._needUVs = false;
                 if (scene.texturesEnabled) {
                 if (scene.texturesEnabled) {
                     if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                     if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                         if (!this._diffuseTexture.isReady()) {
                         if (!this._diffuseTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.DIFFUSE = true;
+                            defines._needUVs = true;
+                            defines.DIFFUSE = true;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.DIFFUSE = false;
+                        defines.DIFFUSE = false;
                     }
                     }
 
 
                     if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
                     if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
                         if (!this._ambientTexture.isReady()) {
                         if (!this._ambientTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.AMBIENT = true;
+                            defines._needUVs = true;
+                            defines.AMBIENT = true;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.AMBIENT = false;
+                        defines.AMBIENT = false;
                     }
                     }
 
 
                     if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
                     if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
                         if (!this._opacityTexture.isReady()) {
                         if (!this._opacityTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.OPACITY = true;
-                            this._defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;
+                            defines._needUVs = true;
+                            defines.OPACITY = true;
+                            defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.OPACITY = false;
+                        defines.OPACITY = false;
                     }
                     }
 
 
                     if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
                     if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
@@ -485,167 +484,167 @@ module BABYLON {
                             return false;
                             return false;
                         } else {
                         } else {
                             needNormals = true;
                             needNormals = true;
-                            this._defines.REFLECTION = true;
+                            defines.REFLECTION = true;
 
 
-                            this._defines.ROUGHNESS = (this.roughness > 0);
-                            this._defines.REFLECTIONOVERALPHA = this.useReflectionOverAlpha;
-                            this._defines.INVERTCUBICMAP = (this._reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE);
-                            this._defines.REFLECTIONMAP_3D = this._reflectionTexture.isCube;
+                            defines.ROUGHNESS = (this.roughness > 0);
+                            defines.REFLECTIONOVERALPHA = this.useReflectionOverAlpha;
+                            defines.INVERTCUBICMAP = (this._reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE);
+                            defines.REFLECTIONMAP_3D = this._reflectionTexture.isCube;
 
 
                             switch (this._reflectionTexture.coordinatesMode) {
                             switch (this._reflectionTexture.coordinatesMode) {
                                 case Texture.CUBIC_MODE:
                                 case Texture.CUBIC_MODE:
                                 case Texture.INVCUBIC_MODE:
                                 case Texture.INVCUBIC_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_CUBIC");
+                                    defines.setReflectionMode("REFLECTIONMAP_CUBIC");
                                     break;
                                     break;
                                 case Texture.EXPLICIT_MODE:
                                 case Texture.EXPLICIT_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_EXPLICIT");
+                                    defines.setReflectionMode("REFLECTIONMAP_EXPLICIT");
                                     break;
                                     break;
                                 case Texture.PLANAR_MODE:
                                 case Texture.PLANAR_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_PLANAR");
+                                    defines.setReflectionMode("REFLECTIONMAP_PLANAR");
                                     break;
                                     break;
                                 case Texture.PROJECTION_MODE:
                                 case Texture.PROJECTION_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_PROJECTION");
+                                    defines.setReflectionMode("REFLECTIONMAP_PROJECTION");
                                     break;
                                     break;
                                 case Texture.SKYBOX_MODE:
                                 case Texture.SKYBOX_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_SKYBOX");
+                                    defines.setReflectionMode("REFLECTIONMAP_SKYBOX");
                                     break;
                                     break;
                                 case Texture.SPHERICAL_MODE:
                                 case Texture.SPHERICAL_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_SPHERICAL");
+                                    defines.setReflectionMode("REFLECTIONMAP_SPHERICAL");
                                     break;
                                     break;
                                 case Texture.EQUIRECTANGULAR_MODE:
                                 case Texture.EQUIRECTANGULAR_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_EQUIRECTANGULAR");
+                                    defines.setReflectionMode("REFLECTIONMAP_EQUIRECTANGULAR");
                                     break;
                                     break;
                                 case Texture.FIXED_EQUIRECTANGULAR_MODE:
                                 case Texture.FIXED_EQUIRECTANGULAR_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_EQUIRECTANGULAR_FIXED");
+                                    defines.setReflectionMode("REFLECTIONMAP_EQUIRECTANGULAR_FIXED");
                                     break;
                                     break;
                                 case Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE:
                                 case Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE:
-                                    this._defines.setReflectionMode("REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED");
+                                    defines.setReflectionMode("REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED");
                                     break;
                                     break;
                             }
                             }
                         }
                         }
                     } else {
                     } else {
-                        this._defines.REFLECTION = false;
+                        defines.REFLECTION = false;
                     }
                     }
 
 
                     if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
                     if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
                         if (!this._emissiveTexture.isReady()) {
                         if (!this._emissiveTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.EMISSIVE = true;
+                            defines._needUVs = true;
+                            defines.EMISSIVE = true;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.EMISSIVE = false;
+                        defines.EMISSIVE = false;
                     }
                     }
 
 
                     if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
                     if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
                         if (!this._lightmapTexture.isReady()) {
                         if (!this._lightmapTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.LIGHTMAP = true;
-                            this._defines.USELIGHTMAPASSHADOWMAP = this.useLightmapAsShadowmap;
+                            defines._needUVs = true;
+                            defines.LIGHTMAP = true;
+                            defines.USELIGHTMAPASSHADOWMAP = this.useLightmapAsShadowmap;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.LIGHTMAP = false;
+                        defines.LIGHTMAP = false;
                     }
                     }
 
 
                     if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
                     if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
                         if (!this._specularTexture.isReady()) {
                         if (!this._specularTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.SPECULAR = true;
-                            this._defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
+                            defines._needUVs = true;
+                            defines.SPECULAR = true;
+                            defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.SPECULAR = false;
+                        defines.SPECULAR = false;
                     }
                     }
 
 
                     if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && StandardMaterial.BumpTextureEnabled) {
                     if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && StandardMaterial.BumpTextureEnabled) {
                         if (!this._bumpTexture.isReady()) {
                         if (!this._bumpTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.BUMP = true;
+                            defines._needUVs = true;
+                            defines.BUMP = true;
 
 
-                            this._defines.PARALLAX = this.useParallax;
-                            this._defines.PARALLAXOCCLUSION = this.useParallaxOcclusion;
+                            defines.PARALLAX = this.useParallax;
+                            defines.PARALLAXOCCLUSION = this.useParallaxOcclusion;
 
 
-                            this._defines.INVERTNORMALMAPX = this.invertNormalMapX;
-                            this._defines.INVERTNORMALMAPY = this.invertNormalMapY;
+                            defines.INVERTNORMALMAPX = this.invertNormalMapX;
+                            defines.INVERTNORMALMAPY = this.invertNormalMapY;
 
 
                             if (scene._mirroredCameraPosition) {
                             if (scene._mirroredCameraPosition) {
-                                this._defines.INVERTNORMALMAPX = !this._defines.INVERTNORMALMAPX;
-                                this._defines.INVERTNORMALMAPY = !this._defines.INVERTNORMALMAPY;
+                                defines.INVERTNORMALMAPX = !defines.INVERTNORMALMAPX;
+                                defines.INVERTNORMALMAPY = !defines.INVERTNORMALMAPY;
                             }
                             }
                         }
                         }
                     } else {
                     } else {
-                        this._defines.BUMP = false;
+                        defines.BUMP = false;
                     }
                     }
 
 
                     if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                     if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                         if (!this._refractionTexture.isReady()) {
                         if (!this._refractionTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines._needUVs = true;
-                            this._defines.REFRACTION = true;
+                            defines._needUVs = true;
+                            defines.REFRACTION = true;
 
 
-                            this._defines.REFRACTIONMAP_3D = this._refractionTexture.isCube;
+                            defines.REFRACTIONMAP_3D = this._refractionTexture.isCube;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.REFRACTION = false;
+                        defines.REFRACTION = false;
                     }
                     }
 
 
                     if (this._cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
                     if (this._cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
                         if (!this._cameraColorGradingTexture.isReady()) {
                         if (!this._cameraColorGradingTexture.isReady()) {
                             return false;
                             return false;
                         } else {
                         } else {
-                            this._defines.CAMERACOLORGRADING = true;
+                            defines.CAMERACOLORGRADING = true;
                         }
                         }
                     } else {
                     } else {
-                        this._defines.CAMERACOLORGRADING = false;
+                        defines.CAMERACOLORGRADING = false;
                     }
                     }
 
 
                     if (!this.backFaceCulling && this.twoSidedLighting) {
                     if (!this.backFaceCulling && this.twoSidedLighting) {
-                        this._defines.TWOSIDEDLIGHTING = true;
+                        defines.TWOSIDEDLIGHTING = true;
                     } else {
                     } else {
-                        this._defines.TWOSIDEDLIGHTING = false;
+                        defines.TWOSIDEDLIGHTING = false;
                     }
                     }
+                } else {
+                    defines.DIFFUSE = false;
+                    defines.AMBIENT = false;
+                    defines.OPACITY = false;
+                    defines.REFLECTION = false;
+                    defines.EMISSIVE = false;
+                    defines.LIGHTMAP = false;
+                    defines.BUMP = false;
+                    defines.REFRACTION = false;
+                    defines.CAMERACOLORGRADING = false;
                 }
                 }
-                this._defines._areTexturesDirty = false;
-            } else {
-                this._defines.DIFFUSE = false;
-                this._defines.AMBIENT = false;
-                this._defines.OPACITY = false;
-                this._defines.REFLECTION = false;
-                this._defines.EMISSIVE = false;
-                this._defines.LIGHTMAP = false;
-                this._defines.BUMP = false;
-                this._defines.REFRACTION = false;
-                this._defines.CAMERACOLORGRADING = false;
-            }
+                defines._areTexturesDirty = false;
+            } 
 
 
             // Effect
             // Effect
-            this._defines.CLIPPLANE = (scene.clipPlane !== undefined && scene.clipPlane !== null);
+            defines.CLIPPLANE = (scene.clipPlane !== undefined && scene.clipPlane !== null);
 
 
-            this._defines.ALPHATEST = engine.getAlphaTesting();
+            defines.ALPHATEST = engine.getAlphaTesting();
 
 
-            this._defines.ALPHAFROMDIFFUSE = this._shouldUseAlphaFromDiffuseTexture();
+            defines.ALPHAFROMDIFFUSE = this._shouldUseAlphaFromDiffuseTexture();
 
 
-            this._defines.EMISSIVEASILLUMINATION = this.useEmissiveAsIllumination;
+            defines.EMISSIVEASILLUMINATION = this.useEmissiveAsIllumination;
 
 
-            this._defines.LINKEMISSIVEWITHDIFFUSE = this.linkEmissiveWithDiffuse;
+            defines.LINKEMISSIVEWITHDIFFUSE = this.linkEmissiveWithDiffuse;
 
 
-            this._defines.LOGARITHMICDEPTH = this.useLogarithmicDepth;
+            defines.LOGARITHMICDEPTH = this.useLogarithmicDepth;
 
 
-            this._defines.CAMERACOLORCURVES = (this.cameraColorCurves !== undefined && this.cameraColorCurves !== null);
+            defines.CAMERACOLORCURVES = (this.cameraColorCurves !== undefined && this.cameraColorCurves !== null);
 
 
             // Point size
             // Point size
-            this._defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
+            defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
 
 
             // Fog
             // Fog
-            this._defines.FOG = (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
+            defines.FOG = (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
 
 
             if (StandardMaterial.FresnelEnabled) {
             if (StandardMaterial.FresnelEnabled) {
                 // Fresnel
                 // Fresnel
@@ -655,149 +654,149 @@ module BABYLON {
                     this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled ||
                     this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled ||
                     this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
                     this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
 
 
-                    this._defines.DIFFUSEFRESNEL = (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled);
+                    defines.DIFFUSEFRESNEL = (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled);
 
 
-                    this._defines.OPACITYFRESNEL = (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled);
+                    defines.OPACITYFRESNEL = (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled);
 
 
-                    this._defines.REFLECTIONFRESNEL = (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled);
+                    defines.REFLECTIONFRESNEL = (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled);
 
 
-                    this._defines.REFLECTIONFRESNELFROMSPECULAR = this.useReflectionFresnelFromSpecular;
+                    defines.REFLECTIONFRESNELFROMSPECULAR = this.useReflectionFresnelFromSpecular;
 
 
-                    this._defines.REFRACTIONFRESNEL = (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) ;
+                    defines.REFRACTIONFRESNEL = (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) ;
 
 
-                    this._defines.EMISSIVEFRESNEL = (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) ;
+                    defines.EMISSIVEFRESNEL = (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) ;
 
 
                     needNormals = true;
                     needNormals = true;
-                    this._defines.FRESNEL = true;
+                    defines.FRESNEL = true;
                 }
                 }
             } else {
             } else {
-                this._defines.FRESNEL = false;
+                defines.FRESNEL = false;
             }
             }
 
 
-            this._defines.SPECULAROVERALPHA = (this._defines.SPECULARTERM && this.useSpecularOverAlpha);
+            defines.SPECULAROVERALPHA = (defines.SPECULARTERM && this.useSpecularOverAlpha);
 
 
             // Attribs
             // Attribs
             if (mesh) {
             if (mesh) {
-                this._defines.NORMAL = (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
+                defines.NORMAL = (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
 
 
-                if (this._defines._needUVs) {
-                    this._defines.UV1 = mesh.isVerticesDataPresent(VertexBuffer.UVKind);
-                    this._defines.UV2 = mesh.isVerticesDataPresent(VertexBuffer.UV2Kind);
+                if (defines._needUVs) {
+                    defines.UV1 = mesh.isVerticesDataPresent(VertexBuffer.UVKind);
+                    defines.UV2 = mesh.isVerticesDataPresent(VertexBuffer.UV2Kind);
                 } else {
                 } else {
-                    this._defines.UV1 = false;
-                    this._defines.UV2 = false;
+                    defines.UV1 = false;
+                    defines.UV2 = false;
                 }
                 }
 
 
-                this._defines.VERTEXCOLOR = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
+                defines.VERTEXCOLOR = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
 
 
-                this._defines.VERTEXALPHA = mesh.hasVertexAlpha;
+                defines.VERTEXALPHA = mesh.hasVertexAlpha;
 
 
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
+                    defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
                 } else {
                 } else {
-                    this._defines.NUM_BONE_INFLUENCERS = 0;
-                    this._defines.BonesPerMesh = 0;
+                    defines.NUM_BONE_INFLUENCERS = 0;
+                    defines.BonesPerMesh = 0;
                 }
                 }
 
 
                 // Instances
                 // Instances
-                this._defines.INSTANCES = useInstances;
+                defines.INSTANCES = useInstances;
             }
             }
 
 
             // Get correct effect      
             // Get correct effect      
-            if (this._defines._isDirty) {
-                this._defines._isDirty = false;
+            if (defines._isDirty) {
+                defines._isDirty = false;
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();
                 var fallbacks = new EffectFallbacks();
-                if (this._defines.REFLECTION) {
+                if (defines.REFLECTION) {
                     fallbacks.addFallback(0, "REFLECTION");
                     fallbacks.addFallback(0, "REFLECTION");
                 }
                 }
 
 
-                if (this._defines.SPECULAR) {
+                if (defines.SPECULAR) {
                     fallbacks.addFallback(0, "SPECULAR");
                     fallbacks.addFallback(0, "SPECULAR");
                 }
                 }
 
 
-                if (this._defines.BUMP) {
+                if (defines.BUMP) {
                     fallbacks.addFallback(0, "BUMP");
                     fallbacks.addFallback(0, "BUMP");
                 }
                 }
 
 
-                if (this._defines.PARALLAX) {
+                if (defines.PARALLAX) {
                     fallbacks.addFallback(1, "PARALLAX");
                     fallbacks.addFallback(1, "PARALLAX");
                 }
                 }
 
 
-                if (this._defines.PARALLAXOCCLUSION) {
+                if (defines.PARALLAXOCCLUSION) {
                     fallbacks.addFallback(0, "PARALLAXOCCLUSION");
                     fallbacks.addFallback(0, "PARALLAXOCCLUSION");
                 }
                 }
 
 
-                if (this._defines.SPECULAROVERALPHA) {
+                if (defines.SPECULAROVERALPHA) {
                     fallbacks.addFallback(0, "SPECULAROVERALPHA");
                     fallbacks.addFallback(0, "SPECULAROVERALPHA");
                 }
                 }
 
 
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                if (this._defines.POINTSIZE) {
+                if (defines.POINTSIZE) {
                     fallbacks.addFallback(0, "POINTSIZE");
                     fallbacks.addFallback(0, "POINTSIZE");
                 }
                 }
 
 
-                if (this._defines.LOGARITHMICDEPTH) {
+                if (defines.LOGARITHMICDEPTH) {
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
 
 
-                if (this._defines.SPECULARTERM) {
+                if (defines.SPECULARTERM) {
                     fallbacks.addFallback(0, "SPECULARTERM");
                     fallbacks.addFallback(0, "SPECULARTERM");
                 }
                 }
 
 
-                if (this._defines.DIFFUSEFRESNEL) {
+                if (defines.DIFFUSEFRESNEL) {
                     fallbacks.addFallback(1, "DIFFUSEFRESNEL");
                     fallbacks.addFallback(1, "DIFFUSEFRESNEL");
                 }
                 }
 
 
-                if (this._defines.OPACITYFRESNEL) {
+                if (defines.OPACITYFRESNEL) {
                     fallbacks.addFallback(2, "OPACITYFRESNEL");
                     fallbacks.addFallback(2, "OPACITYFRESNEL");
                 }
                 }
 
 
-                if (this._defines.REFLECTIONFRESNEL) {
+                if (defines.REFLECTIONFRESNEL) {
                     fallbacks.addFallback(3, "REFLECTIONFRESNEL");
                     fallbacks.addFallback(3, "REFLECTIONFRESNEL");
                 }
                 }
 
 
-                if (this._defines.EMISSIVEFRESNEL) {
+                if (defines.EMISSIVEFRESNEL) {
                     fallbacks.addFallback(4, "EMISSIVEFRESNEL");
                     fallbacks.addFallback(4, "EMISSIVEFRESNEL");
                 }
                 }
 
 
-                if (this._defines.FRESNEL) {
+                if (defines.FRESNEL) {
                     fallbacks.addFallback(4, "FRESNEL");
                     fallbacks.addFallback(4, "FRESNEL");
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                 }
                 }
 
 
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(VertexBuffer.UV2Kind);
                     attribs.push(VertexBuffer.UV2Kind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 
                 
                 var shaderName = "default";
                 var shaderName = "default";
 
 
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
                     "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
@@ -810,20 +809,20 @@ module BABYLON {
 
 
                 var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"]
                 var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"]
 
 
-                if (this._defines.CAMERACOLORCURVES) {
+                if (defines.CAMERACOLORCURVES) {
                     ColorCurves.PrepareUniforms(uniforms);
                     ColorCurves.PrepareUniforms(uniforms);
                 }
                 }
-                if (this._defines.CAMERACOLORGRADING) {
+                if (defines.CAMERACOLORGRADING) {
                     ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers);
                     ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers);
                 }
                 }
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
 
 
-                this._effect = scene.getEngine().createEffect(shaderName,
+                subMesh.effect = scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
                     attribs, uniforms, samplers,
                     join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
                     join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
             }
             }
 
 
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -836,184 +835,197 @@ module BABYLON {
 
 
         public unbind(): void {
         public unbind(): void {
             if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
             if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
-                this._effect.setTexture("reflection2DSampler", null);
+                this._activeEffect.setTexture("reflection2DSampler", null);
             }
             }
 
 
             if (this._refractionTexture && this._refractionTexture.isRenderTarget) {
             if (this._refractionTexture && this._refractionTexture.isRenderTarget) {
-                this._effect.setTexture("refraction2DSampler", null);
+                this._activeEffect.setTexture("refraction2DSampler", null);
             }
             }
 
 
             super.unbind();
             super.unbind();
         }
         }
 
 
         public bindOnlyWorldMatrix(world: Matrix): void {
         public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
+            this._activeEffect.setMatrix("world", world);
         }
         }
 
 
         public bind(world: Matrix, mesh?: Mesh): void {
         public bind(world: Matrix, mesh?: Mesh): void {
+            if (!mesh) {
+                return;
+            }
+
+            this.bindForSubMesh(world, mesh, mesh.subMeshes[0]);
+        }
+
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <StandardMaterialDefines>subMesh._materialDefines;
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, effect);
 
 
             if (scene.getCachedMaterial() !== this) {
             if (scene.getCachedMaterial() !== this) {
-                this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+                effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
                 if (StandardMaterial.FresnelEnabled) {
                 if (StandardMaterial.FresnelEnabled) {
                     // Fresnel
                     // Fresnel
                     if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
                     if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._effect.setColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
-                        this._effect.setColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
+                        effect.setColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
+                        effect.setColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
                     }
                     }
 
 
                     if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
                     if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
-                        this._effect.setColor4("opacityParts", new Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
+                        effect.setColor4("opacityParts", new Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
                     }
                     }
 
 
                     if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
                     if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        this._effect.setColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
-                        this._effect.setColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
+                        effect.setColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
+                        effect.setColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
                     }
                     }
 
 
                     if (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) {
                     if (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) {
-                        this._effect.setColor4("refractionLeftColor", this.refractionFresnelParameters.leftColor, this.refractionFresnelParameters.power);
-                        this._effect.setColor4("refractionRightColor", this.refractionFresnelParameters.rightColor, this.refractionFresnelParameters.bias);
+                        effect.setColor4("refractionLeftColor", this.refractionFresnelParameters.leftColor, this.refractionFresnelParameters.power);
+                        effect.setColor4("refractionRightColor", this.refractionFresnelParameters.rightColor, this.refractionFresnelParameters.bias);
                     }
                     }
 
 
                     if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
                     if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
-                        this._effect.setColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
-                        this._effect.setColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
+                        effect.setColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
+                        effect.setColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
                     }
                     }
                 }
                 }
 
 
                 // Textures     
                 // Textures     
                 if (scene.texturesEnabled) {
                 if (scene.texturesEnabled) {
                     if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                     if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                        this._effect.setTexture("diffuseSampler", this._diffuseTexture);
+                        effect.setTexture("diffuseSampler", this._diffuseTexture);
 
 
-                        this._effect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
-                        this._effect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
+                        effect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                        effect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                     }
                     }
 
 
                     if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
                     if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
-                        this._effect.setTexture("ambientSampler", this._ambientTexture);
+                        effect.setTexture("ambientSampler", this._ambientTexture);
 
 
-                        this._effect.setFloat2("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level);
-                        this._effect.setMatrix("ambientMatrix", this._ambientTexture.getTextureMatrix());
+                        effect.setFloat2("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level);
+                        effect.setMatrix("ambientMatrix", this._ambientTexture.getTextureMatrix());
                     }
                     }
 
 
                     if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
                     if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
-                        this._effect.setTexture("opacitySampler", this._opacityTexture);
+                        effect.setTexture("opacitySampler", this._opacityTexture);
 
 
-                        this._effect.setFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
-                        this._effect.setMatrix("opacityMatrix", this._opacityTexture.getTextureMatrix());
+                        effect.setFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
+                        effect.setMatrix("opacityMatrix", this._opacityTexture.getTextureMatrix());
                     }
                     }
 
 
                     if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
                     if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
                         if (this._reflectionTexture.isCube) {
                         if (this._reflectionTexture.isCube) {
-                            this._effect.setTexture("reflectionCubeSampler", this._reflectionTexture);
+                            effect.setTexture("reflectionCubeSampler", this._reflectionTexture);
                         } else {
                         } else {
-                            this._effect.setTexture("reflection2DSampler", this._reflectionTexture);
+                            effect.setTexture("reflection2DSampler", this._reflectionTexture);
                         }
                         }
 
 
-                        this._effect.setMatrix("reflectionMatrix", this._reflectionTexture.getReflectionTextureMatrix());
-                        this._effect.setFloat2("vReflectionInfos", this._reflectionTexture.level, this.roughness);
+                        effect.setMatrix("reflectionMatrix", this._reflectionTexture.getReflectionTextureMatrix());
+                        effect.setFloat2("vReflectionInfos", this._reflectionTexture.level, this.roughness);
                     }
                     }
 
 
                     if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
                     if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
-                        this._effect.setTexture("emissiveSampler", this._emissiveTexture);
+                        effect.setTexture("emissiveSampler", this._emissiveTexture);
 
 
-                        this._effect.setFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
-                        this._effect.setMatrix("emissiveMatrix", this._emissiveTexture.getTextureMatrix());
+                        effect.setFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
+                        effect.setMatrix("emissiveMatrix", this._emissiveTexture.getTextureMatrix());
                     }
                     }
 
 
                     if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
                     if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
-                        this._effect.setTexture("lightmapSampler", this._lightmapTexture);
+                        effect.setTexture("lightmapSampler", this._lightmapTexture);
 
 
-                        this._effect.setFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
-                        this._effect.setMatrix("lightmapMatrix", this._lightmapTexture.getTextureMatrix());
+                        effect.setFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
+                        effect.setMatrix("lightmapMatrix", this._lightmapTexture.getTextureMatrix());
                     }
                     }
 
 
                     if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
                     if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
-                        this._effect.setTexture("specularSampler", this._specularTexture);
+                        effect.setTexture("specularSampler", this._specularTexture);
 
 
-                        this._effect.setFloat2("vSpecularInfos", this._specularTexture.coordinatesIndex, this._specularTexture.level);
-                        this._effect.setMatrix("specularMatrix", this._specularTexture.getTextureMatrix());
+                        effect.setFloat2("vSpecularInfos", this._specularTexture.coordinatesIndex, this._specularTexture.level);
+                        effect.setMatrix("specularMatrix", this._specularTexture.getTextureMatrix());
                     }
                     }
 
 
                     if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {
                     if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {
-                        this._effect.setTexture("bumpSampler", this._bumpTexture);
+                        effect.setTexture("bumpSampler", this._bumpTexture);
 
 
-                        this._effect.setFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, 1.0 / this._bumpTexture.level, this.parallaxScaleBias);
-                        this._effect.setMatrix("bumpMatrix", this._bumpTexture.getTextureMatrix());
+                        effect.setFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, 1.0 / this._bumpTexture.level, this.parallaxScaleBias);
+                        effect.setMatrix("bumpMatrix", this._bumpTexture.getTextureMatrix());
                     }
                     }
 
 
                     if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                     if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                         var depth = 1.0;
                         var depth = 1.0;
                         if (this._refractionTexture.isCube) {
                         if (this._refractionTexture.isCube) {
-                            this._effect.setTexture("refractionCubeSampler", this._refractionTexture);
+                            effect.setTexture("refractionCubeSampler", this._refractionTexture);
                         } else {
                         } else {
-                            this._effect.setTexture("refraction2DSampler", this._refractionTexture);
-                            this._effect.setMatrix("refractionMatrix", this._refractionTexture.getReflectionTextureMatrix());
+                            effect.setTexture("refraction2DSampler", this._refractionTexture);
+                            effect.setMatrix("refractionMatrix", this._refractionTexture.getReflectionTextureMatrix());
 
 
                             if ((<any>this._refractionTexture).depth) {
                             if ((<any>this._refractionTexture).depth) {
                                 depth = (<any>this._refractionTexture).depth;
                                 depth = (<any>this._refractionTexture).depth;
                             }
                             }
                         }
                         }
-                        this._effect.setFloat4("vRefractionInfos", this._refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);
+                        effect.setFloat4("vRefractionInfos", this._refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);
                     }
                     }
                     
                     
                     if (this._cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
                     if (this._cameraColorGradingTexture && StandardMaterial.ColorGradingTextureEnabled) {
-                        ColorGradingTexture.Bind(this._cameraColorGradingTexture, this._effect);
+                        ColorGradingTexture.Bind(this._cameraColorGradingTexture, effect);
                     }
                     }
                 }
                 }
 
 
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(effect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    effect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
                 // Colors
                 // Colors
                 scene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
                 scene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
-                this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
+                effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                effect.setColor3("vAmbientColor", this._globalAmbientColor);
 
 
-                if (this._defines.SPECULARTERM) {
-                    this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+                if (defines.SPECULARTERM) {
+                    effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
                 }
                 }
-                this._effect.setColor3("vEmissiveColor", this.emissiveColor);
+                effect.setColor3("vEmissiveColor", this.emissiveColor);
             }
             }
 
 
             if (scene.getCachedMaterial() !== this || !this.isFrozen) {
             if (scene.getCachedMaterial() !== this || !this.isFrozen) {
                 // Diffuse
                 // Diffuse
-                this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+                effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
 
                 // Lights
                 // Lights
                 if (scene.lightsEnabled && !this.disableLighting) {
                 if (scene.lightsEnabled && !this.disableLighting) {
-                    MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                    MaterialHelper.BindLights(scene, mesh, effect, defines, this.maxSimultaneousLights);
                 }
                 }
 
 
                 // View
                 // View
                 if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || this._reflectionTexture || this._refractionTexture) {
                 if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || this._reflectionTexture || this._refractionTexture) {
-                    this._effect.setMatrix("view", scene.getViewMatrix());
+                    effect.setMatrix("view", scene.getViewMatrix());
                 }
                 }
 
 
                 // Fog
                 // Fog
-                MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+                MaterialHelper.BindFogParameters(scene, mesh, effect);
 
 
                 // Log. depth
                 // Log. depth
-                MaterialHelper.BindLogDepth(this._defines, this._effect, scene);
+                MaterialHelper.BindLogDepth(defines, effect, scene);
 
 
                 // Color Curves
                 // Color Curves
                 if (this.cameraColorCurves) {
                 if (this.cameraColorCurves) {
-                    ColorCurves.Bind(this.cameraColorCurves, this._effect);
+                    ColorCurves.Bind(this.cameraColorCurves, effect);
                 }
                 }
             }
             }
 
 
@@ -1120,6 +1132,23 @@ module BABYLON {
             return SerializationHelper.Serialize(this);
             return SerializationHelper.Serialize(this);
         }
         }
 
 
+        private _markAllSubMeshesAsTextureDirty() {
+            for (var mesh of this.getScene().meshes) {
+                if (!mesh.subMeshes) {
+                    continue;
+                }
+                for (var subMesh of mesh.subMeshes) {
+                    if (subMesh.getMaterial() !== this) {
+                        continue;
+                    }
+                    if (!subMesh._materialDefines) {
+                        subMesh._materialDefines = new StandardMaterialDefines();
+                    }
+                    (<StandardMaterialDefines>subMesh._materialDefines)._areTexturesDirty = true;
+                }
+            }
+        }
+
         // Statics
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial {
         public static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial {
             return SerializationHelper.Parse(() => new StandardMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new StandardMaterial(source.name, scene), source, scene, rootUrl);

+ 0 - 1
src/Mesh/babylon.abstractMesh.ts

@@ -207,7 +207,6 @@
         public _positions: Vector3[];
         public _positions: Vector3[];
         private _isDirty = false;
         private _isDirty = false;
         public _masterMesh: AbstractMesh;
         public _masterMesh: AbstractMesh;
-        public _materialDefines: MaterialDefines;
 
 
         public _boundingInfo: BoundingInfo;
         public _boundingInfo: BoundingInfo;
         private _pivotMatrix = Matrix.Identity();
         private _pivotMatrix = Matrix.Identity();

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

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

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

@@ -15,6 +15,17 @@
         public _distanceToCamera: number;
         public _distanceToCamera: number;
         public _id: number;
         public _id: number;
 
 
+        public _materialDefines: MaterialDefines;
+        private _materialEffect: Effect;
+
+        public get effect(): Effect {
+            return this._materialEffect;
+        }
+
+        public set effect(effect: Effect) {
+            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) {
         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._mesh = mesh;
             this._renderingMesh = renderingMesh || <Mesh>mesh;
             this._renderingMesh = renderingMesh || <Mesh>mesh;