浏览代码

standard material is in push mode!

David Catuhe 8 年之前
父节点
当前提交
1b0cf5e915

+ 401 - 359
dist/preview release/babylon.d.ts

@@ -1282,6 +1282,7 @@ declare module BABYLON {
         clearColor: Color4;
         ambientColor: Color3;
         forceWireframe: boolean;
+        private _forcePointsCloud;
         forcePointsCloud: boolean;
         forceShowBoundingBoxes: boolean;
         clipPlane: Plane;
@@ -1429,7 +1430,9 @@ declare module BABYLON {
         * is fog enabled on this scene.
         * @type {boolean}
         */
+        private _fogEnabled;
         fogEnabled: boolean;
+        private _fogMode;
         fogMode: number;
         fogColor: Color3;
         fogDensity: number;
@@ -1481,6 +1484,7 @@ declare module BABYLON {
         spriteManagers: SpriteManager[];
         layers: Layer[];
         highlightLayers: HighlightLayer[];
+        private _skeletonsEnabled;
         skeletonsEnabled: boolean;
         skeletons: Skeleton[];
         lensFlaresEnabled: boolean;
@@ -2272,188 +2276,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class Analyser {
-        SMOOTHING: number;
-        FFT_SIZE: number;
-        BARGRAPHAMPLITUDE: number;
-        DEBUGCANVASPOS: {
-            x: number;
-            y: number;
-        };
-        DEBUGCANVASSIZE: {
-            width: number;
-            height: number;
-        };
-        private _byteFreqs;
-        private _byteTime;
-        private _floatFreqs;
-        private _webAudioAnalyser;
-        private _debugCanvas;
-        private _debugCanvasContext;
-        private _scene;
-        private _registerFunc;
-        private _audioEngine;
-        constructor(scene: Scene);
-        getFrequencyBinCount(): number;
-        getByteFrequencyData(): Uint8Array;
-        getByteTimeDomainData(): Uint8Array;
-        getFloatFrequencyData(): Uint8Array;
-        drawDebugCanvas(): void;
-        stopDebugCanvas(): void;
-        connectAudioNodes(inputAudioNode: AudioNode, outputAudioNode: AudioNode): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class AudioEngine {
-        private _audioContext;
-        private _audioContextInitialized;
-        canUseWebAudio: boolean;
-        masterGain: GainNode;
-        private _connectedAnalyser;
-        WarnedWebAudioUnsupported: boolean;
-        unlocked: boolean;
-        onAudioUnlocked: () => any;
-        isMP3supported: boolean;
-        isOGGsupported: boolean;
-        readonly audioContext: AudioContext;
-        constructor();
-        private _unlockiOSaudio();
-        private _initializeAudioContext();
-        dispose(): void;
-        getGlobalVolume(): number;
-        setGlobalVolume(newVolume: number): void;
-        connectToAnalyser(analyser: Analyser): void;
-    }
-}
-
-declare module BABYLON {
-    class Sound {
-        name: string;
-        autoplay: boolean;
-        loop: boolean;
-        useCustomAttenuation: boolean;
-        soundTrackId: number;
-        spatialSound: boolean;
-        refDistance: number;
-        rolloffFactor: number;
-        maxDistance: number;
-        distanceModel: string;
-        private _panningModel;
-        onended: () => any;
-        private _playbackRate;
-        private _streaming;
-        private _startTime;
-        private _startOffset;
-        private _position;
-        private _localDirection;
-        private _volume;
-        private _isLoaded;
-        private _isReadyToPlay;
-        isPlaying: boolean;
-        isPaused: boolean;
-        private _isDirectional;
-        private _readyToPlayCallback;
-        private _audioBuffer;
-        private _soundSource;
-        private _streamingSource;
-        private _soundPanner;
-        private _soundGain;
-        private _inputAudioNode;
-        private _ouputAudioNode;
-        private _coneInnerAngle;
-        private _coneOuterAngle;
-        private _coneOuterGain;
-        private _scene;
-        private _connectedMesh;
-        private _customAttenuationFunction;
-        private _registerFunc;
-        private _isOutputConnected;
-        private _htmlAudioElement;
-        private _urlType;
-        /**
-        * Create a sound and attach it to a scene
-        * @param name Name of your sound
-        * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer
-        * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
-        * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
-        */
-        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback?: () => void, options?: any);
-        dispose(): void;
-        isReady(): boolean;
-        private _soundLoaded(audioData);
-        setAudioBuffer(audioBuffer: AudioBuffer): void;
-        updateOptions(options: any): void;
-        private _createSpatialParameters();
-        private _updateSpatialParameters();
-        switchPanningModelToHRTF(): void;
-        switchPanningModelToEqualPower(): void;
-        private _switchPanningModel();
-        connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode): void;
-        /**
-        * Transform this sound into a directional source
-        * @param coneInnerAngle Size of the inner cone in degree
-        * @param coneOuterAngle Size of the outer cone in degree
-        * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)
-        */
-        setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): void;
-        setPosition(newPosition: Vector3): void;
-        setLocalDirectionToMesh(newLocalDirection: Vector3): void;
-        private _updateDirection();
-        updateDistanceFromListener(): void;
-        setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number): void;
-        /**
-        * Play the sound
-        * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.
-        * @param offset (optional) Start the sound setting it at a specific time
-        */
-        play(time?: number, offset?: number): void;
-        private _onended();
-        /**
-        * Stop the sound
-        * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.
-        */
-        stop(time?: number): void;
-        pause(): void;
-        setVolume(newVolume: number, time?: number): void;
-        setPlaybackRate(newPlaybackRate: number): void;
-        getVolume(): number;
-        attachToMesh(meshToConnectTo: AbstractMesh): void;
-        detachFromMesh(): void;
-        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
-        clone(): Sound;
-        getAudioBuffer(): AudioBuffer;
-        serialize(): any;
-        static Parse(parsedSound: any, scene: Scene, rootUrl: string, sourceSound?: Sound): Sound;
-    }
-}
-
-declare module BABYLON {
-    class SoundTrack {
-        private _outputAudioNode;
-        private _inputAudioNode;
-        private _trackConvolver;
-        private _scene;
-        id: number;
-        soundCollection: Array<Sound>;
-        private _isMainTrack;
-        private _connectedAnalyser;
-        private _options;
-        private _isInitialized;
-        constructor(scene: Scene, options?: any);
-        private _initializeSoundTrackAudioGraph();
-        dispose(): void;
-        AddSound(sound: Sound): void;
-        RemoveSound(sound: Sound): void;
-        setVolume(newVolume: number): void;
-        switchPanningModelToHRTF(): void;
-        switchPanningModelToEqualPower(): void;
-        connectToAnalyser(analyser: Analyser): void;
-    }
-}
-
-declare module BABYLON {
     class Animatable {
         target: any;
         fromFrame: number;
@@ -2681,6 +2503,188 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class Analyser {
+        SMOOTHING: number;
+        FFT_SIZE: number;
+        BARGRAPHAMPLITUDE: number;
+        DEBUGCANVASPOS: {
+            x: number;
+            y: number;
+        };
+        DEBUGCANVASSIZE: {
+            width: number;
+            height: number;
+        };
+        private _byteFreqs;
+        private _byteTime;
+        private _floatFreqs;
+        private _webAudioAnalyser;
+        private _debugCanvas;
+        private _debugCanvasContext;
+        private _scene;
+        private _registerFunc;
+        private _audioEngine;
+        constructor(scene: Scene);
+        getFrequencyBinCount(): number;
+        getByteFrequencyData(): Uint8Array;
+        getByteTimeDomainData(): Uint8Array;
+        getFloatFrequencyData(): Uint8Array;
+        drawDebugCanvas(): void;
+        stopDebugCanvas(): void;
+        connectAudioNodes(inputAudioNode: AudioNode, outputAudioNode: AudioNode): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class AudioEngine {
+        private _audioContext;
+        private _audioContextInitialized;
+        canUseWebAudio: boolean;
+        masterGain: GainNode;
+        private _connectedAnalyser;
+        WarnedWebAudioUnsupported: boolean;
+        unlocked: boolean;
+        onAudioUnlocked: () => any;
+        isMP3supported: boolean;
+        isOGGsupported: boolean;
+        readonly audioContext: AudioContext;
+        constructor();
+        private _unlockiOSaudio();
+        private _initializeAudioContext();
+        dispose(): void;
+        getGlobalVolume(): number;
+        setGlobalVolume(newVolume: number): void;
+        connectToAnalyser(analyser: Analyser): void;
+    }
+}
+
+declare module BABYLON {
+    class Sound {
+        name: string;
+        autoplay: boolean;
+        loop: boolean;
+        useCustomAttenuation: boolean;
+        soundTrackId: number;
+        spatialSound: boolean;
+        refDistance: number;
+        rolloffFactor: number;
+        maxDistance: number;
+        distanceModel: string;
+        private _panningModel;
+        onended: () => any;
+        private _playbackRate;
+        private _streaming;
+        private _startTime;
+        private _startOffset;
+        private _position;
+        private _localDirection;
+        private _volume;
+        private _isLoaded;
+        private _isReadyToPlay;
+        isPlaying: boolean;
+        isPaused: boolean;
+        private _isDirectional;
+        private _readyToPlayCallback;
+        private _audioBuffer;
+        private _soundSource;
+        private _streamingSource;
+        private _soundPanner;
+        private _soundGain;
+        private _inputAudioNode;
+        private _ouputAudioNode;
+        private _coneInnerAngle;
+        private _coneOuterAngle;
+        private _coneOuterGain;
+        private _scene;
+        private _connectedMesh;
+        private _customAttenuationFunction;
+        private _registerFunc;
+        private _isOutputConnected;
+        private _htmlAudioElement;
+        private _urlType;
+        /**
+        * Create a sound and attach it to a scene
+        * @param name Name of your sound
+        * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer
+        * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
+        * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
+        */
+        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback?: () => void, options?: any);
+        dispose(): void;
+        isReady(): boolean;
+        private _soundLoaded(audioData);
+        setAudioBuffer(audioBuffer: AudioBuffer): void;
+        updateOptions(options: any): void;
+        private _createSpatialParameters();
+        private _updateSpatialParameters();
+        switchPanningModelToHRTF(): void;
+        switchPanningModelToEqualPower(): void;
+        private _switchPanningModel();
+        connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode): void;
+        /**
+        * Transform this sound into a directional source
+        * @param coneInnerAngle Size of the inner cone in degree
+        * @param coneOuterAngle Size of the outer cone in degree
+        * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)
+        */
+        setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): void;
+        setPosition(newPosition: Vector3): void;
+        setLocalDirectionToMesh(newLocalDirection: Vector3): void;
+        private _updateDirection();
+        updateDistanceFromListener(): void;
+        setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number): void;
+        /**
+        * Play the sound
+        * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.
+        * @param offset (optional) Start the sound setting it at a specific time
+        */
+        play(time?: number, offset?: number): void;
+        private _onended();
+        /**
+        * Stop the sound
+        * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.
+        */
+        stop(time?: number): void;
+        pause(): void;
+        setVolume(newVolume: number, time?: number): void;
+        setPlaybackRate(newPlaybackRate: number): void;
+        getVolume(): number;
+        attachToMesh(meshToConnectTo: AbstractMesh): void;
+        detachFromMesh(): void;
+        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
+        clone(): Sound;
+        getAudioBuffer(): AudioBuffer;
+        serialize(): any;
+        static Parse(parsedSound: any, scene: Scene, rootUrl: string, sourceSound?: Sound): Sound;
+    }
+}
+
+declare module BABYLON {
+    class SoundTrack {
+        private _outputAudioNode;
+        private _inputAudioNode;
+        private _trackConvolver;
+        private _scene;
+        id: number;
+        soundCollection: Array<Sound>;
+        private _isMainTrack;
+        private _connectedAnalyser;
+        private _options;
+        private _isInitialized;
+        constructor(scene: Scene, options?: any);
+        private _initializeSoundTrackAudioGraph();
+        dispose(): void;
+        AddSound(sound: Sound): void;
+        RemoveSound(sound: Sound): void;
+        setVolume(newVolume: number): void;
+        switchPanningModelToHRTF(): void;
+        switchPanningModelToEqualPower(): void;
+        connectToAnalyser(analyser: Analyser): void;
+    }
+}
+
+declare module BABYLON {
     class Bone extends Node {
         name: string;
         children: Bone[];
@@ -3828,27 +3832,132 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON {
-    class IntersectionInfo {
-        bu: number;
-        bv: number;
-        distance: number;
-        faceId: number;
-        subMeshId: number;
-        constructor(bu: number, bv: number, distance: number);
-    }
-    class PickingInfo {
-        hit: boolean;
-        distance: number;
-        pickedPoint: Vector3;
-        pickedMesh: AbstractMesh;
-        bu: number;
-        bv: number;
-        faceId: number;
-        subMeshId: number;
-        pickedSprite: Sprite;
-        getNormal(useWorldCoordinates?: boolean, useVerticesNormals?: boolean): Vector3;
-        getTextureCoordinates(): Vector2;
+declare module BABYLON {
+    class IntersectionInfo {
+        bu: number;
+        bv: number;
+        distance: number;
+        faceId: number;
+        subMeshId: number;
+        constructor(bu: number, bv: number, distance: number);
+    }
+    class PickingInfo {
+        hit: boolean;
+        distance: number;
+        pickedPoint: Vector3;
+        pickedMesh: AbstractMesh;
+        bu: number;
+        bv: number;
+        faceId: number;
+        subMeshId: number;
+        pickedSprite: Sprite;
+        getNormal(useWorldCoordinates?: boolean, useVerticesNormals?: boolean): Vector3;
+        getTextureCoordinates(): Vector2;
+    }
+}
+
+declare module BABYLON.Debug {
+    class AxesViewer {
+        private _xline;
+        private _yline;
+        private _zline;
+        private _xmesh;
+        private _ymesh;
+        private _zmesh;
+        scene: Scene;
+        scaleLines: number;
+        constructor(scene: Scene, scaleLines?: number);
+        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    class BoneAxesViewer extends Debug.AxesViewer {
+        mesh: Mesh;
+        bone: Bone;
+        pos: Vector3;
+        xaxis: Vector3;
+        yaxis: Vector3;
+        zaxis: Vector3;
+        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
+        update(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class DebugLayer {
+        private _scene;
+        static InspectorURL: string;
+        private _inspector;
+        constructor(scene: Scene);
+        /** Creates the inspector window. */
+        private _createInspector(config?);
+        isVisible(): boolean;
+        hide(): void;
+        show(config?: {
+            popup?: boolean;
+            initialTab?: number;
+            parentElement?: HTMLElement;
+            newColors?: {
+                backgroundColor?: string;
+                backgroundColorLighter?: string;
+                backgroundColorLighter2?: string;
+                backgroundColorLighter3?: string;
+                color?: string;
+                colorTop?: string;
+                colorBot?: string;
+            };
+        }): void;
+    }
+}
+
+declare module BABYLON {
+    class RayHelper {
+        ray: Ray;
+        private _renderPoints;
+        private _renderLine;
+        private _renderFunction;
+        private _scene;
+        private _updateToMeshFunction;
+        private _attachedToMesh;
+        private _meshSpaceDirection;
+        private _meshSpaceOrigin;
+        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
+        constructor(ray: Ray);
+        show(scene: Scene, color: Color3): void;
+        hide(): void;
+        private _render();
+        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
+        detachFromMesh(): void;
+        private _updateToMesh();
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    /**
+    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
+    */
+    class SkeletonViewer {
+        skeleton: Skeleton;
+        mesh: AbstractMesh;
+        autoUpdateBonesMatrices: boolean;
+        renderingGroupId: number;
+        color: Color3;
+        private _scene;
+        private _debugLines;
+        private _debugMesh;
+        private _isEnabled;
+        private _renderFunction;
+        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
+        isEnabled: boolean;
+        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
+        private _getLinesForBonesWithLength(bones, meshMat);
+        private _getLinesForBonesNoLength(bones, meshMat);
+        update(): void;
+        dispose(): void;
     }
 }
 
@@ -3966,111 +4075,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Debug {
-    class AxesViewer {
-        private _xline;
-        private _yline;
-        private _zline;
-        private _xmesh;
-        private _ymesh;
-        private _zmesh;
-        scene: Scene;
-        scaleLines: number;
-        constructor(scene: Scene, scaleLines?: number);
-        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    class BoneAxesViewer extends Debug.AxesViewer {
-        mesh: Mesh;
-        bone: Bone;
-        pos: Vector3;
-        xaxis: Vector3;
-        yaxis: Vector3;
-        zaxis: Vector3;
-        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
-        update(): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class DebugLayer {
-        private _scene;
-        static InspectorURL: string;
-        private _inspector;
-        constructor(scene: Scene);
-        /** Creates the inspector window. */
-        private _createInspector(config?);
-        isVisible(): boolean;
-        hide(): void;
-        show(config?: {
-            popup?: boolean;
-            initialTab?: number;
-            parentElement?: HTMLElement;
-            newColors?: {
-                backgroundColor?: string;
-                backgroundColorLighter?: string;
-                backgroundColorLighter2?: string;
-                backgroundColorLighter3?: string;
-                color?: string;
-                colorTop?: string;
-                colorBot?: string;
-            };
-        }): void;
-    }
-}
-
-declare module BABYLON {
-    class RayHelper {
-        ray: Ray;
-        private _renderPoints;
-        private _renderLine;
-        private _renderFunction;
-        private _scene;
-        private _updateToMeshFunction;
-        private _attachedToMesh;
-        private _meshSpaceDirection;
-        private _meshSpaceOrigin;
-        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
-        constructor(ray: Ray);
-        show(scene: Scene, color: Color3): void;
-        hide(): void;
-        private _render();
-        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
-        detachFromMesh(): void;
-        private _updateToMesh();
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    /**
-    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
-    */
-    class SkeletonViewer {
-        skeleton: Skeleton;
-        mesh: AbstractMesh;
-        autoUpdateBonesMatrices: boolean;
-        renderingGroupId: number;
-        color: Color3;
-        private _scene;
-        private _debugLines;
-        private _debugMesh;
-        private _isEnabled;
-        private _renderFunction;
-        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
-        isEnabled: boolean;
-        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
-        private _getLinesForBonesWithLength(bones, meshMat);
-        private _getLinesForBonesNoLength(bones, meshMat);
-        update(): void;
-        dispose(): void;
-    }
-}
-
 declare module BABYLON {
     /**
      * Highlight layer options. This helps customizing the behaviour
@@ -4327,51 +4331,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class LensFlare {
-        size: number;
-        position: number;
-        color: Color3;
-        texture: Texture;
-        alphaMode: number;
-        private _system;
-        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
-        dispose: () => void;
-    }
-}
-
-declare module BABYLON {
-    class LensFlareSystem {
-        name: string;
-        lensFlares: LensFlare[];
-        borderLimit: number;
-        viewportBorder: number;
-        meshesSelectionPredicate: (mesh: Mesh) => boolean;
-        layerMask: number;
-        id: string;
-        private _scene;
-        private _emitter;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effect;
-        private _positionX;
-        private _positionY;
-        private _isEnabled;
-        constructor(name: string, emitter: any, scene: Scene);
-        isEnabled: boolean;
-        getScene(): Scene;
-        getEmitter(): any;
-        setEmitter(newEmitter: any): void;
-        getEmitterPosition(): Vector3;
-        computeEffectivePosition(globalViewport: Viewport): boolean;
-        _isVisible(): boolean;
-        render(): boolean;
-        dispose(): void;
-        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
-        serialize(): any;
-    }
-}
-
-declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
         position: Vector3;
         direction: Vector3;
@@ -4756,6 +4715,51 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class LensFlare {
+        size: number;
+        position: number;
+        color: Color3;
+        texture: Texture;
+        alphaMode: number;
+        private _system;
+        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
+        dispose: () => void;
+    }
+}
+
+declare module BABYLON {
+    class LensFlareSystem {
+        name: string;
+        lensFlares: LensFlare[];
+        borderLimit: number;
+        viewportBorder: number;
+        meshesSelectionPredicate: (mesh: Mesh) => boolean;
+        layerMask: number;
+        id: string;
+        private _scene;
+        private _emitter;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effect;
+        private _positionX;
+        private _positionY;
+        private _isEnabled;
+        constructor(name: string, emitter: any, scene: Scene);
+        isEnabled: boolean;
+        getScene(): Scene;
+        getEmitter(): any;
+        setEmitter(newEmitter: any): void;
+        getEmitterPosition(): Vector3;
+        computeEffectivePosition(globalViewport: Viewport): boolean;
+        _isVisible(): boolean;
+        render(): boolean;
+        dispose(): void;
+        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
+        serialize(): any;
+    }
+}
+
+declare module BABYLON {
     interface ISceneLoaderPluginExtensions {
         [extension: string]: {
             isBinary: boolean;
@@ -5157,8 +5161,11 @@ declare module BABYLON {
         _keys: string[];
         _isDirty: boolean;
         _trackIsDirty: boolean;
+        _renderId: number;
         _areLightsDirty: boolean;
+        _areAttributesDirty: boolean;
         _needNormals: boolean;
+        _needUVs: boolean;
         constructor(trackIsDirty?: boolean);
         private _reBind(key);
         rebuild(): void;
@@ -5181,15 +5188,20 @@ declare module BABYLON {
         private static _TextureDirtyFlag;
         private static _LightDirtyFlag;
         private static _FresnelDirtyFlag;
+        private static _AttributesDirtyFlag;
+        private static _MiscDirtyFlag;
         static readonly TextureDirtyFlag: number;
         static readonly LightDirtyFlag: number;
         static readonly FresnelDirtyFlag: number;
+        static readonly AttributesDirtyFlag: number;
+        static readonly MiscDirtyFlag: number;
         id: string;
         name: string;
         checkReadyOnEveryCall: boolean;
         checkReadyOnlyOnce: boolean;
         state: string;
         alpha: number;
+        protected _backFaceCulling: boolean;
         backFaceCulling: boolean;
         sideOrientation: number;
         onCompiled: (effect: Effect) => void;
@@ -5218,6 +5230,7 @@ declare module BABYLON {
         onUnBindObservable: Observable<Material>;
         alphaMode: number;
         disableDepthWrite: boolean;
+        private _fogEnabled;
         fogEnabled: boolean;
         pointSize: number;
         zOffset: number;
@@ -5267,6 +5280,7 @@ declare module BABYLON {
 
 declare module BABYLON {
     class MaterialHelper {
+        static PrepareDefinesForAttributes(mesh: AbstractMesh, defines: MaterialDefines, useInstances: boolean): void;
         static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, maxSimultaneousLights?: number, disableLighting?: boolean): boolean;
         static PrepareUniformsAndSamplersList(uniformsList: string[], samplersList: string[], defines: MaterialDefines, maxSimultaneousLights?: number): void;
         static HandleFallbacksForShadows(defines: MaterialDefines, fallbacks: EffectFallbacks, maxSimultaneousLights?: number): void;
@@ -5724,7 +5738,7 @@ declare module BABYLON {
         CAMERACOLORCURVES: boolean;
         _areTexturesDirty: boolean;
         _areFresnelDirty: boolean;
-        _needUVs: boolean;
+        _areMiscDirty: boolean;
         constructor();
         setReflectionMode(modeToEnable: string): void;
     }
@@ -5752,19 +5766,28 @@ declare module BABYLON {
         specularColor: Color3;
         emissiveColor: Color3;
         specularPower: number;
+        private _useAlphaFromDiffuseTexture;
         useAlphaFromDiffuseTexture: boolean;
+        private _useEmissiveAsIllumination;
         useEmissiveAsIllumination: boolean;
+        private _linkEmissiveWithDiffuse;
         linkEmissiveWithDiffuse: boolean;
+        private _useSpecularOverAlpha;
         useSpecularOverAlpha: boolean;
+        private _useReflectionOverAlpha;
         useReflectionOverAlpha: boolean;
         private _disableLighting;
         disableLighting: boolean;
+        private _useParallax;
         useParallax: boolean;
+        private _useParallaxOcclusion;
         useParallaxOcclusion: boolean;
         parallaxScaleBias: number;
+        private _roughness;
         roughness: number;
         indexOfRefraction: number;
         invertRefractionY: boolean;
+        private _useLightmapAsShadowmap;
         useLightmapAsShadowmap: boolean;
         private _diffuseFresnelParameters;
         diffuseFresnelParameters: FresnelParameters;
@@ -5778,20 +5801,26 @@ declare module BABYLON {
         emissiveFresnelParameters: FresnelParameters;
         private _useReflectionFresnelFromSpecular;
         useReflectionFresnelFromSpecular: boolean;
+        private _useGlossinessFromSpecularMapAlpha;
         useGlossinessFromSpecularMapAlpha: boolean;
+        private _maxSimultaneousLights;
         maxSimultaneousLights: number;
         /**
          * If sets to true, x component of normal map value will invert (x = 1.0 - x).
          */
+        private _invertNormalMapX;
         invertNormalMapX: boolean;
         /**
          * If sets to true, y component of normal map value will invert (y = 1.0 - y).
          */
+        private _invertNormalMapY;
         invertNormalMapY: boolean;
         /**
          * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
          */
+        private _twoSidedLighting;
         twoSidedLighting: boolean;
+        readonly inverttwoSidedLightingNormalMapY: boolean;
         /**
          * Color Grading 2D Lookup Texture.
          * This allows special effects like sepia, black and white to sixties rendering style.
@@ -5804,11 +5833,11 @@ declare module BABYLON {
          * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
          * corresponding to low luminance, medium luminance, and high luminance areas respectively.
          */
+        private _cameraColorCurves;
         cameraColorCurves: ColorCurves;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;
         protected _globalAmbientColor: Color3;
-        protected _renderId: number;
         protected _useLogarithmicDepth: boolean;
         constructor(name: string, scene: Scene);
         private _activeEffect;
@@ -5833,9 +5862,12 @@ declare module BABYLON {
         dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
         clone(name: string): StandardMaterial;
         serialize(): any;
-        private _markAllSubMeshesAsTextureDirty();
+        private _markAllSubMeshesAsDirty(func);
+        private _markAllSubMeshesAsTexturesDirty();
         private _markAllSubMeshesAsFresnelDirty();
-        private _markAllSubMeshesAsLightDirty();
+        private _markAllSubMeshesAsLightsDirty();
+        private _markAllSubMeshesAsAttributesDirty();
+        private _markAllSubMeshesAsMiscDirty();
         static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial;
         static _DiffuseTextureEnabled: boolean;
         static DiffuseTextureEnabled: boolean;
@@ -7957,12 +7989,17 @@ declare module BABYLON {
         renderOverlay: boolean;
         overlayColor: Color3;
         overlayAlpha: number;
+        private _hasVertexAlpha;
         hasVertexAlpha: boolean;
+        private _useVertexColors;
         useVertexColors: boolean;
-        applyFog: boolean;
+        private _computeBonesUsingShaders;
         computeBonesUsingShaders: boolean;
-        scalingDeterminant: number;
+        private _numBoneInfluencers;
         numBoneInfluencers: number;
+        private _applyFog;
+        applyFog: boolean;
+        scalingDeterminant: number;
         useOctreeForRenderingSelection: boolean;
         useOctreeForPicking: boolean;
         useOctreeForCollisions: boolean;
@@ -8028,7 +8065,10 @@ declare module BABYLON {
         _resyncLightSources(): void;
         _resyncLighSource(light: Light): void;
         _removeLightSource(light: Light): void;
+        private _markSubMeshesAsDirty(func);
         _markSubMeshesAsLightDirty(): void;
+        _markSubMeshesAsAttributesDirty(): void;
+        _markSubMeshesAsMiscDirty(): void;
         /**
          * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z.
          * If rotation quaternion is set, this Vector3 will (almost always) be the Zero vector!
@@ -14666,10 +14706,12 @@ declare module BABYLON.Internals {
 declare module BABYLON {
     class BaseTexture {
         name: string;
+        private _hasAlpha;
         hasAlpha: boolean;
         getAlphaFromRGB: boolean;
         level: number;
         coordinatesIndex: number;
+        private _coordinatesMode;
         coordinatesMode: number;
         wrapU: number;
         wrapV: number;

+ 401 - 359
dist/preview release/babylon.module.d.ts

@@ -1282,6 +1282,7 @@ declare module BABYLON {
         clearColor: Color4;
         ambientColor: Color3;
         forceWireframe: boolean;
+        private _forcePointsCloud;
         forcePointsCloud: boolean;
         forceShowBoundingBoxes: boolean;
         clipPlane: Plane;
@@ -1429,7 +1430,9 @@ declare module BABYLON {
         * is fog enabled on this scene.
         * @type {boolean}
         */
+        private _fogEnabled;
         fogEnabled: boolean;
+        private _fogMode;
         fogMode: number;
         fogColor: Color3;
         fogDensity: number;
@@ -1481,6 +1484,7 @@ declare module BABYLON {
         spriteManagers: SpriteManager[];
         layers: Layer[];
         highlightLayers: HighlightLayer[];
+        private _skeletonsEnabled;
         skeletonsEnabled: boolean;
         skeletons: Skeleton[];
         lensFlaresEnabled: boolean;
@@ -2272,188 +2276,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class Analyser {
-        SMOOTHING: number;
-        FFT_SIZE: number;
-        BARGRAPHAMPLITUDE: number;
-        DEBUGCANVASPOS: {
-            x: number;
-            y: number;
-        };
-        DEBUGCANVASSIZE: {
-            width: number;
-            height: number;
-        };
-        private _byteFreqs;
-        private _byteTime;
-        private _floatFreqs;
-        private _webAudioAnalyser;
-        private _debugCanvas;
-        private _debugCanvasContext;
-        private _scene;
-        private _registerFunc;
-        private _audioEngine;
-        constructor(scene: Scene);
-        getFrequencyBinCount(): number;
-        getByteFrequencyData(): Uint8Array;
-        getByteTimeDomainData(): Uint8Array;
-        getFloatFrequencyData(): Uint8Array;
-        drawDebugCanvas(): void;
-        stopDebugCanvas(): void;
-        connectAudioNodes(inputAudioNode: AudioNode, outputAudioNode: AudioNode): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class AudioEngine {
-        private _audioContext;
-        private _audioContextInitialized;
-        canUseWebAudio: boolean;
-        masterGain: GainNode;
-        private _connectedAnalyser;
-        WarnedWebAudioUnsupported: boolean;
-        unlocked: boolean;
-        onAudioUnlocked: () => any;
-        isMP3supported: boolean;
-        isOGGsupported: boolean;
-        readonly audioContext: AudioContext;
-        constructor();
-        private _unlockiOSaudio();
-        private _initializeAudioContext();
-        dispose(): void;
-        getGlobalVolume(): number;
-        setGlobalVolume(newVolume: number): void;
-        connectToAnalyser(analyser: Analyser): void;
-    }
-}
-
-declare module BABYLON {
-    class Sound {
-        name: string;
-        autoplay: boolean;
-        loop: boolean;
-        useCustomAttenuation: boolean;
-        soundTrackId: number;
-        spatialSound: boolean;
-        refDistance: number;
-        rolloffFactor: number;
-        maxDistance: number;
-        distanceModel: string;
-        private _panningModel;
-        onended: () => any;
-        private _playbackRate;
-        private _streaming;
-        private _startTime;
-        private _startOffset;
-        private _position;
-        private _localDirection;
-        private _volume;
-        private _isLoaded;
-        private _isReadyToPlay;
-        isPlaying: boolean;
-        isPaused: boolean;
-        private _isDirectional;
-        private _readyToPlayCallback;
-        private _audioBuffer;
-        private _soundSource;
-        private _streamingSource;
-        private _soundPanner;
-        private _soundGain;
-        private _inputAudioNode;
-        private _ouputAudioNode;
-        private _coneInnerAngle;
-        private _coneOuterAngle;
-        private _coneOuterGain;
-        private _scene;
-        private _connectedMesh;
-        private _customAttenuationFunction;
-        private _registerFunc;
-        private _isOutputConnected;
-        private _htmlAudioElement;
-        private _urlType;
-        /**
-        * Create a sound and attach it to a scene
-        * @param name Name of your sound
-        * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer
-        * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
-        * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
-        */
-        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback?: () => void, options?: any);
-        dispose(): void;
-        isReady(): boolean;
-        private _soundLoaded(audioData);
-        setAudioBuffer(audioBuffer: AudioBuffer): void;
-        updateOptions(options: any): void;
-        private _createSpatialParameters();
-        private _updateSpatialParameters();
-        switchPanningModelToHRTF(): void;
-        switchPanningModelToEqualPower(): void;
-        private _switchPanningModel();
-        connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode): void;
-        /**
-        * Transform this sound into a directional source
-        * @param coneInnerAngle Size of the inner cone in degree
-        * @param coneOuterAngle Size of the outer cone in degree
-        * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)
-        */
-        setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): void;
-        setPosition(newPosition: Vector3): void;
-        setLocalDirectionToMesh(newLocalDirection: Vector3): void;
-        private _updateDirection();
-        updateDistanceFromListener(): void;
-        setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number): void;
-        /**
-        * Play the sound
-        * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.
-        * @param offset (optional) Start the sound setting it at a specific time
-        */
-        play(time?: number, offset?: number): void;
-        private _onended();
-        /**
-        * Stop the sound
-        * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.
-        */
-        stop(time?: number): void;
-        pause(): void;
-        setVolume(newVolume: number, time?: number): void;
-        setPlaybackRate(newPlaybackRate: number): void;
-        getVolume(): number;
-        attachToMesh(meshToConnectTo: AbstractMesh): void;
-        detachFromMesh(): void;
-        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
-        clone(): Sound;
-        getAudioBuffer(): AudioBuffer;
-        serialize(): any;
-        static Parse(parsedSound: any, scene: Scene, rootUrl: string, sourceSound?: Sound): Sound;
-    }
-}
-
-declare module BABYLON {
-    class SoundTrack {
-        private _outputAudioNode;
-        private _inputAudioNode;
-        private _trackConvolver;
-        private _scene;
-        id: number;
-        soundCollection: Array<Sound>;
-        private _isMainTrack;
-        private _connectedAnalyser;
-        private _options;
-        private _isInitialized;
-        constructor(scene: Scene, options?: any);
-        private _initializeSoundTrackAudioGraph();
-        dispose(): void;
-        AddSound(sound: Sound): void;
-        RemoveSound(sound: Sound): void;
-        setVolume(newVolume: number): void;
-        switchPanningModelToHRTF(): void;
-        switchPanningModelToEqualPower(): void;
-        connectToAnalyser(analyser: Analyser): void;
-    }
-}
-
-declare module BABYLON {
     class Animatable {
         target: any;
         fromFrame: number;
@@ -2681,6 +2503,188 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class Analyser {
+        SMOOTHING: number;
+        FFT_SIZE: number;
+        BARGRAPHAMPLITUDE: number;
+        DEBUGCANVASPOS: {
+            x: number;
+            y: number;
+        };
+        DEBUGCANVASSIZE: {
+            width: number;
+            height: number;
+        };
+        private _byteFreqs;
+        private _byteTime;
+        private _floatFreqs;
+        private _webAudioAnalyser;
+        private _debugCanvas;
+        private _debugCanvasContext;
+        private _scene;
+        private _registerFunc;
+        private _audioEngine;
+        constructor(scene: Scene);
+        getFrequencyBinCount(): number;
+        getByteFrequencyData(): Uint8Array;
+        getByteTimeDomainData(): Uint8Array;
+        getFloatFrequencyData(): Uint8Array;
+        drawDebugCanvas(): void;
+        stopDebugCanvas(): void;
+        connectAudioNodes(inputAudioNode: AudioNode, outputAudioNode: AudioNode): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class AudioEngine {
+        private _audioContext;
+        private _audioContextInitialized;
+        canUseWebAudio: boolean;
+        masterGain: GainNode;
+        private _connectedAnalyser;
+        WarnedWebAudioUnsupported: boolean;
+        unlocked: boolean;
+        onAudioUnlocked: () => any;
+        isMP3supported: boolean;
+        isOGGsupported: boolean;
+        readonly audioContext: AudioContext;
+        constructor();
+        private _unlockiOSaudio();
+        private _initializeAudioContext();
+        dispose(): void;
+        getGlobalVolume(): number;
+        setGlobalVolume(newVolume: number): void;
+        connectToAnalyser(analyser: Analyser): void;
+    }
+}
+
+declare module BABYLON {
+    class Sound {
+        name: string;
+        autoplay: boolean;
+        loop: boolean;
+        useCustomAttenuation: boolean;
+        soundTrackId: number;
+        spatialSound: boolean;
+        refDistance: number;
+        rolloffFactor: number;
+        maxDistance: number;
+        distanceModel: string;
+        private _panningModel;
+        onended: () => any;
+        private _playbackRate;
+        private _streaming;
+        private _startTime;
+        private _startOffset;
+        private _position;
+        private _localDirection;
+        private _volume;
+        private _isLoaded;
+        private _isReadyToPlay;
+        isPlaying: boolean;
+        isPaused: boolean;
+        private _isDirectional;
+        private _readyToPlayCallback;
+        private _audioBuffer;
+        private _soundSource;
+        private _streamingSource;
+        private _soundPanner;
+        private _soundGain;
+        private _inputAudioNode;
+        private _ouputAudioNode;
+        private _coneInnerAngle;
+        private _coneOuterAngle;
+        private _coneOuterGain;
+        private _scene;
+        private _connectedMesh;
+        private _customAttenuationFunction;
+        private _registerFunc;
+        private _isOutputConnected;
+        private _htmlAudioElement;
+        private _urlType;
+        /**
+        * Create a sound and attach it to a scene
+        * @param name Name of your sound
+        * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer
+        * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
+        * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
+        */
+        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback?: () => void, options?: any);
+        dispose(): void;
+        isReady(): boolean;
+        private _soundLoaded(audioData);
+        setAudioBuffer(audioBuffer: AudioBuffer): void;
+        updateOptions(options: any): void;
+        private _createSpatialParameters();
+        private _updateSpatialParameters();
+        switchPanningModelToHRTF(): void;
+        switchPanningModelToEqualPower(): void;
+        private _switchPanningModel();
+        connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode): void;
+        /**
+        * Transform this sound into a directional source
+        * @param coneInnerAngle Size of the inner cone in degree
+        * @param coneOuterAngle Size of the outer cone in degree
+        * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)
+        */
+        setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): void;
+        setPosition(newPosition: Vector3): void;
+        setLocalDirectionToMesh(newLocalDirection: Vector3): void;
+        private _updateDirection();
+        updateDistanceFromListener(): void;
+        setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number): void;
+        /**
+        * Play the sound
+        * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.
+        * @param offset (optional) Start the sound setting it at a specific time
+        */
+        play(time?: number, offset?: number): void;
+        private _onended();
+        /**
+        * Stop the sound
+        * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.
+        */
+        stop(time?: number): void;
+        pause(): void;
+        setVolume(newVolume: number, time?: number): void;
+        setPlaybackRate(newPlaybackRate: number): void;
+        getVolume(): number;
+        attachToMesh(meshToConnectTo: AbstractMesh): void;
+        detachFromMesh(): void;
+        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
+        clone(): Sound;
+        getAudioBuffer(): AudioBuffer;
+        serialize(): any;
+        static Parse(parsedSound: any, scene: Scene, rootUrl: string, sourceSound?: Sound): Sound;
+    }
+}
+
+declare module BABYLON {
+    class SoundTrack {
+        private _outputAudioNode;
+        private _inputAudioNode;
+        private _trackConvolver;
+        private _scene;
+        id: number;
+        soundCollection: Array<Sound>;
+        private _isMainTrack;
+        private _connectedAnalyser;
+        private _options;
+        private _isInitialized;
+        constructor(scene: Scene, options?: any);
+        private _initializeSoundTrackAudioGraph();
+        dispose(): void;
+        AddSound(sound: Sound): void;
+        RemoveSound(sound: Sound): void;
+        setVolume(newVolume: number): void;
+        switchPanningModelToHRTF(): void;
+        switchPanningModelToEqualPower(): void;
+        connectToAnalyser(analyser: Analyser): void;
+    }
+}
+
+declare module BABYLON {
     class Bone extends Node {
         name: string;
         children: Bone[];
@@ -3828,27 +3832,132 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON {
-    class IntersectionInfo {
-        bu: number;
-        bv: number;
-        distance: number;
-        faceId: number;
-        subMeshId: number;
-        constructor(bu: number, bv: number, distance: number);
-    }
-    class PickingInfo {
-        hit: boolean;
-        distance: number;
-        pickedPoint: Vector3;
-        pickedMesh: AbstractMesh;
-        bu: number;
-        bv: number;
-        faceId: number;
-        subMeshId: number;
-        pickedSprite: Sprite;
-        getNormal(useWorldCoordinates?: boolean, useVerticesNormals?: boolean): Vector3;
-        getTextureCoordinates(): Vector2;
+declare module BABYLON {
+    class IntersectionInfo {
+        bu: number;
+        bv: number;
+        distance: number;
+        faceId: number;
+        subMeshId: number;
+        constructor(bu: number, bv: number, distance: number);
+    }
+    class PickingInfo {
+        hit: boolean;
+        distance: number;
+        pickedPoint: Vector3;
+        pickedMesh: AbstractMesh;
+        bu: number;
+        bv: number;
+        faceId: number;
+        subMeshId: number;
+        pickedSprite: Sprite;
+        getNormal(useWorldCoordinates?: boolean, useVerticesNormals?: boolean): Vector3;
+        getTextureCoordinates(): Vector2;
+    }
+}
+
+declare module BABYLON.Debug {
+    class AxesViewer {
+        private _xline;
+        private _yline;
+        private _zline;
+        private _xmesh;
+        private _ymesh;
+        private _zmesh;
+        scene: Scene;
+        scaleLines: number;
+        constructor(scene: Scene, scaleLines?: number);
+        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    class BoneAxesViewer extends Debug.AxesViewer {
+        mesh: Mesh;
+        bone: Bone;
+        pos: Vector3;
+        xaxis: Vector3;
+        yaxis: Vector3;
+        zaxis: Vector3;
+        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
+        update(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class DebugLayer {
+        private _scene;
+        static InspectorURL: string;
+        private _inspector;
+        constructor(scene: Scene);
+        /** Creates the inspector window. */
+        private _createInspector(config?);
+        isVisible(): boolean;
+        hide(): void;
+        show(config?: {
+            popup?: boolean;
+            initialTab?: number;
+            parentElement?: HTMLElement;
+            newColors?: {
+                backgroundColor?: string;
+                backgroundColorLighter?: string;
+                backgroundColorLighter2?: string;
+                backgroundColorLighter3?: string;
+                color?: string;
+                colorTop?: string;
+                colorBot?: string;
+            };
+        }): void;
+    }
+}
+
+declare module BABYLON {
+    class RayHelper {
+        ray: Ray;
+        private _renderPoints;
+        private _renderLine;
+        private _renderFunction;
+        private _scene;
+        private _updateToMeshFunction;
+        private _attachedToMesh;
+        private _meshSpaceDirection;
+        private _meshSpaceOrigin;
+        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
+        constructor(ray: Ray);
+        show(scene: Scene, color: Color3): void;
+        hide(): void;
+        private _render();
+        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
+        detachFromMesh(): void;
+        private _updateToMesh();
+        dispose(): void;
+    }
+}
+
+declare module BABYLON.Debug {
+    /**
+    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
+    */
+    class SkeletonViewer {
+        skeleton: Skeleton;
+        mesh: AbstractMesh;
+        autoUpdateBonesMatrices: boolean;
+        renderingGroupId: number;
+        color: Color3;
+        private _scene;
+        private _debugLines;
+        private _debugMesh;
+        private _isEnabled;
+        private _renderFunction;
+        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
+        isEnabled: boolean;
+        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
+        private _getLinesForBonesWithLength(bones, meshMat);
+        private _getLinesForBonesNoLength(bones, meshMat);
+        update(): void;
+        dispose(): void;
     }
 }
 
@@ -3966,111 +4075,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Debug {
-    class AxesViewer {
-        private _xline;
-        private _yline;
-        private _zline;
-        private _xmesh;
-        private _ymesh;
-        private _zmesh;
-        scene: Scene;
-        scaleLines: number;
-        constructor(scene: Scene, scaleLines?: number);
-        update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    class BoneAxesViewer extends Debug.AxesViewer {
-        mesh: Mesh;
-        bone: Bone;
-        pos: Vector3;
-        xaxis: Vector3;
-        yaxis: Vector3;
-        zaxis: Vector3;
-        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines?: number);
-        update(): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class DebugLayer {
-        private _scene;
-        static InspectorURL: string;
-        private _inspector;
-        constructor(scene: Scene);
-        /** Creates the inspector window. */
-        private _createInspector(config?);
-        isVisible(): boolean;
-        hide(): void;
-        show(config?: {
-            popup?: boolean;
-            initialTab?: number;
-            parentElement?: HTMLElement;
-            newColors?: {
-                backgroundColor?: string;
-                backgroundColorLighter?: string;
-                backgroundColorLighter2?: string;
-                backgroundColorLighter3?: string;
-                color?: string;
-                colorTop?: string;
-                colorBot?: string;
-            };
-        }): void;
-    }
-}
-
-declare module BABYLON {
-    class RayHelper {
-        ray: Ray;
-        private _renderPoints;
-        private _renderLine;
-        private _renderFunction;
-        private _scene;
-        private _updateToMeshFunction;
-        private _attachedToMesh;
-        private _meshSpaceDirection;
-        private _meshSpaceOrigin;
-        static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper;
-        constructor(ray: Ray);
-        show(scene: Scene, color: Color3): void;
-        hide(): void;
-        private _render();
-        attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void;
-        detachFromMesh(): void;
-        private _updateToMesh();
-        dispose(): void;
-    }
-}
-
-declare module BABYLON.Debug {
-    /**
-    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
-    */
-    class SkeletonViewer {
-        skeleton: Skeleton;
-        mesh: AbstractMesh;
-        autoUpdateBonesMatrices: boolean;
-        renderingGroupId: number;
-        color: Color3;
-        private _scene;
-        private _debugLines;
-        private _debugMesh;
-        private _isEnabled;
-        private _renderFunction;
-        constructor(skeleton: Skeleton, mesh: AbstractMesh, scene: Scene, autoUpdateBonesMatrices?: boolean, renderingGroupId?: number);
-        isEnabled: boolean;
-        private _getBonePosition(position, bone, meshMat, x?, y?, z?);
-        private _getLinesForBonesWithLength(bones, meshMat);
-        private _getLinesForBonesNoLength(bones, meshMat);
-        update(): void;
-        dispose(): void;
-    }
-}
-
 declare module BABYLON {
     /**
      * Highlight layer options. This helps customizing the behaviour
@@ -4327,51 +4331,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class LensFlare {
-        size: number;
-        position: number;
-        color: Color3;
-        texture: Texture;
-        alphaMode: number;
-        private _system;
-        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
-        dispose: () => void;
-    }
-}
-
-declare module BABYLON {
-    class LensFlareSystem {
-        name: string;
-        lensFlares: LensFlare[];
-        borderLimit: number;
-        viewportBorder: number;
-        meshesSelectionPredicate: (mesh: Mesh) => boolean;
-        layerMask: number;
-        id: string;
-        private _scene;
-        private _emitter;
-        private _vertexBuffers;
-        private _indexBuffer;
-        private _effect;
-        private _positionX;
-        private _positionY;
-        private _isEnabled;
-        constructor(name: string, emitter: any, scene: Scene);
-        isEnabled: boolean;
-        getScene(): Scene;
-        getEmitter(): any;
-        setEmitter(newEmitter: any): void;
-        getEmitterPosition(): Vector3;
-        computeEffectivePosition(globalViewport: Viewport): boolean;
-        _isVisible(): boolean;
-        render(): boolean;
-        dispose(): void;
-        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
-        serialize(): any;
-    }
-}
-
-declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
         position: Vector3;
         direction: Vector3;
@@ -4756,6 +4715,51 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class LensFlare {
+        size: number;
+        position: number;
+        color: Color3;
+        texture: Texture;
+        alphaMode: number;
+        private _system;
+        constructor(size: number, position: number, color: any, imgUrl: string, system: LensFlareSystem);
+        dispose: () => void;
+    }
+}
+
+declare module BABYLON {
+    class LensFlareSystem {
+        name: string;
+        lensFlares: LensFlare[];
+        borderLimit: number;
+        viewportBorder: number;
+        meshesSelectionPredicate: (mesh: Mesh) => boolean;
+        layerMask: number;
+        id: string;
+        private _scene;
+        private _emitter;
+        private _vertexBuffers;
+        private _indexBuffer;
+        private _effect;
+        private _positionX;
+        private _positionY;
+        private _isEnabled;
+        constructor(name: string, emitter: any, scene: Scene);
+        isEnabled: boolean;
+        getScene(): Scene;
+        getEmitter(): any;
+        setEmitter(newEmitter: any): void;
+        getEmitterPosition(): Vector3;
+        computeEffectivePosition(globalViewport: Viewport): boolean;
+        _isVisible(): boolean;
+        render(): boolean;
+        dispose(): void;
+        static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem;
+        serialize(): any;
+    }
+}
+
+declare module BABYLON {
     interface ISceneLoaderPluginExtensions {
         [extension: string]: {
             isBinary: boolean;
@@ -5157,8 +5161,11 @@ declare module BABYLON {
         _keys: string[];
         _isDirty: boolean;
         _trackIsDirty: boolean;
+        _renderId: number;
         _areLightsDirty: boolean;
+        _areAttributesDirty: boolean;
         _needNormals: boolean;
+        _needUVs: boolean;
         constructor(trackIsDirty?: boolean);
         private _reBind(key);
         rebuild(): void;
@@ -5181,15 +5188,20 @@ declare module BABYLON {
         private static _TextureDirtyFlag;
         private static _LightDirtyFlag;
         private static _FresnelDirtyFlag;
+        private static _AttributesDirtyFlag;
+        private static _MiscDirtyFlag;
         static readonly TextureDirtyFlag: number;
         static readonly LightDirtyFlag: number;
         static readonly FresnelDirtyFlag: number;
+        static readonly AttributesDirtyFlag: number;
+        static readonly MiscDirtyFlag: number;
         id: string;
         name: string;
         checkReadyOnEveryCall: boolean;
         checkReadyOnlyOnce: boolean;
         state: string;
         alpha: number;
+        protected _backFaceCulling: boolean;
         backFaceCulling: boolean;
         sideOrientation: number;
         onCompiled: (effect: Effect) => void;
@@ -5218,6 +5230,7 @@ declare module BABYLON {
         onUnBindObservable: Observable<Material>;
         alphaMode: number;
         disableDepthWrite: boolean;
+        private _fogEnabled;
         fogEnabled: boolean;
         pointSize: number;
         zOffset: number;
@@ -5267,6 +5280,7 @@ declare module BABYLON {
 
 declare module BABYLON {
     class MaterialHelper {
+        static PrepareDefinesForAttributes(mesh: AbstractMesh, defines: MaterialDefines, useInstances: boolean): void;
         static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, maxSimultaneousLights?: number, disableLighting?: boolean): boolean;
         static PrepareUniformsAndSamplersList(uniformsList: string[], samplersList: string[], defines: MaterialDefines, maxSimultaneousLights?: number): void;
         static HandleFallbacksForShadows(defines: MaterialDefines, fallbacks: EffectFallbacks, maxSimultaneousLights?: number): void;
@@ -5724,7 +5738,7 @@ declare module BABYLON {
         CAMERACOLORCURVES: boolean;
         _areTexturesDirty: boolean;
         _areFresnelDirty: boolean;
-        _needUVs: boolean;
+        _areMiscDirty: boolean;
         constructor();
         setReflectionMode(modeToEnable: string): void;
     }
@@ -5752,19 +5766,28 @@ declare module BABYLON {
         specularColor: Color3;
         emissiveColor: Color3;
         specularPower: number;
+        private _useAlphaFromDiffuseTexture;
         useAlphaFromDiffuseTexture: boolean;
+        private _useEmissiveAsIllumination;
         useEmissiveAsIllumination: boolean;
+        private _linkEmissiveWithDiffuse;
         linkEmissiveWithDiffuse: boolean;
+        private _useSpecularOverAlpha;
         useSpecularOverAlpha: boolean;
+        private _useReflectionOverAlpha;
         useReflectionOverAlpha: boolean;
         private _disableLighting;
         disableLighting: boolean;
+        private _useParallax;
         useParallax: boolean;
+        private _useParallaxOcclusion;
         useParallaxOcclusion: boolean;
         parallaxScaleBias: number;
+        private _roughness;
         roughness: number;
         indexOfRefraction: number;
         invertRefractionY: boolean;
+        private _useLightmapAsShadowmap;
         useLightmapAsShadowmap: boolean;
         private _diffuseFresnelParameters;
         diffuseFresnelParameters: FresnelParameters;
@@ -5778,20 +5801,26 @@ declare module BABYLON {
         emissiveFresnelParameters: FresnelParameters;
         private _useReflectionFresnelFromSpecular;
         useReflectionFresnelFromSpecular: boolean;
+        private _useGlossinessFromSpecularMapAlpha;
         useGlossinessFromSpecularMapAlpha: boolean;
+        private _maxSimultaneousLights;
         maxSimultaneousLights: number;
         /**
          * If sets to true, x component of normal map value will invert (x = 1.0 - x).
          */
+        private _invertNormalMapX;
         invertNormalMapX: boolean;
         /**
          * If sets to true, y component of normal map value will invert (y = 1.0 - y).
          */
+        private _invertNormalMapY;
         invertNormalMapY: boolean;
         /**
          * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
          */
+        private _twoSidedLighting;
         twoSidedLighting: boolean;
+        readonly inverttwoSidedLightingNormalMapY: boolean;
         /**
          * Color Grading 2D Lookup Texture.
          * This allows special effects like sepia, black and white to sixties rendering style.
@@ -5804,11 +5833,11 @@ declare module BABYLON {
          * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
          * corresponding to low luminance, medium luminance, and high luminance areas respectively.
          */
+        private _cameraColorCurves;
         cameraColorCurves: ColorCurves;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;
         protected _globalAmbientColor: Color3;
-        protected _renderId: number;
         protected _useLogarithmicDepth: boolean;
         constructor(name: string, scene: Scene);
         private _activeEffect;
@@ -5833,9 +5862,12 @@ declare module BABYLON {
         dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
         clone(name: string): StandardMaterial;
         serialize(): any;
-        private _markAllSubMeshesAsTextureDirty();
+        private _markAllSubMeshesAsDirty(func);
+        private _markAllSubMeshesAsTexturesDirty();
         private _markAllSubMeshesAsFresnelDirty();
-        private _markAllSubMeshesAsLightDirty();
+        private _markAllSubMeshesAsLightsDirty();
+        private _markAllSubMeshesAsAttributesDirty();
+        private _markAllSubMeshesAsMiscDirty();
         static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial;
         static _DiffuseTextureEnabled: boolean;
         static DiffuseTextureEnabled: boolean;
@@ -7957,12 +7989,17 @@ declare module BABYLON {
         renderOverlay: boolean;
         overlayColor: Color3;
         overlayAlpha: number;
+        private _hasVertexAlpha;
         hasVertexAlpha: boolean;
+        private _useVertexColors;
         useVertexColors: boolean;
-        applyFog: boolean;
+        private _computeBonesUsingShaders;
         computeBonesUsingShaders: boolean;
-        scalingDeterminant: number;
+        private _numBoneInfluencers;
         numBoneInfluencers: number;
+        private _applyFog;
+        applyFog: boolean;
+        scalingDeterminant: number;
         useOctreeForRenderingSelection: boolean;
         useOctreeForPicking: boolean;
         useOctreeForCollisions: boolean;
@@ -8028,7 +8065,10 @@ declare module BABYLON {
         _resyncLightSources(): void;
         _resyncLighSource(light: Light): void;
         _removeLightSource(light: Light): void;
+        private _markSubMeshesAsDirty(func);
         _markSubMeshesAsLightDirty(): void;
+        _markSubMeshesAsAttributesDirty(): void;
+        _markSubMeshesAsMiscDirty(): void;
         /**
          * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z.
          * If rotation quaternion is set, this Vector3 will (almost always) be the Zero vector!
@@ -14666,10 +14706,12 @@ declare module BABYLON.Internals {
 declare module BABYLON {
     class BaseTexture {
         name: string;
+        private _hasAlpha;
         hasAlpha: boolean;
         getAlphaFromRGB: boolean;
         level: number;
         coordinatesIndex: number;
+        private _coordinatesMode;
         coordinatesMode: number;
         wrapU: number;
         wrapV: number;

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

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

+ 43 - 5
src/Materials/babylon.material.ts

@@ -4,8 +4,11 @@
         _isDirty = true;
         _trackIsDirty = false;    
 
+        public _renderId: number;
         public _areLightsDirty = true;
+        public _areAttributesDirty = true;
         public _needNormals = false;
+        public _needUVs = false;
 
         constructor(trackIsDirty?: boolean) {
             this._trackIsDirty = trackIsDirty;
@@ -146,6 +149,8 @@
         private static _TextureDirtyFlag = 0;
         private static _LightDirtyFlag = 1;
         private static _FresnelDirtyFlag = 2;
+        private static _AttributesDirtyFlag = 4;
+        private static _MiscDirtyFlag = 8;
 
         public static get TextureDirtyFlag(): number {
             return Material._TextureDirtyFlag;
@@ -159,6 +164,14 @@
             return Material._FresnelDirtyFlag;
         }
 
+        public static get AttributesDirtyFlag(): number {
+            return Material._AttributesDirtyFlag;
+        }
+
+        public static get MiscDirtyFlag(): number {
+            return Material._MiscDirtyFlag;
+        }
+
         @serialize()
         public id: string;
 
@@ -177,8 +190,18 @@
         @serialize()
         public alpha = 1.0;
 
-        @serialize()
-        public backFaceCulling = true;
+        @serialize("backFaceCulling")
+        protected _backFaceCulling = true;
+        public set backFaceCulling(value : boolean) {
+            if (this._backFaceCulling === value) {
+                return;
+            }
+            this._backFaceCulling = value;
+            this.markAsDirty(Material.TextureDirtyFlag);
+        }
+        public get backFaceCulling(): boolean {
+            return this._backFaceCulling;
+        }          
 
         @serialize()
         public sideOrientation: number;
@@ -232,8 +255,18 @@
         @serialize()
         public disableDepthWrite = false;
 
-        @serialize()
-        public fogEnabled = true;
+        @serialize("fogEnabled")
+        private _fogEnabled = true;
+        public set fogEnabled(value : boolean) {
+            if (this._fogEnabled === value) {
+                return;
+            }
+            this._fogEnabled = value;
+            this.markAsDirty(Material.MiscDirtyFlag);
+        }
+        public get fogEnabled(): boolean {
+            return this._fogEnabled;
+        }         
 
         @serialize()
         public pointSize = 1.0;
@@ -256,7 +289,7 @@
         }
 
         public set pointsCloud(value: boolean) {
-            this._fillMode = (value ? Material.PointFillMode : Material.TriangleFillMode);
+            this._fillMode = (value ? Material.PointFillMode : Material.TriangleFillMode);            
         }
 
         @serialize()
@@ -265,7 +298,12 @@
         }
 
         public set fillMode(value: number) {
+            if (this._fillMode === value) {
+                return;
+            }
+
             this._fillMode = value;
+            this.markAsDirty(Material.MiscDirtyFlag);
         }
 
         public _effect: Effect;

+ 28 - 0
src/Materials/babylon.materialHelper.ts

@@ -1,5 +1,33 @@
 module BABYLON {
     export class MaterialHelper {
+        public static PrepareDefinesForAttributes(mesh: AbstractMesh, defines: MaterialDefines, useInstances: boolean): void {
+            if (!defines._areAttributesDirty) {
+                return;
+            }
+
+            defines["NORMAL"] = (defines._needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
+
+            if (defines._needUVs) {
+                defines["UV1"] = mesh.isVerticesDataPresent(VertexBuffer.UVKind);
+                defines["UV2"] = mesh.isVerticesDataPresent(VertexBuffer.UV2Kind);
+            } else {
+                defines["UV1"] = false;
+                defines["UV2"] = false;
+            }
+
+            defines["VERTEXCOLOR"] = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
+
+            defines["VERTEXALPHA"] = mesh.hasVertexAlpha;
+
+            if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
+                defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
+            } else {
+                defines["NUM_BONE_INFLUENCERS"] = 0;
+                defines["BonesPerMesh"] = 0;
+            }           
+        }
+
         public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, maxSimultaneousLights = 4, disableLighting = false): boolean {
             if (!defines._areLightsDirty) {
                 return defines._needNormals;

+ 264 - 145
src/Materials/babylon.standardMaterial.ts

@@ -62,7 +62,7 @@ module BABYLON {
 
         public _areTexturesDirty = true;
         public _areFresnelDirty = true;
-        public _needUVs = false;
+        public _areMiscDirty = true;
 
         constructor() {
             super(true);
@@ -91,7 +91,7 @@ module BABYLON {
                 return;
             }
             this._diffuseTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get diffuseTexture(): BaseTexture {
@@ -105,7 +105,7 @@ module BABYLON {
                 return;
             }
             this._ambientTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get ambientTexture(): BaseTexture {
@@ -119,7 +119,7 @@ module BABYLON {
                 return;
             }
             this._opacityTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get opacityTexture(): BaseTexture {
@@ -133,7 +133,7 @@ module BABYLON {
                 return;
             }
             this._reflectionTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get reflectionTexture(): BaseTexture {
@@ -147,7 +147,7 @@ module BABYLON {
                 return;
             }
             this._emissiveTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get emissiveTexture(): BaseTexture {
@@ -161,7 +161,7 @@ module BABYLON {
                 return;
             }
             this._specularTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get specularTexture(): BaseTexture {
@@ -175,7 +175,7 @@ module BABYLON {
                 return;
             }
             this._bumpTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get bumpTexture(): BaseTexture {
@@ -189,7 +189,7 @@ module BABYLON {
                 return;
             }
             this._lightmapTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get lightmapTexture(): BaseTexture {
@@ -203,7 +203,7 @@ module BABYLON {
                 return;
             }
             this._refractionTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get refractionTexture(): BaseTexture {
@@ -225,20 +225,70 @@ module BABYLON {
         @serialize()
         public specularPower = 64;
 
-        @serialize()
-        public useAlphaFromDiffuseTexture = false;
-
-        @serialize()
-        public useEmissiveAsIllumination = false;
-
-        @serialize()
-        public linkEmissiveWithDiffuse = false;
+        @serialize("useAlphaFromDiffuseTexture")
+        private _useAlphaFromDiffuseTexture = false;
+        public set useAlphaFromDiffuseTexture(value : boolean) {
+            if (this._useAlphaFromDiffuseTexture === value) {
+                return;
+            }
+            this._useAlphaFromDiffuseTexture = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useAlphaFromDiffuseTexture(): boolean {
+            return this._useAlphaFromDiffuseTexture;
+        }           
 
-        @serialize()
-        public useSpecularOverAlpha = false;
+        @serialize("useEmissiveAsIllumination")
+        private _useEmissiveAsIllumination = false;
+        public set useEmissiveAsIllumination(value : boolean) {
+            if (this._useAlphaFromDiffuseTexture === value) {
+                return;
+            }
+            this._useEmissiveAsIllumination = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useEmissiveAsIllumination(): boolean {
+            return this._useEmissiveAsIllumination;
+        }          
+      
+        @serialize("linkEmissiveWithDiffuse")
+        private _linkEmissiveWithDiffuse = false;
+        public set linkEmissiveWithDiffuse(value : boolean) {
+            if (this._linkEmissiveWithDiffuse === value) {
+                return;
+            }
+            this._linkEmissiveWithDiffuse = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get linkEmissiveWithDiffuse(): boolean {
+            return this._linkEmissiveWithDiffuse;
+        }                    
+
+        @serialize("useSpecularOverAlpha")
+        private _useSpecularOverAlpha = false;
+        public set useSpecularOverAlpha(value : boolean) {
+            if (this._useSpecularOverAlpha === value) {
+                return;
+            }
+            this._useSpecularOverAlpha = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useSpecularOverAlpha(): boolean {
+            return this._useSpecularOverAlpha;
+        }          
 
-        @serialize()
-        public useReflectionOverAlpha = false;
+        @serialize("useReflectionOverAlpha")
+        private _useReflectionOverAlpha = false;
+        public set useReflectionOverAlpha(value : boolean) {
+            if (this._useReflectionOverAlpha === value) {
+                return;
+            }
+            this._useReflectionOverAlpha = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useReflectionOverAlpha(): boolean {
+            return this._useReflectionOverAlpha;
+        }            
 
         @serialize("disableLighting")
         private _disableLighting = false;
@@ -247,23 +297,53 @@ module BABYLON {
                 return;
             }
             this._disableLighting = value;
-            this._markAllSubMeshesAsLightDirty();
+            this._markAllSubMeshesAsLightsDirty();
         }
         public get disableLighting(): boolean {
             return this._disableLighting;
         }            
 
-        @serialize()
-        public useParallax = false;
+        @serialize("useParallax")
+        private _useParallax = false;
+        public set useParallax(value : boolean) {
+            if (this._useParallax === value) {
+                return;
+            }
+            this._useParallax = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useParallax(): boolean {
+            return this._useParallax;
+        }          
 
-        @serialize()
-        public useParallaxOcclusion = false;
+        @serialize("useParallaxOcclusion")
+        private _useParallaxOcclusion = false;
+        public set useParallaxOcclusion(value : boolean) {
+            if (this._useParallaxOcclusion === value) {
+                return;
+            }
+            this._useParallaxOcclusion = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useParallaxOcclusion(): boolean {
+            return this._useParallaxOcclusion;
+        }         
 
         @serialize()
         public parallaxScaleBias = 0.05;
 
-        @serialize()
-        public roughness = 0;
+        @serialize("roughness")
+        private _roughness = 0;
+        public set roughness(value : number) {
+            if (this._roughness === value) {
+                return;
+            }
+            this._roughness = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get roughness(): number {
+            return this._roughness;
+        }         
 
         @serialize()
         public indexOfRefraction = 0.98;
@@ -271,8 +351,18 @@ module BABYLON {
         @serialize()
         public invertRefractionY = true;
 
-        @serialize()
-        public useLightmapAsShadowmap = false;
+        @serialize("useLightmapAsShadowmap")
+        private _useLightmapAsShadowmap = false;
+        public set useLightmapAsShadowmap(value : boolean) {
+            if (this._useLightmapAsShadowmap === value) {
+                return;
+            }
+            this._useLightmapAsShadowmap = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useLightmapAsShadowmap(): boolean {
+            return this._useLightmapAsShadowmap;
+        }            
 
         // Fresnel
         @serializeAsFresnelParameters("diffuseFresnelParameters")
@@ -353,29 +443,79 @@ module BABYLON {
             return this._useReflectionFresnelFromSpecular;
         }               
 
-        @serialize()
-        public useGlossinessFromSpecularMapAlpha = false;
+        @serialize("useGlossinessFromSpecularMapAlpha")
+        private _useGlossinessFromSpecularMapAlpha = false;
+        public set useGlossinessFromSpecularMapAlpha(value : boolean) {
+            if (this._useGlossinessFromSpecularMapAlpha === value) {
+                return;
+            }
+            this._useGlossinessFromSpecularMapAlpha = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get useGlossinessFromSpecularMapAlpha(): boolean {
+            return this._useGlossinessFromSpecularMapAlpha;
+        }        
 
-        @serialize()
-        public maxSimultaneousLights = 4;
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        public set maxSimultaneousLights(value : number) {
+            if (this._maxSimultaneousLights === value) {
+                return;
+            }
+            this._maxSimultaneousLights = value;
+            this._markAllSubMeshesAsLightsDirty();
+        }
+        public get maxSimultaneousLights(): number {
+            return this._maxSimultaneousLights;
+        }          
 
         /**
          * If sets to true, x component of normal map value will invert (x = 1.0 - x).
          */
-        @serialize()
-        public invertNormalMapX = false;
+        @serialize("invertNormalMapX")
+        private _invertNormalMapX = false;
+        public set invertNormalMapX(value : boolean) {
+            if (this._invertNormalMapX === value) {
+                return;
+            }
+            this._invertNormalMapX = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get invertNormalMapX(): boolean {
+            return this._invertNormalMapX;
+        }           
 
         /**
          * If sets to true, y component of normal map value will invert (y = 1.0 - y).
          */
-        @serialize()
-        public invertNormalMapY = false;
+        @serialize("invertNormalMapY")
+        private _invertNormalMapY = false;
+        public set invertNormalMapY(value : boolean) {
+            if (this._invertNormalMapY === value) {
+                return;
+            }
+            this._invertNormalMapY = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get invertNormalMapY(): boolean {
+            return this._invertNormalMapY;
+        }           
 
         /**
          * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
          */
-        @serialize()
-        public twoSidedLighting = false;
+        @serialize("twoSidedLighting")
+        private _twoSidedLighting = false;
+        public set twoSidedLighting(value : boolean) {
+            if (this._twoSidedLighting === value) {
+                return;
+            }
+            this._twoSidedLighting = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+        public get inverttwoSidedLightingNormalMapY(): boolean {
+            return this._twoSidedLighting;
+        }            
 
         /**
          * Color Grading 2D Lookup Texture.
@@ -389,7 +529,7 @@ module BABYLON {
                 return;
             }
             this._cameraColorGradingTexture = value;
-            this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsTexturesDirty();
         }
 
         public get cameraColorGradingTexture(): BaseTexture {
@@ -402,13 +542,23 @@ module BABYLON {
          * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image; 
          * corresponding to low luminance, medium luminance, and high luminance areas respectively.
          */
-        @serializeAsColorCurves()
-        public cameraColorCurves: ColorCurves = null;
+        @serializeAsColorCurves("cameraColorCurves")
+        private _cameraColorCurves: ColorCurves = null;
+        public set cameraColorCurves(value : ColorCurves) {
+            if (this._cameraColorCurves === value) {
+                return;
+            }
+            this._cameraColorCurves = value;
+            this._markAllSubMeshesAsTexturesDirty();
+        }
+
+        public get cameraColorCurves(): ColorCurves {
+            return this._cameraColorCurves;
+        }          
 
         protected _renderTargets = new SmartArray<RenderTargetTexture>(16);
         protected _worldViewProjectionMatrix = Matrix.Zero();
         protected _globalAmbientColor = new Color3(0, 0, 0);
-        protected _renderId: number;
 
         protected _useLogarithmicDepth: boolean;
 
@@ -444,6 +594,8 @@ module BABYLON {
 
         public set useLogarithmicDepth(value: boolean) {
             this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
+
+            this._markAllSubMeshesAsMiscDirty();
         }
 
         public needAlphaBlending(): boolean {
@@ -467,16 +619,24 @@ module BABYLON {
          */
         public markAsDirty(flag: number): void {
             if (flag & Material.TextureDirtyFlag) {
-                this._markAllSubMeshesAsTextureDirty();
+                this._markAllSubMeshesAsTexturesDirty();
             }
 
             if (flag & Material.LightDirtyFlag) {
-                this._markAllSubMeshesAsLightDirty();
+                this._markAllSubMeshesAsLightsDirty();
             }
 
             if (flag & Material.FresnelDirtyFlag) {
                 this._markAllSubMeshesAsFresnelDirty();
             }
+
+            if (flag & Material.AttributesDirtyFlag) {
+                this._markAllSubMeshesAsAttributesDirty();
+            }
+
+            if (flag & Material.MiscDirtyFlag) {
+                this._markAllSubMeshesAsMiscDirty();
+            }
         }
 
         public getEffect(): Effect {
@@ -507,11 +667,11 @@ module BABYLON {
             var engine = scene.getEngine();
 
             // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, this.maxSimultaneousLights, this.disableLighting);
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, this._maxSimultaneousLights, this._disableLighting);
             defines._areLightsDirty = false;
 
             if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
+                if (defines._renderId === scene.getRenderId()) {
                     return true;
                 }
             }
@@ -561,8 +721,8 @@ module BABYLON {
                             defines._needNormals = true;
                             defines.REFLECTION = true;
 
-                            defines.ROUGHNESS = (this.roughness > 0);
-                            defines.REFLECTIONOVERALPHA = this.useReflectionOverAlpha;
+                            defines.ROUGHNESS = (this._roughness > 0);
+                            defines.REFLECTIONOVERALPHA = this._useReflectionOverAlpha;
                             defines.INVERTCUBICMAP = (this._reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE);
                             defines.REFLECTIONMAP_3D = this._reflectionTexture.isCube;
 
@@ -618,7 +778,7 @@ module BABYLON {
                         } else {
                             defines._needUVs = true;
                             defines.LIGHTMAP = true;
-                            defines.USELIGHTMAPASSHADOWMAP = this.useLightmapAsShadowmap;
+                            defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;
                         }
                     } else {
                         defines.LIGHTMAP = false;
@@ -630,7 +790,7 @@ module BABYLON {
                         } else {
                             defines._needUVs = true;
                             defines.SPECULAR = true;
-                            defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
+                            defines.GLOSSINESS = this._useGlossinessFromSpecularMapAlpha;
                         }
                     } else {
                         defines.SPECULAR = false;
@@ -643,16 +803,11 @@ module BABYLON {
                             defines._needUVs = true;
                             defines.BUMP = true;
 
-                            defines.PARALLAX = this.useParallax;
-                            defines.PARALLAXOCCLUSION = this.useParallaxOcclusion;
-
                             defines.INVERTNORMALMAPX = this.invertNormalMapX;
                             defines.INVERTNORMALMAPY = this.invertNormalMapY;
 
-                            if (scene._mirroredCameraPosition) {
-                                defines.INVERTNORMALMAPX = !defines.INVERTNORMALMAPX;
-                                defines.INVERTNORMALMAPY = !defines.INVERTNORMALMAPY;
-                            }
+                            defines.PARALLAX = this._useParallax;
+                            defines.PARALLAXOCCLUSION = this._useParallaxOcclusion;
                         }
                     } else {
                         defines.BUMP = false;
@@ -681,11 +836,7 @@ module BABYLON {
                         defines.CAMERACOLORGRADING = false;
                     }
 
-                    if (!this.backFaceCulling && this.twoSidedLighting) {
-                        defines.TWOSIDEDLIGHTING = true;
-                    } else {
-                        defines.TWOSIDEDLIGHTING = false;
-                    }
+                    defines.TWOSIDEDLIGHTING = !this._backFaceCulling && this._twoSidedLighting;
                 } else {
                     defines.DIFFUSE = false;
                     defines.AMBIENT = false;
@@ -698,6 +849,16 @@ module BABYLON {
                     defines.CAMERACOLORGRADING = false;
                 }
 
+                defines.CAMERACOLORCURVES = (this._cameraColorCurves !== undefined && this._cameraColorCurves !== null);
+
+                defines.ALPHAFROMDIFFUSE = this._shouldUseAlphaFromDiffuseTexture();
+
+                defines.EMISSIVEASILLUMINATION = this._useEmissiveAsIllumination;
+
+                defines.LINKEMISSIVEWITHDIFFUSE = this._linkEmissiveWithDiffuse;       
+
+                defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
+         
                 defines._areTexturesDirty = false;
             } 
 
@@ -732,55 +893,27 @@ module BABYLON {
                 defines._areFresnelDirty = false;
             }
 
-            // Effect
-            defines.CLIPPLANE = (scene.clipPlane !== undefined && scene.clipPlane !== null);
-
-            defines.ALPHATEST = engine.getAlphaTesting();
-
-            defines.ALPHAFROMDIFFUSE = this._shouldUseAlphaFromDiffuseTexture();
-
-            defines.EMISSIVEASILLUMINATION = this.useEmissiveAsIllumination;
-
-            defines.LINKEMISSIVEWITHDIFFUSE = this.linkEmissiveWithDiffuse;
-
-            defines.LOGARITHMICDEPTH = this.useLogarithmicDepth;
-
-            defines.CAMERACOLORCURVES = (this.cameraColorCurves !== undefined && this.cameraColorCurves !== null);
-
-            // Point size
-            defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
+            // Misc.
+            if (defines._areMiscDirty) {
+                defines.LOGARITHMICDEPTH = this._useLogarithmicDepth;
+                defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
+                defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
 
-            // Fog
-            defines.FOG = (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
-
-            defines.SPECULAROVERALPHA = (defines.SPECULARTERM && this.useSpecularOverAlpha);
+                defines._areMiscDirty = false;
+            }
 
             // Attribs
-            if (mesh) {
-                defines.NORMAL = (defines._needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
-
-                if (defines._needUVs) {
-                    defines.UV1 = mesh.isVerticesDataPresent(VertexBuffer.UVKind);
-                    defines.UV2 = mesh.isVerticesDataPresent(VertexBuffer.UV2Kind);
-                } else {
-                    defines.UV1 = false;
-                    defines.UV2 = false;
-                }
-
-                defines.VERTEXCOLOR = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, useInstances);
+            defines._areAttributesDirty = false;
 
-                defines.VERTEXALPHA = mesh.hasVertexAlpha;
-
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                } else {
-                    defines.NUM_BONE_INFLUENCERS = 0;
-                    defines.BonesPerMesh = 0;
-                }
+            // Values that need to be evaluated on every frame
+            defines.CLIPPLANE = (scene.clipPlane !== undefined && scene.clipPlane !== null);
+            defines.ALPHATEST = engine.getAlphaTesting();
+            defines.INSTANCES = useInstances;
 
-                // Instances
-                defines.INSTANCES = useInstances;
+            if (scene._mirroredCameraPosition && defines.BUMP) {
+                defines.INVERTNORMALMAPX = !this.invertNormalMapX;
+                defines.INVERTNORMALMAPY = !this.invertNormalMapY;
             }
 
             // Get correct effect      
@@ -826,7 +959,7 @@ module BABYLON {
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
 
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights);
 
                 if (defines.SPECULARTERM) {
                     fallbacks.addFallback(0, "SPECULARTERM");
@@ -895,18 +1028,18 @@ module BABYLON {
                 if (defines.CAMERACOLORGRADING) {
                     ColorGradingTexture.PrepareUniformsAndSamplers(uniforms, samplers);
                 }
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this._maxSimultaneousLights);
 
                 subMesh.effect = scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this._maxSimultaneousLights - 1 });
             }
 
             if (!subMesh.effect.isReady()) {
                 return false;
             }
 
-            this._renderId = scene.getRenderId();
+            defines._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
 
             return true;
@@ -1088,7 +1221,7 @@ module BABYLON {
 
                 // Lights
                 if (scene.lightsEnabled && !this.disableLighting) {
-                    MaterialHelper.BindLights(scene, mesh, effect, defines, this.maxSimultaneousLights);
+                    MaterialHelper.BindLights(scene, mesh, effect, defines, this._maxSimultaneousLights);
                 }
 
                 // View
@@ -1211,7 +1344,7 @@ module BABYLON {
             return SerializationHelper.Serialize(this);
         }
 
-        private _markAllSubMeshesAsTextureDirty() {
+        private _markAllSubMeshesAsDirty(func: (defines: StandardMaterialDefines) => void) {
             for (var mesh of this.getScene().meshes) {
                 if (!mesh.subMeshes) {
                     continue;
@@ -1223,43 +1356,29 @@ module BABYLON {
                     if (!subMesh._materialDefines) {
                         subMesh._materialDefines = new StandardMaterialDefines();
                     }
-                    (<StandardMaterialDefines>subMesh._materialDefines)._areTexturesDirty = true;
+                    func(<StandardMaterialDefines>(subMesh._materialDefines));
                 }
             }
         }
 
+        private _markAllSubMeshesAsTexturesDirty() {
+            this._markAllSubMeshesAsDirty(defines => defines._areTexturesDirty = true);
+        }
+
         private _markAllSubMeshesAsFresnelDirty() {
-            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)._areFresnelDirty = true;
-                }
-            }
+            this._markAllSubMeshesAsDirty(defines => defines._areFresnelDirty = true);
         }
 
-        private _markAllSubMeshesAsLightDirty() {
-            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();
-                    }
-                    subMesh._materialDefines._areLightsDirty = true;
-                }
-            }
+        private _markAllSubMeshesAsLightsDirty() {
+            this._markAllSubMeshesAsDirty(defines => defines._areLightsDirty = true);
+        }
+
+        private _markAllSubMeshesAsAttributesDirty() {
+            this._markAllSubMeshesAsDirty(defines => defines._areAttributesDirty = true);
+        }
+
+        private _markAllSubMeshesAsMiscDirty() {
+            this._markAllSubMeshesAsDirty(defines => defines._areMiscDirty = true);
         }
 
         // Statics

+ 90 - 7
src/Mesh/babylon.abstractMesh.ts

@@ -148,12 +148,72 @@
         public renderOverlay = false;
         public overlayColor = Color3.Red();
         public overlayAlpha = 0.5;
-        public hasVertexAlpha = false;
-        public useVertexColors = true;
-        public applyFog = true;
-        public computeBonesUsingShaders = true;
+        private _hasVertexAlpha = false;
+        public get hasVertexAlpha(): boolean {
+            return this._hasVertexAlpha;
+        }
+        public set hasVertexAlpha(value: boolean) {
+            if (this._hasVertexAlpha === value) {
+                return;
+            }
+
+            this._hasVertexAlpha = value;
+            this._markSubMeshesAsAttributesDirty();
+        }        
+
+        private _useVertexColors = true;
+        public get useVertexColors(): boolean {
+            return this._useVertexColors;
+        }
+        public set useVertexColors(value: boolean) {
+            if (this._useVertexColors === value) {
+                return;
+            }
+
+            this._useVertexColors = value;
+            this._markSubMeshesAsAttributesDirty();
+        }         
+
+        private _computeBonesUsingShaders = true;
+        public get computeBonesUsingShaders(): boolean {
+            return this._computeBonesUsingShaders;
+        }
+        public set computeBonesUsingShaders(value: boolean) {
+            if (this._computeBonesUsingShaders === value) {
+                return;
+            }
+
+            this._computeBonesUsingShaders = value;
+            this._markSubMeshesAsAttributesDirty();
+        }                
+
+        private _numBoneInfluencers = 4;
+        public get numBoneInfluencers(): number {
+            return this._numBoneInfluencers;
+        }
+        public set numBoneInfluencers(value: number) {
+            if (this._numBoneInfluencers === value) {
+                return;
+            }
+
+            this._numBoneInfluencers = value;
+            this._markSubMeshesAsAttributesDirty();
+        }           
+
+        private _applyFog = true;
+        public get applyFog(): boolean {
+            return this._applyFog;
+        }
+        public set applyFog(value: boolean) {
+            if (this._applyFog === value) {
+                return;
+            }
+
+            this._applyFog = value;
+            this._markSubMeshesAsMiscDirty();
+        }  
+
         public scalingDeterminant = 1;
-        public numBoneInfluencers = 4;
 
         public useOctreeForRenderingSelection = true;
         public useOctreeForPicking = true;
@@ -259,6 +319,8 @@
             if (!this._skeleton) {
                 this._bonesTransformMatrices = null;
             }
+
+            this._markSubMeshesAsAttributesDirty();
         }
 
         public get skeleton(): Skeleton {
@@ -342,14 +404,35 @@
             this._lightSources.slice(index, 1);       
         }
 
-        public _markSubMeshesAsLightDirty() {
+        private _markSubMeshesAsDirty(func: (defines: MaterialDefines) => void) {
             if (!this.subMeshes) {
                 return;
             }
             
             for (var subMesh of this.subMeshes) {
                 if (subMesh._materialDefines) {
-                    subMesh._materialDefines._areLightsDirty = true;
+                    func(subMesh._materialDefines);
+                }
+            }
+        }
+
+        public _markSubMeshesAsLightDirty() {
+            this._markSubMeshesAsDirty(defines => defines._areLightsDirty = true);
+        }
+
+        public _markSubMeshesAsAttributesDirty() {
+            this._markSubMeshesAsDirty(defines => defines._areAttributesDirty = true);
+        }
+
+        public _markSubMeshesAsMiscDirty() {
+            if (!this.subMeshes) {
+                return;
+            }
+            
+            for (var subMesh of this.subMeshes) {
+                var material = subMesh.getMaterial();
+                if (material) {
+                    material.markAsDirty(Material.MiscDirtyFlag);
                 }
             }
         }

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

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

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

@@ -372,14 +372,13 @@ void main(void) {
 
 #ifdef SPECULARTERM
 	vec3 finalSpecular = specularBase * specularColor;
+	#ifdef SPECULAROVERALPHA
+		alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
+	#endif
 #else
 	vec3 finalSpecular = vec3(0.0);
 #endif
 
-#ifdef SPECULAROVERALPHA
-	alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
-#endif
-
 #ifdef REFLECTIONOVERALPHA
 	alpha = clamp(alpha + dot(reflectionColor, vec3(0.3, 0.59, 0.11)), 0., 1.);
 #endif

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

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

+ 50 - 6
src/babylon.scene.ts

@@ -190,7 +190,18 @@
         public ambientColor = new Color3(0, 0, 0);
 
         public forceWireframe = false;
-        public forcePointsCloud = false;
+        private _forcePointsCloud = false;
+        public set forcePointsCloud(value : boolean) {
+            if (this._forcePointsCloud === value) {
+                return;
+            }
+            this._forcePointsCloud = value;
+            this.markAllMaterialsAsDirty(Material.MiscDirtyFlag);
+        }
+        public get forcePointsCloud(): boolean {
+            return this._forcePointsCloud;
+        }   
+
         public forceShowBoundingBoxes = false;
         public clipPlane: Plane;
         public animationsEnabled = true;
@@ -395,6 +406,7 @@
         private _previousStartingPointerPosition = new Vector2(0, 0);
         private _startingPointerTime = 0;
         private _previousStartingPointerTime = 0;
+        
         // Mirror
         public _mirroredCameraPosition: Vector3;
 
@@ -407,8 +419,30 @@
         * is fog enabled on this scene.
         * @type {boolean}
         */
-        public fogEnabled = true;
-        public fogMode = Scene.FOGMODE_NONE;
+        private _fogEnabled = true;
+        public set fogEnabled(value : boolean) {
+            if (this._fogEnabled === value) {
+                return;
+            }
+            this._fogEnabled = value;
+            this.markAllMaterialsAsDirty(Material.MiscDirtyFlag);
+        }
+        public get fogEnabled(): boolean {
+            return this._fogEnabled;
+        }   
+
+        private _fogMode = Scene.FOGMODE_NONE;
+        public set fogMode(value : number) {
+            if (this._fogMode === value) {
+                return;
+            }
+            this._fogMode = value;
+            this.markAllMaterialsAsDirty(Material.MiscDirtyFlag);
+        }
+        public get fogMode(): number {
+            return this._fogMode;
+        }  
+
         public fogColor = new Color3(0.2, 0.2, 0.3);
         public fogDensity = 0.1;
         public fogStart = 0;
@@ -427,7 +461,6 @@
             this._shadowsEnabled = value;
             this.markAllMaterialsAsDirty(Material.LightDirtyFlag);
         }
-
         public get shadowsEnabled(): boolean {
             return this._shadowsEnabled;
         }       
@@ -491,7 +524,6 @@
 
         // Textures
         private _texturesEnabled = true;
-
         public set texturesEnabled(value : boolean) {
             if (this._texturesEnabled === value) {
                 return;
@@ -519,7 +551,19 @@
         public highlightLayers = new Array<HighlightLayer>();
 
         // Skeletons
-        public skeletonsEnabled = true;
+        private _skeletonsEnabled = true;
+        public set skeletonsEnabled(value : boolean) {
+            if (this._skeletonsEnabled === value) {
+                return;
+            }
+            this._skeletonsEnabled = value;
+            this.markAllMaterialsAsDirty(Material.AttributesDirtyFlag);
+        }
+
+        public get skeletonsEnabled(): boolean {
+            return this._skeletonsEnabled;
+        }       
+
         public skeletons = new Array<Skeleton>();
 
         // Lens flares