Sébastien Vandenberghe пре 9 година
родитељ
комит
9b8bc40d3f

+ 1 - 0
Tools/Gulp/config.json

@@ -62,6 +62,7 @@
       "../../src/Materials/Textures/babylon.videoTexture.js",
       "../../src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js",
       "../../src/Materials/babylon.effect.js",
+      "../../src/Materials/babylon.materialHelper.js",
       "../../src/Materials/babylon.material.js",
       "../../src/Materials/babylon.standardMaterial.js",
       "../../src/Materials/babylon.multiMaterial.js",

Разлика између датотеке није приказан због своје велике величине
+ 13 - 12
dist/preview release/babylon.core.js


+ 210 - 206
dist/preview release/babylon.d.ts

@@ -1265,6 +1265,181 @@ 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;
+        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;
+        /**
+        * 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;
+        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.
+        */
+        play(time?: 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;
+        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
+        clone(): Sound;
+        getAudioBuffer(): AudioBuffer;
+        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;
@@ -1457,181 +1632,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;
-        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;
-        /**
-        * 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;
-        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.
-        */
-        play(time?: 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;
-        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
-        clone(): Sound;
-        getAudioBuffer(): AudioBuffer;
-        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[];
@@ -2845,6 +2845,19 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class MaterialHelper {
+        static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines): boolean;
+        static HandleFallbacksForShadows(defines: MaterialDefines, fallbacks: EffectFallbacks): void;
+        static PrepareAttributesForBones(attribs: string[], mesh: AbstractMesh, defines: MaterialDefines, fallbacks: EffectFallbacks): void;
+        static PrepareAttributesForInstances(attribs: string[], defines: MaterialDefines): void;
+        static BindLightShadow(light: Light, scene: Scene, mesh: AbstractMesh, lightIndex: number, effect: Effect, depthValuesAlreadySet: boolean): boolean;
+        static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines): void;
+        static BindFogParameters(scene: Scene, mesh: AbstractMesh, effect: Effect): void;
+        static BindBonesParameters(mesh: AbstractMesh, effect: Effect): void;
+    }
+}
+
+declare module BABYLON {
     class MultiMaterial extends Material {
         subMaterials: Material[];
         constructor(name: string, scene: Scene);
@@ -2953,20 +2966,10 @@ declare module BABYLON {
         private _shouldUseAlphaFromDiffuseTexture();
         getAlphaTestTexture(): BaseTexture;
         private _checkCache(scene, mesh?, useInstances?);
-        static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines): boolean;
-        private static _scaledDiffuse;
-        private static _scaledSpecular;
-        static BindLightShadow(light: Light, scene: Scene, mesh: AbstractMesh, lightIndex: number, effect: Effect, depthValuesAlreadySet: boolean): boolean;
-        static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines): void;
-        static HandleFallbacksForShadows(defines: MaterialDefines, fallbacks: EffectFallbacks): void;
-        static PrepareAttributesForBones(attribs: string[], mesh: AbstractMesh, defines: MaterialDefines, fallbacks: EffectFallbacks): void;
-        static PrepareAttributesForInstances(attribs: string[], defines: MaterialDefines): void;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         unbind(): void;
         bindOnlyWorldMatrix(world: Matrix): void;
         bind(world: Matrix, mesh?: Mesh): void;
-        static ApplyFogParameters(scene: Scene, mesh: AbstractMesh, effect: Effect): void;
-        static ApplyBonesParameters(mesh: AbstractMesh, effect: Effect): void;
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): StandardMaterial;
@@ -3546,6 +3549,7 @@ declare module BABYLON {
         clone(): PositionNormalTextureVertex;
     }
     class Tmp {
+        static Color3: Color3[];
         static Vector2: Vector2[];
         static Vector3: Vector3[];
         static Vector4: Vector4[];
@@ -5354,27 +5358,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class ReflectionProbe {
-        name: string;
-        private _scene;
-        private _renderTargetTexture;
-        private _projectionMatrix;
-        private _viewMatrix;
-        private _target;
-        private _add;
-        private _attachedMesh;
-        position: Vector3;
-        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
-        refreshRate: number;
-        getScene(): Scene;
-        cubeTexture: RenderTargetTexture;
-        renderList: AbstractMesh[];
-        attachToMesh(mesh: AbstractMesh): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
     class AnaglyphPostProcess extends PostProcess {
         constructor(name: string, ratio: number, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean);
     }
@@ -5944,6 +5927,27 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class ReflectionProbe {
+        name: string;
+        private _scene;
+        private _renderTargetTexture;
+        private _projectionMatrix;
+        private _viewMatrix;
+        private _target;
+        private _add;
+        private _attachedMesh;
+        position: Vector3;
+        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
+        refreshRate: number;
+        getScene(): Scene;
+        cubeTexture: RenderTargetTexture;
+        renderList: AbstractMesh[];
+        attachToMesh(mesh: AbstractMesh): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
     class BoundingBoxRenderer {
         frontColor: Color3;
         backColor: Color3;

Разлика између датотеке није приказан због своје велике величине
+ 21 - 23
dist/preview release/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 200 - 190
dist/preview release/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 20 - 22
dist/preview release/babylon.noworker.js


+ 7 - 10
materialsLibrary/dist/babylon.pbrMaterial.js

@@ -253,7 +253,7 @@ var BABYLON;
                 }
                 // Shadows
                 if (scene.shadowsEnabled) {
-                    depthValuesAlreadySet = BABYLON.StandardMaterial.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
+                    depthValuesAlreadySet = BABYLON.MaterialHelper.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
                 }
                 lightIndex++;
                 if (lightIndex === maxSimultaneousLights)
@@ -459,7 +459,7 @@ var BABYLON;
                 this._defines.FOG = true;
             }
             if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.StandardMaterial.PrepareDefinesForLights(scene, mesh, this._defines) || needNormals;
+                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines) || needNormals;
             }
             if (BABYLON.StandardMaterial.FresnelEnabled) {
                 // Fresnel
@@ -533,7 +533,7 @@ var BABYLON;
                 if (this._defines.LOGARITHMICDEPTH) {
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
-                BABYLON.StandardMaterial.HandleFallbacksForShadows(this._defines, fallbacks);
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
                 if (this._defines.SPECULARTERM) {
                     fallbacks.addFallback(0, "SPECULARTERM");
                 }
@@ -563,8 +563,8 @@ var BABYLON;
                 if (this._defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
-                BABYLON.StandardMaterial.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.StandardMaterial.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
                 // Legacy browser patch
                 var shaderName = "pbr";
                 if (!scene.getEngine().getCaps().standardDerivatives) {
@@ -622,7 +622,7 @@ var BABYLON;
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             // Bones
-            BABYLON.StandardMaterial.ApplyBonesParameters(mesh, this._effect);
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
             if (this._myScene.getCachedMaterial() !== this) {
                 this._effect.setMatrix("viewProjection", this._myScene.getTransformMatrix());
                 if (BABYLON.StandardMaterial.FresnelEnabled) {
@@ -747,10 +747,7 @@ var BABYLON;
                     this._effect.setMatrix("view", this._myScene.getViewMatrix());
                 }
                 // Fog
-                if (this._myScene.fogEnabled && mesh.applyFog && this._myScene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                    this._effect.setFloat4("vFogInfos", this._myScene.fogMode, this._myScene.fogStart, this._myScene.fogEnd, this._myScene.fogDensity);
-                    this._effect.setColor3("vFogColor", this._myScene.fogColor);
-                }
+                BABYLON.MaterialHelper.BindFogParameters(this._myScene, mesh, this._effect);
                 this._lightingInfos.x = this.directIntensity;
                 this._lightingInfos.y = this.emissiveIntensity;
                 this._lightingInfos.z = this.environmentIntensity;

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
materialsLibrary/dist/babylon.pbrMaterial.min.js


+ 7 - 7
materialsLibrary/dist/babylon.simpleMaterial.js

@@ -138,7 +138,7 @@ var BABYLON;
             }
             var lightIndex = 0;
             if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.StandardMaterial.PrepareDefinesForLights(scene, mesh, this._defines);
+                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines);
             }
             // Attribs
             if (mesh) {
@@ -177,7 +177,7 @@ var BABYLON;
                 if (this._defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                 }
-                BABYLON.StandardMaterial.HandleFallbacksForShadows(this._defines, fallbacks);
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
                 if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
@@ -195,8 +195,8 @@ var BABYLON;
                 if (this._defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
-                BABYLON.StandardMaterial.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.StandardMaterial.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
                 // Legacy browser patch
                 var shaderName = "simple";
                 var join = this._defines.toString();
@@ -236,7 +236,7 @@ var BABYLON;
             this.bindOnlyWorldMatrix(world);
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
-            BABYLON.StandardMaterial.ApplyBonesParameters(mesh, this._effect);
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
                 if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
@@ -258,14 +258,14 @@ var BABYLON;
             this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
             }
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
                 this._effect.setMatrix("view", scene.getViewMatrix());
             }
             // Fog
-            BABYLON.StandardMaterial.ApplyFogParameters(scene, mesh, this._effect);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
             _super.prototype.bind.call(this, world, mesh);
         };
         SimpleMaterial.prototype.getAnimatables = function () {

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
materialsLibrary/dist/babylon.simpleMaterial.min.js


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

@@ -307,7 +307,7 @@ module BABYLON {
 
                 // Shadows
                 if (scene.shadowsEnabled) {
-                    depthValuesAlreadySet = StandardMaterial.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
+                    depthValuesAlreadySet = MaterialHelper.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
                 }
 
                 lightIndex++;
@@ -545,7 +545,7 @@ module BABYLON {
             }
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = StandardMaterial.PrepareDefinesForLights(scene, mesh, this._defines) || needNormals;
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines) || needNormals;
             }
 
             if (StandardMaterial.FresnelEnabled) {
@@ -637,7 +637,7 @@ module BABYLON {
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
 
-                StandardMaterial.HandleFallbacksForShadows(this._defines, fallbacks);
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
 
                 if (this._defines.SPECULARTERM) {
                     fallbacks.addFallback(0, "SPECULARTERM");
@@ -678,8 +678,8 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                StandardMaterial.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                StandardMaterial.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
 
                 // Legacy browser patch
                 var shaderName = "pbr";
@@ -757,7 +757,7 @@ module BABYLON {
             this.bindOnlyWorldMatrix(world);
 
             // Bones
-            StandardMaterial.ApplyBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._effect);
 
             if (this._myScene.getCachedMaterial() !== (<BABYLON.Material>this)) {
                 this._effect.setMatrix("viewProjection", this._myScene.getTransformMatrix());
@@ -937,10 +937,7 @@ module BABYLON {
                 }
 
                 // Fog
-                if (this._myScene.fogEnabled && mesh.applyFog && this._myScene.fogMode !== Scene.FOGMODE_NONE) {
-                    this._effect.setFloat4("vFogInfos", this._myScene.fogMode, this._myScene.fogStart, this._myScene.fogEnd, this._myScene.fogDensity);
-                    this._effect.setColor3("vFogColor", this._myScene.fogColor);
-                }
+                MaterialHelper.BindFogParameters(this._myScene, mesh, this._effect);
 
                 this._lightingInfos.x = this.directIntensity;
                 this._lightingInfos.y = this.emissiveIntensity;

+ 7 - 7
materialsLibrary/materials/simple/babylon.simpleMaterial.ts

@@ -161,7 +161,7 @@ module BABYLON {
 
             var lightIndex = 0;
             if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = StandardMaterial.PrepareDefinesForLights(scene, mesh, this._defines);
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines);
             }
 
             // Attribs
@@ -207,7 +207,7 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
 
-                StandardMaterial.HandleFallbacksForShadows(this._defines, fallbacks);
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
                 
                 if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
@@ -232,8 +232,8 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                StandardMaterial.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                StandardMaterial.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
 
                 // Legacy browser patch
                 var shaderName = "simple";
@@ -286,7 +286,7 @@ module BABYLON {
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
             // Bones
-            StandardMaterial.ApplyBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._effect);
 
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
@@ -314,7 +314,7 @@ module BABYLON {
 
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
-                StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);          
+                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);          
             }
 
             // View
@@ -323,7 +323,7 @@ module BABYLON {
             }
 
             // Fog
-            StandardMaterial.ApplyFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
 
             super.bind(world, mesh);
         }

Разлика између датотеке није приказан због своје велике величине
+ 200 - 190
materialsLibrary/test/refs/babylon.max.js


+ 190 - 0
src/Materials/babylon.materialHelper.js

@@ -0,0 +1,190 @@
+var BABYLON;
+(function (BABYLON) {
+    var maxSimultaneousLights = 4;
+    var MaterialHelper = (function () {
+        function MaterialHelper() {
+        }
+        MaterialHelper.PrepareDefinesForLights = function (scene, mesh, defines) {
+            var lightIndex = 0;
+            var needNormals = false;
+            for (var index = 0; index < scene.lights.length; index++) {
+                var light = scene.lights[index];
+                if (!light.isEnabled()) {
+                    continue;
+                }
+                // Excluded check
+                if (light._excludedMeshesIds.length > 0) {
+                    for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
+                        var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
+                        if (excludedMesh) {
+                            light.excludedMeshes.push(excludedMesh);
+                        }
+                    }
+                    light._excludedMeshesIds = [];
+                }
+                // Included check
+                if (light._includedOnlyMeshesIds.length > 0) {
+                    for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
+                        var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
+                        if (includedOnlyMesh) {
+                            light.includedOnlyMeshes.push(includedOnlyMesh);
+                        }
+                    }
+                    light._includedOnlyMeshesIds = [];
+                }
+                if (!light.canAffectMesh(mesh)) {
+                    continue;
+                }
+                needNormals = true;
+                defines["LIGHT" + lightIndex] = true;
+                var type;
+                if (light instanceof BABYLON.SpotLight) {
+                    type = "SPOTLIGHT" + lightIndex;
+                }
+                else if (light instanceof BABYLON.HemisphericLight) {
+                    type = "HEMILIGHT" + lightIndex;
+                }
+                else if (light instanceof BABYLON.PointLight) {
+                    type = "POINTLIGHT" + lightIndex;
+                }
+                else {
+                    type = "DIRLIGHT" + lightIndex;
+                }
+                defines[type] = true;
+                // Specular
+                if (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined) {
+                    defines["SPECULARTERM"] = true;
+                }
+                // Shadows
+                if (scene.shadowsEnabled) {
+                    var shadowGenerator = light.getShadowGenerator();
+                    if (mesh && mesh.receiveShadows && shadowGenerator) {
+                        defines["SHADOW" + lightIndex] = true;
+                        defines["SHADOWS"] = true;
+                        if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
+                            defines["SHADOWVSM" + lightIndex] = true;
+                        }
+                        if (shadowGenerator.usePoissonSampling) {
+                            defines["SHADOWPCF" + lightIndex] = true;
+                        }
+                    }
+                }
+                lightIndex++;
+                if (lightIndex === maxSimultaneousLights)
+                    break;
+            }
+            return needNormals;
+        };
+        MaterialHelper.HandleFallbacksForShadows = function (defines, fallbacks) {
+            for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
+                if (!defines["LIGHT" + lightIndex]) {
+                    continue;
+                }
+                if (lightIndex > 0) {
+                    fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
+                }
+                if (defines["SHADOW" + lightIndex]) {
+                    fallbacks.addFallback(0, "SHADOW" + lightIndex);
+                }
+                if (defines["SHADOWPCF" + lightIndex]) {
+                    fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
+                }
+                if (defines["SHADOWVSM" + lightIndex]) {
+                    fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
+                }
+            }
+        };
+        MaterialHelper.PrepareAttributesForBones = function (attribs, mesh, defines, fallbacks) {
+            if (defines["NUM_BONE_INFLUENCERS"] > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+                attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
+                attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
+                if (defines["NUM_BONE_INFLUENCERS"] > 4) {
+                    attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
+                }
+            }
+        };
+        MaterialHelper.PrepareAttributesForInstances = function (attribs, defines) {
+            if (defines["INSTANCES"]) {
+                attribs.push("world0");
+                attribs.push("world1");
+                attribs.push("world2");
+                attribs.push("world3");
+            }
+        };
+        // Bindings
+        MaterialHelper.BindLightShadow = function (light, scene, mesh, lightIndex, effect, depthValuesAlreadySet) {
+            var shadowGenerator = light.getShadowGenerator();
+            if (mesh.receiveShadows && shadowGenerator) {
+                if (!light.needCube()) {
+                    effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                }
+                else {
+                    if (!depthValuesAlreadySet) {
+                        depthValuesAlreadySet = true;
+                        effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                    }
+                }
+                effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
+                effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.blurScale / shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
+            }
+            return depthValuesAlreadySet;
+        };
+        MaterialHelper.BindLights = function (scene, mesh, effect, defines) {
+            var lightIndex = 0;
+            var depthValuesAlreadySet = false;
+            for (var index = 0; index < scene.lights.length; index++) {
+                var light = scene.lights[index];
+                if (!light.isEnabled()) {
+                    continue;
+                }
+                if (!light.canAffectMesh(mesh)) {
+                    continue;
+                }
+                if (light instanceof BABYLON.PointLight) {
+                    // Point Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex);
+                }
+                else if (light instanceof BABYLON.DirectionalLight) {
+                    // Directional Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex);
+                }
+                else if (light instanceof BABYLON.SpotLight) {
+                    // Spot Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
+                }
+                else if (light instanceof BABYLON.HemisphericLight) {
+                    // Hemispheric Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
+                }
+                light.diffuse.scaleToRef(light.intensity, BABYLON.Tmp.Color3[0]);
+                effect.setColor4("vLightDiffuse" + lightIndex, BABYLON.Tmp.Color3[0], light.range);
+                if (defines["SPECULARTERM"]) {
+                    light.specular.scaleToRef(light.intensity, BABYLON.Tmp.Color3[1]);
+                    effect.setColor3("vLightSpecular" + lightIndex, BABYLON.Tmp.Color3[1]);
+                }
+                // Shadows
+                if (scene.shadowsEnabled) {
+                    depthValuesAlreadySet = this.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
+                }
+                lightIndex++;
+                if (lightIndex === maxSimultaneousLights)
+                    break;
+            }
+        };
+        MaterialHelper.BindFogParameters = function (scene, mesh, effect) {
+            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
+                effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
+                effect.setColor3("vFogColor", scene.fogColor);
+            }
+        };
+        MaterialHelper.BindBonesParameters = function (mesh, effect) {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+                effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
+            }
+        };
+        return MaterialHelper;
+    })();
+    BABYLON.MaterialHelper = MaterialHelper;
+})(BABYLON || (BABYLON = {}));

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

@@ -0,0 +1,216 @@
+module BABYLON {
+    var maxSimultaneousLights = 4;
+
+    export class MaterialHelper {
+        public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines): boolean {
+            var lightIndex = 0;
+            var needNormals = false;
+            for (var index = 0; index < scene.lights.length; index++) {
+                var light = scene.lights[index];
+
+                if (!light.isEnabled()) {
+                    continue;
+                }
+
+                // Excluded check
+                if (light._excludedMeshesIds.length > 0) {
+                    for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
+                        var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
+
+                        if (excludedMesh) {
+                            light.excludedMeshes.push(excludedMesh);
+                        }
+                    }
+
+                    light._excludedMeshesIds = [];
+                }
+
+                // Included check
+                if (light._includedOnlyMeshesIds.length > 0) {
+                    for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
+                        var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
+
+                        if (includedOnlyMesh) {
+                            light.includedOnlyMeshes.push(includedOnlyMesh);
+                        }
+                    }
+
+                    light._includedOnlyMeshesIds = [];
+                }
+
+                if (!light.canAffectMesh(mesh)) {
+                    continue;
+                }
+                needNormals = true;
+                defines["LIGHT" + lightIndex] = true;
+
+                var type;
+                if (light instanceof SpotLight) {
+                    type = "SPOTLIGHT" + lightIndex;
+                } else if (light instanceof HemisphericLight) {
+                    type = "HEMILIGHT" + lightIndex;
+                } else if (light instanceof PointLight) {
+                    type = "POINTLIGHT" + lightIndex;
+                } else {
+                    type = "DIRLIGHT" + lightIndex;
+                }
+
+                defines[type] = true;
+
+                // Specular
+                if (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined) {
+                    defines["SPECULARTERM"] = true;
+                }
+
+                // Shadows
+                if (scene.shadowsEnabled) {
+                    var shadowGenerator = light.getShadowGenerator();
+                    if (mesh && mesh.receiveShadows && shadowGenerator) {
+                        defines["SHADOW" + lightIndex] = true;
+
+                        defines["SHADOWS"] = true;
+
+                        if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
+                            defines["SHADOWVSM" + lightIndex] = true;
+                        }
+
+                        if (shadowGenerator.usePoissonSampling) {
+                            defines["SHADOWPCF" + lightIndex] = true;
+                        }
+                    }
+                }
+
+                lightIndex++;
+                if (lightIndex === maxSimultaneousLights)
+                    break;
+            }
+
+            return needNormals;
+        }
+
+        public static HandleFallbacksForShadows(defines: MaterialDefines, fallbacks: EffectFallbacks): void {
+            for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
+                if (!defines["LIGHT" + lightIndex]) {
+                    continue;
+                }
+
+                if (lightIndex > 0) {
+                    fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
+                }
+
+                if (defines["SHADOW" + lightIndex]) {
+                    fallbacks.addFallback(0, "SHADOW" + lightIndex);
+                }
+
+                if (defines["SHADOWPCF" + lightIndex]) {
+                    fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
+                }
+
+                if (defines["SHADOWVSM" + lightIndex]) {
+                    fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
+                }
+            }
+        }
+
+        public static PrepareAttributesForBones(attribs: string[], mesh: AbstractMesh, defines: MaterialDefines, fallbacks: EffectFallbacks): void {
+            if (defines["NUM_BONE_INFLUENCERS"] > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+
+                attribs.push(VertexBuffer.MatricesIndicesKind);
+                attribs.push(VertexBuffer.MatricesWeightsKind);
+                if (defines["NUM_BONE_INFLUENCERS"] > 4) {
+                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                }
+            }
+        }
+
+        public static PrepareAttributesForInstances(attribs: string[], defines: MaterialDefines): void {
+            if (defines["INSTANCES"]) {
+                attribs.push("world0");
+                attribs.push("world1");
+                attribs.push("world2");
+                attribs.push("world3");
+            }
+        }
+
+        // Bindings
+        public static BindLightShadow(light: Light, scene: Scene, mesh: AbstractMesh, lightIndex: number, effect: Effect, depthValuesAlreadySet: boolean): boolean {
+            var shadowGenerator = light.getShadowGenerator();
+            if (mesh.receiveShadows && shadowGenerator) {
+                if (!(<any>light).needCube()) {
+                    effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                } else {
+                    if (!depthValuesAlreadySet) {
+                        depthValuesAlreadySet = true;
+                        effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                    }
+                }
+                effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
+                effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.blurScale / shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
+            }
+
+            return depthValuesAlreadySet;
+        }
+
+        public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
+            var lightIndex = 0;
+            var depthValuesAlreadySet = false;
+            for (var index = 0; index < scene.lights.length; index++) {
+                var light = scene.lights[index];
+
+                if (!light.isEnabled()) {
+                    continue;
+                }
+
+                if (!light.canAffectMesh(mesh)) {
+                    continue;
+                }
+
+                if (light instanceof PointLight) {
+                    // Point Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex);
+                } else if (light instanceof DirectionalLight) {
+                    // Directional Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex);
+                } else if (light instanceof SpotLight) {
+                    // Spot Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
+                } else if (light instanceof HemisphericLight) {
+                    // Hemispheric Light
+                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
+                }
+
+                light.diffuse.scaleToRef(light.intensity, Tmp.Color3[0]);
+                effect.setColor4("vLightDiffuse" + lightIndex, Tmp.Color3[0], light.range);
+                if (defines["SPECULARTERM"]) {
+                    light.specular.scaleToRef(light.intensity, Tmp.Color3[1]);
+                    effect.setColor3("vLightSpecular" + lightIndex, Tmp.Color3[1]);
+                }
+
+                // Shadows
+                if (scene.shadowsEnabled) {
+                    depthValuesAlreadySet = this.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
+                }
+
+                lightIndex++;
+
+                if (lightIndex === maxSimultaneousLights)
+                    break;
+            }
+        }
+
+        public static BindFogParameters(scene: Scene, mesh: AbstractMesh, effect: Effect): void {
+            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+                effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
+                effect.setColor3("vFogColor", scene.fogColor);
+            }
+        }
+        public static BindBonesParameters(mesh: AbstractMesh, effect: Effect): void {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+                effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
+            }
+        }
+
+    }
+}

+ 7 - 189
src/Materials/babylon.standardMaterial.js

@@ -5,7 +5,6 @@ var __extends = (this && this.__extends) || function (d, b) {
 };
 var BABYLON;
 (function (BABYLON) {
-    var maxSimultaneousLights = 4;
     var FresnelParameters = (function () {
         function FresnelParameters() {
             this.isEnabled = true;
@@ -203,174 +202,6 @@ var BABYLON;
             }
             return false;
         };
-        StandardMaterial.PrepareDefinesForLights = function (scene, mesh, defines) {
-            var lightIndex = 0;
-            var needNormals = false;
-            for (var index = 0; index < scene.lights.length; index++) {
-                var light = scene.lights[index];
-                if (!light.isEnabled()) {
-                    continue;
-                }
-                // Excluded check
-                if (light._excludedMeshesIds.length > 0) {
-                    for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
-                        var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
-                        if (excludedMesh) {
-                            light.excludedMeshes.push(excludedMesh);
-                        }
-                    }
-                    light._excludedMeshesIds = [];
-                }
-                // Included check
-                if (light._includedOnlyMeshesIds.length > 0) {
-                    for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
-                        var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
-                        if (includedOnlyMesh) {
-                            light.includedOnlyMeshes.push(includedOnlyMesh);
-                        }
-                    }
-                    light._includedOnlyMeshesIds = [];
-                }
-                if (!light.canAffectMesh(mesh)) {
-                    continue;
-                }
-                needNormals = true;
-                defines["LIGHT" + lightIndex] = true;
-                var type;
-                if (light instanceof BABYLON.SpotLight) {
-                    type = "SPOTLIGHT" + lightIndex;
-                }
-                else if (light instanceof BABYLON.HemisphericLight) {
-                    type = "HEMILIGHT" + lightIndex;
-                }
-                else if (light instanceof BABYLON.PointLight) {
-                    type = "POINTLIGHT" + lightIndex;
-                }
-                else {
-                    type = "DIRLIGHT" + lightIndex;
-                }
-                defines[type] = true;
-                // Specular
-                if (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined) {
-                    defines["SPECULARTERM"] = true;
-                }
-                // Shadows
-                if (scene.shadowsEnabled) {
-                    var shadowGenerator = light.getShadowGenerator();
-                    if (mesh && mesh.receiveShadows && shadowGenerator) {
-                        defines["SHADOW" + lightIndex] = true;
-                        defines["SHADOWS"] = true;
-                        if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
-                            defines["SHADOWVSM" + lightIndex] = true;
-                        }
-                        if (shadowGenerator.usePoissonSampling) {
-                            defines["SHADOWPCF" + lightIndex] = true;
-                        }
-                    }
-                }
-                lightIndex++;
-                if (lightIndex === maxSimultaneousLights)
-                    break;
-            }
-            return needNormals;
-        };
-        StandardMaterial.BindLightShadow = function (light, scene, mesh, lightIndex, effect, depthValuesAlreadySet) {
-            var shadowGenerator = light.getShadowGenerator();
-            if (mesh.receiveShadows && shadowGenerator) {
-                if (!light.needCube()) {
-                    effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                }
-                else {
-                    if (!depthValuesAlreadySet) {
-                        depthValuesAlreadySet = true;
-                        effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
-                    }
-                }
-                effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.blurScale / shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
-            }
-            return depthValuesAlreadySet;
-        };
-        StandardMaterial.BindLights = function (scene, mesh, effect, defines) {
-            var lightIndex = 0;
-            var depthValuesAlreadySet = false;
-            for (var index = 0; index < scene.lights.length; index++) {
-                var light = scene.lights[index];
-                if (!light.isEnabled()) {
-                    continue;
-                }
-                if (!light.canAffectMesh(mesh)) {
-                    continue;
-                }
-                if (light instanceof BABYLON.PointLight) {
-                    // Point Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex);
-                }
-                else if (light instanceof BABYLON.DirectionalLight) {
-                    // Directional Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex);
-                }
-                else if (light instanceof BABYLON.SpotLight) {
-                    // Spot Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
-                }
-                else if (light instanceof BABYLON.HemisphericLight) {
-                    // Hemispheric Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
-                }
-                light.diffuse.scaleToRef(light.intensity, StandardMaterial._scaledDiffuse);
-                effect.setColor4("vLightDiffuse" + lightIndex, StandardMaterial._scaledDiffuse, light.range);
-                if (defines["SPECULARTERM"]) {
-                    light.specular.scaleToRef(light.intensity, StandardMaterial._scaledSpecular);
-                    effect.setColor3("vLightSpecular" + lightIndex, StandardMaterial._scaledSpecular);
-                }
-                // Shadows
-                if (scene.shadowsEnabled) {
-                    depthValuesAlreadySet = this.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
-                }
-                lightIndex++;
-                if (lightIndex === maxSimultaneousLights)
-                    break;
-            }
-        };
-        StandardMaterial.HandleFallbacksForShadows = function (defines, fallbacks) {
-            for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
-                if (!defines["LIGHT" + lightIndex]) {
-                    continue;
-                }
-                if (lightIndex > 0) {
-                    fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
-                }
-                if (defines["SHADOW" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOW" + lightIndex);
-                }
-                if (defines["SHADOWPCF" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
-                }
-                if (defines["SHADOWVSM" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
-                }
-            }
-        };
-        StandardMaterial.PrepareAttributesForBones = function (attribs, mesh, defines, fallbacks) {
-            if (defines["NUM_BONE_INFLUENCERS"] > 0) {
-                fallbacks.addCPUSkinningFallback(0, mesh);
-                attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
-                attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
-                if (defines["NUM_BONE_INFLUENCERS"] > 4) {
-                    attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
-                    attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
-                }
-            }
-        };
-        StandardMaterial.PrepareAttributesForInstances = function (attribs, defines) {
-            if (defines["INSTANCES"]) {
-                attribs.push("world0");
-                attribs.push("world1");
-                attribs.push("world2");
-                attribs.push("world3");
-            }
-        };
         StandardMaterial.prototype.isReady = function (mesh, useInstances) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady) {
@@ -544,7 +375,7 @@ var BABYLON;
                 this._defines.FOG = true;
             }
             if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = StandardMaterial.PrepareDefinesForLights(scene, mesh, this._defines);
+                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines);
             }
             if (StandardMaterial.FresnelEnabled) {
                 // Fresnel
@@ -630,7 +461,7 @@ var BABYLON;
                 if (this._defines.LOGARITHMICDEPTH) {
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
-                StandardMaterial.HandleFallbacksForShadows(this._defines, fallbacks);
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
                 if (this._defines.SPECULARTERM) {
                     fallbacks.addFallback(0, "SPECULARTERM");
                 }
@@ -663,8 +494,8 @@ var BABYLON;
                 if (this._defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
-                StandardMaterial.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                StandardMaterial.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
                 // Legacy browser patch
                 var shaderName = "default";
                 if (!scene.getEngine().getCaps().standardDerivatives) {
@@ -717,7 +548,7 @@ var BABYLON;
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             // Bones
-            StandardMaterial.ApplyBonesParameters(mesh, this._effect);
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
             if (scene.getCachedMaterial() !== this) {
                 this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                 if (StandardMaterial.FresnelEnabled) {
@@ -827,14 +658,14 @@ var BABYLON;
                 this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
                 // Lights
                 if (scene.lightsEnabled && !this.disableLighting) {
-                    StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);
+                    BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
                 }
                 // View
                 if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE || this.reflectionTexture || this.refractionTexture) {
                     this._effect.setMatrix("view", scene.getViewMatrix());
                 }
                 // Fog
-                StandardMaterial.ApplyFogParameters(scene, mesh, this._effect);
+                BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
                 // Log. depth
                 if (this._defines.LOGARITHMICDEPTH) {
                     this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
@@ -842,17 +673,6 @@ var BABYLON;
             }
             _super.prototype.bind.call(this, world, mesh);
         };
-        StandardMaterial.ApplyFogParameters = function (scene, mesh, effect) {
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                effect.setColor3("vFogColor", scene.fogColor);
-            }
-        };
-        StandardMaterial.ApplyBonesParameters = function (mesh, effect) {
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
-            }
-        };
         StandardMaterial.prototype.getAnimatables = function () {
             var results = [];
             if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
@@ -1100,8 +920,6 @@ var BABYLON;
             }
             return material;
         };
-        StandardMaterial._scaledDiffuse = new BABYLON.Color3();
-        StandardMaterial._scaledSpecular = new BABYLON.Color3();
         // Statics
         // Flags used to enable or disable a type of texture for all Standard Materials
         StandardMaterial.DiffuseTextureEnabled = true;

+ 7 - 221
src/Materials/babylon.standardMaterial.ts

@@ -1,6 +1,4 @@
 module BABYLON {
-    var maxSimultaneousLights = 4;
-
     export class FresnelParameters {
         public isEnabled = true;
         public leftColor = Color3.White();
@@ -240,206 +238,6 @@
             return false;
         }
 
-        public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines): boolean {
-            var lightIndex = 0;
-            var needNormals = false;
-            for (var index = 0; index < scene.lights.length; index++) {
-                var light = scene.lights[index];
-
-                if (!light.isEnabled()) {
-                    continue;
-                }
-
-                // Excluded check
-                if (light._excludedMeshesIds.length > 0) {
-                    for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
-                        var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
-
-                        if (excludedMesh) {
-                            light.excludedMeshes.push(excludedMesh);
-                        }
-                    }
-
-                    light._excludedMeshesIds = [];
-                }
-
-                // Included check
-                if (light._includedOnlyMeshesIds.length > 0) {
-                    for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
-                        var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
-
-                        if (includedOnlyMesh) {
-                            light.includedOnlyMeshes.push(includedOnlyMesh);
-                        }
-                    }
-
-                    light._includedOnlyMeshesIds = [];
-                }
-
-                if (!light.canAffectMesh(mesh)) {
-                    continue;
-                }
-                needNormals = true;
-                defines["LIGHT" + lightIndex] = true;
-
-                var type;
-                if (light instanceof SpotLight) {
-                    type = "SPOTLIGHT" + lightIndex;
-                } else if (light instanceof HemisphericLight) {
-                    type = "HEMILIGHT" + lightIndex;
-                } else if (light instanceof PointLight) {
-                    type = "POINTLIGHT" + lightIndex;
-                } else {
-                    type = "DIRLIGHT" + lightIndex;
-                }
-
-                defines[type] = true;
-
-                // Specular
-                if (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined) {
-                    defines["SPECULARTERM"] = true;
-                }
-
-                // Shadows
-                if (scene.shadowsEnabled) {
-                    var shadowGenerator = light.getShadowGenerator();
-                    if (mesh && mesh.receiveShadows && shadowGenerator) {
-                        defines["SHADOW" + lightIndex] = true;
-
-                        defines["SHADOWS"] = true;
-
-                        if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
-                            defines["SHADOWVSM" + lightIndex] = true;
-                        }
-
-                        if (shadowGenerator.usePoissonSampling) {
-                            defines["SHADOWPCF" + lightIndex] = true;
-                        }
-                    }
-                }
-
-                lightIndex++;
-                if (lightIndex === maxSimultaneousLights)
-                    break;
-            }
-
-            return needNormals;
-        }
-
-        private static _scaledDiffuse = new Color3();
-        private static _scaledSpecular = new Color3();
-
-        public static BindLightShadow(light: Light, scene: Scene, mesh: AbstractMesh, lightIndex: number, effect: Effect, depthValuesAlreadySet: boolean): boolean {
-            var shadowGenerator = light.getShadowGenerator();
-            if (mesh.receiveShadows && shadowGenerator) {
-                if (!(<any>light).needCube()) {
-                    effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
-                } else {
-                    if (!depthValuesAlreadySet) {
-                        depthValuesAlreadySet = true;
-                        effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
-                    }
-                }
-                effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.blurScale / shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
-            }
-
-            return depthValuesAlreadySet;
-        }
-
-        public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
-            var lightIndex = 0;
-            var depthValuesAlreadySet = false;
-            for (var index = 0; index < scene.lights.length; index++) {
-                var light = scene.lights[index];
-
-                if (!light.isEnabled()) {
-                    continue;
-                }
-
-                if (!light.canAffectMesh(mesh)) {
-                    continue;
-                }
-
-                if (light instanceof PointLight) {
-                    // Point Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex);
-                } else if (light instanceof DirectionalLight) {
-                    // Directional Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex);
-                } else if (light instanceof SpotLight) {
-                    // Spot Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
-                } else if (light instanceof HemisphericLight) {
-                    // Hemispheric Light
-                    light.transferToEffect(effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
-                }
-
-                light.diffuse.scaleToRef(light.intensity, StandardMaterial._scaledDiffuse);
-                effect.setColor4("vLightDiffuse" + lightIndex, StandardMaterial._scaledDiffuse, light.range);
-                if (defines["SPECULARTERM"]) {
-                    light.specular.scaleToRef(light.intensity, StandardMaterial._scaledSpecular);
-                    effect.setColor3("vLightSpecular" + lightIndex, StandardMaterial._scaledSpecular);
-                }
-
-                // Shadows
-                if (scene.shadowsEnabled) {
-                    depthValuesAlreadySet = this.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
-                }
-
-                lightIndex++;
-
-                if (lightIndex === maxSimultaneousLights)
-                    break;
-            }
-        }
-
-        public static HandleFallbacksForShadows(defines: MaterialDefines, fallbacks: EffectFallbacks): void {
-            for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
-                if (!defines["LIGHT" + lightIndex]) {
-                    continue;
-                }
-
-                if (lightIndex > 0) {
-                    fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
-                }
-
-                if (defines["SHADOW" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOW" + lightIndex);
-                }
-
-                if (defines["SHADOWPCF" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
-                }
-
-                if (defines["SHADOWVSM" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
-                }
-            }
-        }
-
-        public static PrepareAttributesForBones(attribs: string[], mesh: AbstractMesh, defines: MaterialDefines, fallbacks: EffectFallbacks): void {
-            if (defines["NUM_BONE_INFLUENCERS"] > 0) {
-                fallbacks.addCPUSkinningFallback(0, mesh);
-
-                attribs.push(VertexBuffer.MatricesIndicesKind);
-                attribs.push(VertexBuffer.MatricesWeightsKind);
-                if (defines["NUM_BONE_INFLUENCERS"] > 4) {
-                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                }
-            }
-        }
-
-        public static PrepareAttributesForInstances(attribs: string[], defines: MaterialDefines): void {
-            if (defines["INSTANCES"]) {
-                attribs.push("world0");
-                attribs.push("world1");
-                attribs.push("world2");
-                attribs.push("world3");
-            }
-        }
-
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady) {
@@ -633,7 +431,7 @@
             }
 
             if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = StandardMaterial.PrepareDefinesForLights(scene, mesh, this._defines);
+                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines);
             }
 
             if (StandardMaterial.FresnelEnabled) {
@@ -740,7 +538,7 @@
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
 
-                StandardMaterial.HandleFallbacksForShadows(this._defines, fallbacks);
+                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
 
                 if (this._defines.SPECULARTERM) {
                     fallbacks.addFallback(0, "SPECULARTERM");
@@ -785,8 +583,8 @@
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                StandardMaterial.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                StandardMaterial.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
                 
                 // Legacy browser patch
                 var shaderName = "default";
@@ -856,7 +654,7 @@
             this.bindOnlyWorldMatrix(world);
 
             // Bones
-            StandardMaterial.ApplyBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._effect);
 
             if (scene.getCachedMaterial() !== this) {
                 this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
@@ -995,7 +793,7 @@
 
                 // Lights
                 if (scene.lightsEnabled && !this.disableLighting) {
-                    StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);
+                    MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
                 }
 
                 // View
@@ -1004,7 +802,7 @@
                 }
 
                 // Fog
-                StandardMaterial.ApplyFogParameters(scene, mesh, this._effect);
+                MaterialHelper.BindFogParameters(scene, mesh, this._effect);
 
                 // Log. depth
                 if (this._defines.LOGARITHMICDEPTH) {
@@ -1015,18 +813,6 @@
             super.bind(world, mesh);
         }
 
-        public static ApplyFogParameters(scene: Scene, mesh: AbstractMesh, effect: Effect): void {
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                effect.setColor3("vFogColor", scene.fogColor);
-            }
-        }
-        public static ApplyBonesParameters(mesh: AbstractMesh, effect: Effect): void {
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
-            }
-        }
-
         public getAnimatables(): IAnimatable[] {
             var results = [];
 

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

@@ -3027,6 +3027,7 @@ var BABYLON;
     var Tmp = (function () {
         function Tmp() {
         }
+        Tmp.Color3 = [Color3.Black(), Color3.Black(), Color3.Black()];
         Tmp.Vector2 = [Vector2.Zero(), Vector2.Zero(), Vector2.Zero()]; // 3 temp Vector2 at once should be enough
         Tmp.Vector3 = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),
             Vector3.Zero(), Vector3.Zero(), Vector3.Zero()]; // 6 temp Vector3 at once should be enough

+ 1 - 0
src/Math/babylon.math.ts

@@ -3703,6 +3703,7 @@
     // var tmp = Tmp.Vector3[0];   <= gets access to the first pre-created Vector3
     // There's a Tmp array per object type : int, float, Vector2, Vector3, Vector4, Quaternion, Matrix
     export class Tmp {
+        public static Color3: Color3[] = [Color3.Black(), Color3.Black(), Color3.Black()];
         public static Vector2: Vector2[] = [Vector2.Zero(), Vector2.Zero(), Vector2.Zero()];  // 3 temp Vector2 at once should be enough
         public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero()
             , Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];    // 6 temp Vector3 at once should be enough