David Catuhe 7 anni fa
parent
commit
9f6ca1c622

File diff suppressed because it is too large
+ 8816 - 8811
Playground/babylon.d.txt


File diff suppressed because it is too large
+ 8840 - 8835
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.js


+ 53 - 29
dist/preview release/babylon.max.js

@@ -56499,21 +56499,25 @@ var BABYLON;
             return particleEmitter;
         };
         /**
-         * Source color is added to the destination color without alpha affecting the result.
+         * Source color is added to the destination color without alpha affecting the result
          */
         BaseParticleSystem.BLENDMODE_ONEONE = 0;
         /**
-         * Blend current color and particle color using particle’s alpha.
+         * Blend current color and particle color using particle’s alpha
          */
         BaseParticleSystem.BLENDMODE_STANDARD = 1;
         /**
-         * Add current color and particle color multiplied by particle’s alpha.
+         * Add current color and particle color multiplied by particle’s alpha
          */
         BaseParticleSystem.BLENDMODE_ADD = 2;
         /**
          * Multiply current color with particle color
          */
         BaseParticleSystem.BLENDMODE_MULTIPLY = 3;
+        /**
+         * Multiply current color with particle color then add current color and particle color multiplied by particle’s alpha
+         */
+        BaseParticleSystem.BLENDMODE_MULTIPLYADD = 4;
         return BaseParticleSystem;
     }());
     BABYLON.BaseParticleSystem = BaseParticleSystem;
@@ -57472,6 +57476,12 @@ var BABYLON;
                     this._vertexData[offset++] = particle.direction.z;
                 }
             }
+            if (this._useRampGradients) {
+                this._vertexData[offset++] = particle.remapData.x;
+                this._vertexData[offset++] = particle.remapData.y;
+                this._vertexData[offset++] = particle.remapData.z;
+                this._vertexData[offset++] = particle.remapData.w;
+            }
             if (!this._useInstancing) {
                 if (this._isAnimationSheetEnabled) {
                     if (offsetX === 0)
@@ -57486,12 +57496,6 @@ var BABYLON;
                 this._vertexData[offset++] = offsetX;
                 this._vertexData[offset++] = offsetY;
             }
-            if (this._useRampGradients) {
-                this._vertexData[offset++] = particle.remapData.x;
-                this._vertexData[offset++] = particle.remapData.y;
-                this._vertexData[offset++] = particle.remapData.z;
-                this._vertexData[offset++] = particle.remapData.w;
-            }
         };
         ParticleSystem.prototype._stopSubEmitters = function () {
             if (!this.activeSubSystems) {
@@ -57715,7 +57719,7 @@ var BABYLON;
             }
             return effectCreationOption;
         };
-        ParticleSystem.prototype._getEffect = function () {
+        ParticleSystem.prototype._getEffect = function (blendMode) {
             if (this._customEffect) {
                 return this._customEffect;
             }
@@ -57736,7 +57740,7 @@ var BABYLON;
             if (this._isAnimationSheetEnabled) {
                 defines.push("#define ANIMATESHEET");
             }
-            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
+            if (blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
                 defines.push("#define BLENDMULTIPLYMODE");
             }
             if (this._useRampGradients) {
@@ -57782,9 +57786,8 @@ var BABYLON;
             if (!this._started)
                 return;
             if (!preWarmOnly) {
-                var effect = this._getEffect();
                 // Check
-                if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady())
+                if (!this.isReady())
                     return;
                 if (this._currentRenderId === this._scene.getRenderId()) {
                     return;
@@ -57879,26 +57882,29 @@ var BABYLON;
          * @return true if the system is ready
          */
         ParticleSystem.prototype.isReady = function () {
-            var effect = this._getEffect();
-            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
+            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
                 return false;
             }
+            if (this.blendMode !== ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                if (!this._getEffect(this.blendMode).isReady()) {
+                    return false;
+                }
+            }
+            else {
+                if (!this._getEffect(ParticleSystem.BLENDMODE_MULTIPLY).isReady()) {
+                    return false;
+                }
+                if (!this._getEffect(ParticleSystem.BLENDMODE_ADD).isReady()) {
+                    return false;
+                }
+            }
             return true;
         };
-        /**
-         * Renders the particle system in its current state.
-         * @returns the current number of particles
-         */
-        ParticleSystem.prototype.render = function () {
-            var effect = this._getEffect();
-            // Check
-            if (!this.isReady() || !this._particles.length) {
-                return 0;
-            }
+        ParticleSystem.prototype._render = function (blendMode) {
+            var effect = this._getEffect(blendMode);
             var engine = this._scene.getEngine();
             // Render
             engine.enableEffect(effect);
-            engine.setState(false);
             var viewMatrix = this._scene.getViewMatrix();
             effect.setTexture("diffuseSampler", this.particleTexture);
             effect.setMatrix("view", viewMatrix);
@@ -57928,7 +57934,7 @@ var BABYLON;
                 this._imageProcessingConfiguration.bind(effect);
             }
             // Draw order
-            switch (this.blendMode) {
+            switch (blendMode) {
                 case ParticleSystem.BLENDMODE_ADD:
                     engine.setAlphaMode(BABYLON.Engine.ALPHA_ADD);
                     break;
@@ -57947,15 +57953,33 @@ var BABYLON;
             }
             if (this._useInstancing) {
                 engine.drawArraysType(BABYLON.Material.TriangleFanDrawMode, 0, 4, this._particles.length);
-                engine.unbindInstanceAttributes();
             }
             else {
                 engine.drawElementsType(BABYLON.Material.TriangleFillMode, 0, this._particles.length * 6);
             }
-            engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
             return this._particles.length;
         };
         /**
+         * Renders the particle system in its current state.
+         * @returns the current number of particles
+         */
+        ParticleSystem.prototype.render = function () {
+            // Check
+            if (!this.isReady() || !this._particles.length) {
+                return 0;
+            }
+            var engine = this._scene.getEngine();
+            engine.setState(false);
+            var outparticles = 0;
+            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                outparticles = this._render(ParticleSystem.BLENDMODE_MULTIPLY) + this._render(ParticleSystem.BLENDMODE_ADD);
+            }
+            outparticles = this._render(this.blendMode);
+            engine.unbindInstanceAttributes();
+            engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
+            return outparticles;
+        };
+        /**
          * Disposes the particle system and free the associated resources
          * @param disposeTexture defines if the particule texture must be disposed as well (true by default)
          */

+ 53 - 29
dist/preview release/babylon.no-module.max.js

@@ -56466,21 +56466,25 @@ var BABYLON;
             return particleEmitter;
         };
         /**
-         * Source color is added to the destination color without alpha affecting the result.
+         * Source color is added to the destination color without alpha affecting the result
          */
         BaseParticleSystem.BLENDMODE_ONEONE = 0;
         /**
-         * Blend current color and particle color using particle’s alpha.
+         * Blend current color and particle color using particle’s alpha
          */
         BaseParticleSystem.BLENDMODE_STANDARD = 1;
         /**
-         * Add current color and particle color multiplied by particle’s alpha.
+         * Add current color and particle color multiplied by particle’s alpha
          */
         BaseParticleSystem.BLENDMODE_ADD = 2;
         /**
          * Multiply current color with particle color
          */
         BaseParticleSystem.BLENDMODE_MULTIPLY = 3;
+        /**
+         * Multiply current color with particle color then add current color and particle color multiplied by particle’s alpha
+         */
+        BaseParticleSystem.BLENDMODE_MULTIPLYADD = 4;
         return BaseParticleSystem;
     }());
     BABYLON.BaseParticleSystem = BaseParticleSystem;
@@ -57439,6 +57443,12 @@ var BABYLON;
                     this._vertexData[offset++] = particle.direction.z;
                 }
             }
+            if (this._useRampGradients) {
+                this._vertexData[offset++] = particle.remapData.x;
+                this._vertexData[offset++] = particle.remapData.y;
+                this._vertexData[offset++] = particle.remapData.z;
+                this._vertexData[offset++] = particle.remapData.w;
+            }
             if (!this._useInstancing) {
                 if (this._isAnimationSheetEnabled) {
                     if (offsetX === 0)
@@ -57453,12 +57463,6 @@ var BABYLON;
                 this._vertexData[offset++] = offsetX;
                 this._vertexData[offset++] = offsetY;
             }
-            if (this._useRampGradients) {
-                this._vertexData[offset++] = particle.remapData.x;
-                this._vertexData[offset++] = particle.remapData.y;
-                this._vertexData[offset++] = particle.remapData.z;
-                this._vertexData[offset++] = particle.remapData.w;
-            }
         };
         ParticleSystem.prototype._stopSubEmitters = function () {
             if (!this.activeSubSystems) {
@@ -57682,7 +57686,7 @@ var BABYLON;
             }
             return effectCreationOption;
         };
-        ParticleSystem.prototype._getEffect = function () {
+        ParticleSystem.prototype._getEffect = function (blendMode) {
             if (this._customEffect) {
                 return this._customEffect;
             }
@@ -57703,7 +57707,7 @@ var BABYLON;
             if (this._isAnimationSheetEnabled) {
                 defines.push("#define ANIMATESHEET");
             }
-            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
+            if (blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
                 defines.push("#define BLENDMULTIPLYMODE");
             }
             if (this._useRampGradients) {
@@ -57749,9 +57753,8 @@ var BABYLON;
             if (!this._started)
                 return;
             if (!preWarmOnly) {
-                var effect = this._getEffect();
                 // Check
-                if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady())
+                if (!this.isReady())
                     return;
                 if (this._currentRenderId === this._scene.getRenderId()) {
                     return;
@@ -57846,26 +57849,29 @@ var BABYLON;
          * @return true if the system is ready
          */
         ParticleSystem.prototype.isReady = function () {
-            var effect = this._getEffect();
-            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
+            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
                 return false;
             }
+            if (this.blendMode !== ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                if (!this._getEffect(this.blendMode).isReady()) {
+                    return false;
+                }
+            }
+            else {
+                if (!this._getEffect(ParticleSystem.BLENDMODE_MULTIPLY).isReady()) {
+                    return false;
+                }
+                if (!this._getEffect(ParticleSystem.BLENDMODE_ADD).isReady()) {
+                    return false;
+                }
+            }
             return true;
         };
-        /**
-         * Renders the particle system in its current state.
-         * @returns the current number of particles
-         */
-        ParticleSystem.prototype.render = function () {
-            var effect = this._getEffect();
-            // Check
-            if (!this.isReady() || !this._particles.length) {
-                return 0;
-            }
+        ParticleSystem.prototype._render = function (blendMode) {
+            var effect = this._getEffect(blendMode);
             var engine = this._scene.getEngine();
             // Render
             engine.enableEffect(effect);
-            engine.setState(false);
             var viewMatrix = this._scene.getViewMatrix();
             effect.setTexture("diffuseSampler", this.particleTexture);
             effect.setMatrix("view", viewMatrix);
@@ -57895,7 +57901,7 @@ var BABYLON;
                 this._imageProcessingConfiguration.bind(effect);
             }
             // Draw order
-            switch (this.blendMode) {
+            switch (blendMode) {
                 case ParticleSystem.BLENDMODE_ADD:
                     engine.setAlphaMode(BABYLON.Engine.ALPHA_ADD);
                     break;
@@ -57914,15 +57920,33 @@ var BABYLON;
             }
             if (this._useInstancing) {
                 engine.drawArraysType(BABYLON.Material.TriangleFanDrawMode, 0, 4, this._particles.length);
-                engine.unbindInstanceAttributes();
             }
             else {
                 engine.drawElementsType(BABYLON.Material.TriangleFillMode, 0, this._particles.length * 6);
             }
-            engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
             return this._particles.length;
         };
         /**
+         * Renders the particle system in its current state.
+         * @returns the current number of particles
+         */
+        ParticleSystem.prototype.render = function () {
+            // Check
+            if (!this.isReady() || !this._particles.length) {
+                return 0;
+            }
+            var engine = this._scene.getEngine();
+            engine.setState(false);
+            var outparticles = 0;
+            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                outparticles = this._render(ParticleSystem.BLENDMODE_MULTIPLY) + this._render(ParticleSystem.BLENDMODE_ADD);
+            }
+            outparticles = this._render(this.blendMode);
+            engine.unbindInstanceAttributes();
+            engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
+            return outparticles;
+        };
+        /**
          * Disposes the particle system and free the associated resources
          * @param disposeTexture defines if the particule texture must be disposed as well (true by default)
          */

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.worker.js


+ 53 - 29
dist/preview release/es6.js

@@ -56466,21 +56466,25 @@ var BABYLON;
             return particleEmitter;
         };
         /**
-         * Source color is added to the destination color without alpha affecting the result.
+         * Source color is added to the destination color without alpha affecting the result
          */
         BaseParticleSystem.BLENDMODE_ONEONE = 0;
         /**
-         * Blend current color and particle color using particle’s alpha.
+         * Blend current color and particle color using particle’s alpha
          */
         BaseParticleSystem.BLENDMODE_STANDARD = 1;
         /**
-         * Add current color and particle color multiplied by particle’s alpha.
+         * Add current color and particle color multiplied by particle’s alpha
          */
         BaseParticleSystem.BLENDMODE_ADD = 2;
         /**
          * Multiply current color with particle color
          */
         BaseParticleSystem.BLENDMODE_MULTIPLY = 3;
+        /**
+         * Multiply current color with particle color then add current color and particle color multiplied by particle’s alpha
+         */
+        BaseParticleSystem.BLENDMODE_MULTIPLYADD = 4;
         return BaseParticleSystem;
     }());
     BABYLON.BaseParticleSystem = BaseParticleSystem;
@@ -57439,6 +57443,12 @@ var BABYLON;
                     this._vertexData[offset++] = particle.direction.z;
                 }
             }
+            if (this._useRampGradients) {
+                this._vertexData[offset++] = particle.remapData.x;
+                this._vertexData[offset++] = particle.remapData.y;
+                this._vertexData[offset++] = particle.remapData.z;
+                this._vertexData[offset++] = particle.remapData.w;
+            }
             if (!this._useInstancing) {
                 if (this._isAnimationSheetEnabled) {
                     if (offsetX === 0)
@@ -57453,12 +57463,6 @@ var BABYLON;
                 this._vertexData[offset++] = offsetX;
                 this._vertexData[offset++] = offsetY;
             }
-            if (this._useRampGradients) {
-                this._vertexData[offset++] = particle.remapData.x;
-                this._vertexData[offset++] = particle.remapData.y;
-                this._vertexData[offset++] = particle.remapData.z;
-                this._vertexData[offset++] = particle.remapData.w;
-            }
         };
         ParticleSystem.prototype._stopSubEmitters = function () {
             if (!this.activeSubSystems) {
@@ -57682,7 +57686,7 @@ var BABYLON;
             }
             return effectCreationOption;
         };
-        ParticleSystem.prototype._getEffect = function () {
+        ParticleSystem.prototype._getEffect = function (blendMode) {
             if (this._customEffect) {
                 return this._customEffect;
             }
@@ -57703,7 +57707,7 @@ var BABYLON;
             if (this._isAnimationSheetEnabled) {
                 defines.push("#define ANIMATESHEET");
             }
-            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
+            if (blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
                 defines.push("#define BLENDMULTIPLYMODE");
             }
             if (this._useRampGradients) {
@@ -57749,9 +57753,8 @@ var BABYLON;
             if (!this._started)
                 return;
             if (!preWarmOnly) {
-                var effect = this._getEffect();
                 // Check
-                if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady())
+                if (!this.isReady())
                     return;
                 if (this._currentRenderId === this._scene.getRenderId()) {
                     return;
@@ -57846,26 +57849,29 @@ var BABYLON;
          * @return true if the system is ready
          */
         ParticleSystem.prototype.isReady = function () {
-            var effect = this._getEffect();
-            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
+            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
                 return false;
             }
+            if (this.blendMode !== ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                if (!this._getEffect(this.blendMode).isReady()) {
+                    return false;
+                }
+            }
+            else {
+                if (!this._getEffect(ParticleSystem.BLENDMODE_MULTIPLY).isReady()) {
+                    return false;
+                }
+                if (!this._getEffect(ParticleSystem.BLENDMODE_ADD).isReady()) {
+                    return false;
+                }
+            }
             return true;
         };
-        /**
-         * Renders the particle system in its current state.
-         * @returns the current number of particles
-         */
-        ParticleSystem.prototype.render = function () {
-            var effect = this._getEffect();
-            // Check
-            if (!this.isReady() || !this._particles.length) {
-                return 0;
-            }
+        ParticleSystem.prototype._render = function (blendMode) {
+            var effect = this._getEffect(blendMode);
             var engine = this._scene.getEngine();
             // Render
             engine.enableEffect(effect);
-            engine.setState(false);
             var viewMatrix = this._scene.getViewMatrix();
             effect.setTexture("diffuseSampler", this.particleTexture);
             effect.setMatrix("view", viewMatrix);
@@ -57895,7 +57901,7 @@ var BABYLON;
                 this._imageProcessingConfiguration.bind(effect);
             }
             // Draw order
-            switch (this.blendMode) {
+            switch (blendMode) {
                 case ParticleSystem.BLENDMODE_ADD:
                     engine.setAlphaMode(BABYLON.Engine.ALPHA_ADD);
                     break;
@@ -57914,15 +57920,33 @@ var BABYLON;
             }
             if (this._useInstancing) {
                 engine.drawArraysType(BABYLON.Material.TriangleFanDrawMode, 0, 4, this._particles.length);
-                engine.unbindInstanceAttributes();
             }
             else {
                 engine.drawElementsType(BABYLON.Material.TriangleFillMode, 0, this._particles.length * 6);
             }
-            engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
             return this._particles.length;
         };
         /**
+         * Renders the particle system in its current state.
+         * @returns the current number of particles
+         */
+        ParticleSystem.prototype.render = function () {
+            // Check
+            if (!this.isReady() || !this._particles.length) {
+                return 0;
+            }
+            var engine = this._scene.getEngine();
+            engine.setState(false);
+            var outparticles = 0;
+            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                outparticles = this._render(ParticleSystem.BLENDMODE_MULTIPLY) + this._render(ParticleSystem.BLENDMODE_ADD);
+            }
+            outparticles = this._render(this.blendMode);
+            engine.unbindInstanceAttributes();
+            engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
+            return outparticles;
+        };
+        /**
          * Disposes the particle system and free the associated resources
          * @param disposeTexture defines if the particule texture must be disposed as well (true by default)
          */

+ 21 - 0
dist/preview release/viewer/babylon.viewer.d.ts

@@ -1212,6 +1212,27 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
+    /**
+        * The configuration loader will load the configuration object from any source and will use the defined mapper to
+        * parse the object and return a conform ViewerConfiguration.
+        * It is a private member of the scene.
+        */
+    export class ConfigurationLoader {
+            constructor(_enableCache?: boolean);
+            /**
+                * load a configuration object that is defined in the initial configuration provided.
+                * The viewer configuration can extend different types of configuration objects and have an extra configuration defined.
+                *
+                * @param initConfig the initial configuration that has the definitions of further configuration to load.
+                * @param callback an optional callback that will be called sync, if noconfiguration needs to be loaded or configuration is payload-only
+                * @returns A promise that delivers the extended viewer configuration, when done.
+                */
+            loadConfiguration(initConfig?: ViewerConfiguration, callback?: (config: ViewerConfiguration) => void): Promise<ViewerConfiguration>;
+            /**
+                * Dispose the configuration loader. This will cancel file requests, if active.
+                */
+            dispose(): void;
+    }
 }
 declare module BabylonViewer {
     export class ObservablesManager {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 22 - 1
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -1295,7 +1295,28 @@ declare module 'babylonjs-viewer/configuration/configurationContainer' {
 }
 
 declare module 'babylonjs-viewer/configuration/loader' {
-    
+    import { ViewerConfiguration } from 'babylonjs-viewer/configuration/configuration';
+    /**
+        * The configuration loader will load the configuration object from any source and will use the defined mapper to
+        * parse the object and return a conform ViewerConfiguration.
+        * It is a private member of the scene.
+        */
+    export class ConfigurationLoader {
+            constructor(_enableCache?: boolean);
+            /**
+                * load a configuration object that is defined in the initial configuration provided.
+                * The viewer configuration can extend different types of configuration objects and have an extra configuration defined.
+                *
+                * @param initConfig the initial configuration that has the definitions of further configuration to load.
+                * @param callback an optional callback that will be called sync, if noconfiguration needs to be loaded or configuration is payload-only
+                * @returns A promise that delivers the extended viewer configuration, when done.
+                */
+            loadConfiguration(initConfig?: ViewerConfiguration, callback?: (config: ViewerConfiguration) => void): Promise<ViewerConfiguration>;
+            /**
+                * Dispose the configuration loader. This will cancel file requests, if active.
+                */
+            dispose(): void;
+    }
 }
 
 declare module 'babylonjs-viewer/managers/observablesManager' {

+ 8 - 3
src/Particles/babylon.baseParticleSystem.ts

@@ -7,15 +7,15 @@ module BABYLON {
      */
     export class BaseParticleSystem {
         /**
-         * Source color is added to the destination color without alpha affecting the result.
+         * Source color is added to the destination color without alpha affecting the result
          */
         public static BLENDMODE_ONEONE = 0;
         /**
-         * Blend current color and particle color using particle’s alpha.
+         * Blend current color and particle color using particle’s alpha
          */
         public static BLENDMODE_STANDARD = 1;
         /**
-         * Add current color and particle color multiplied by particle’s alpha.
+         * Add current color and particle color multiplied by particle’s alpha
          */
         public static BLENDMODE_ADD = 2;
         /**
@@ -24,6 +24,11 @@ module BABYLON {
         public static BLENDMODE_MULTIPLY = 3;        
 
         /**
+         * Multiply current color with particle color then add current color and particle color multiplied by particle’s alpha
+         */
+        public static BLENDMODE_MULTIPLYADD = 4;                
+
+        /**
          * List of animations used by the particle system.
          */
         public animations: Animation[] = [];

+ 54 - 29
src/Particles/babylon.particleSystem.ts

@@ -1093,6 +1093,13 @@
                 }
             }
 
+            if (this._useRampGradients) {
+                this._vertexData[offset++] = particle.remapData.x;
+                this._vertexData[offset++] = particle.remapData.y;
+                this._vertexData[offset++] = particle.remapData.z;
+                this._vertexData[offset++] = particle.remapData.w;
+            }
+
             if (!this._useInstancing) {
                 if (this._isAnimationSheetEnabled) {
                     if (offsetX === 0)
@@ -1109,13 +1116,6 @@
                 this._vertexData[offset++] = offsetX;
                 this._vertexData[offset++] = offsetY;
             }
-
-            if (this._useRampGradients) {
-                this._vertexData[offset++] = particle.remapData.x;
-                this._vertexData[offset++] = particle.remapData.y;
-                this._vertexData[offset++] = particle.remapData.z;
-                this._vertexData[offset++] = particle.remapData.w;
-            }
         }
 
         // start of sub system methods
@@ -1415,7 +1415,7 @@
             return effectCreationOption;
         }
 
-        private _getEffect(): Effect {
+        private _getEffect(blendMode: number): Effect {
             if (this._customEffect) {
                 return this._customEffect;
             };
@@ -1442,7 +1442,7 @@
                 defines.push("#define ANIMATESHEET");
             }
 
-            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
+            if (blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
                 defines.push("#define BLENDMULTIPLYMODE");
             }
 
@@ -1502,10 +1502,8 @@
                 return;
 
             if (!preWarmOnly) {
-                var effect = this._getEffect();
-
                 // Check
-                if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady())
+                if (!this.isReady())
                     return;
 
                 if (this._currentRenderId === this._scene.getRenderId()) {
@@ -1617,31 +1615,33 @@
          * @return true if the system is ready
          */
         public isReady(): boolean {
-            var effect = this._getEffect();
-            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !effect.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
+            if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
                 return false;
             }
 
+            if (this.blendMode !== ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                if (!this._getEffect(this.blendMode).isReady()) {
+                    return false;
+                }                
+            } else {
+                if (!this._getEffect(ParticleSystem.BLENDMODE_MULTIPLY).isReady()) {
+                    return false;
+                } 
+                if (!this._getEffect(ParticleSystem.BLENDMODE_ADD).isReady()) {
+                    return false;
+                }                 
+            }
+
             return true;
         }
 
-        /**
-         * Renders the particle system in its current state.
-         * @returns the current number of particles
-         */
-        public render(): number {
-            var effect = this._getEffect();
-
-            // Check
-            if (!this.isReady() || !this._particles.length) {
-                return 0;
-            }
+        private _render(blendMode: number) {
+            var effect = this._getEffect(blendMode);
 
             var engine = this._scene.getEngine();
 
             // Render
             engine.enableEffect(effect);
-            engine.setState(false);
 
             var viewMatrix = this._scene.getViewMatrix();
             effect.setTexture("diffuseSampler", this.particleTexture);
@@ -1680,7 +1680,7 @@
             }
 
             // Draw order
-            switch (this.blendMode) {
+            switch (blendMode) {
                 case ParticleSystem.BLENDMODE_ADD:
                     engine.setAlphaMode(Engine.ALPHA_ADD);
                     break;
@@ -1701,16 +1701,41 @@
 
             if (this._useInstancing) {
                 engine.drawArraysType(Material.TriangleFanDrawMode, 0, 4, this._particles.length);
-                engine.unbindInstanceAttributes();
+
             } else {
                 engine.drawElementsType(Material.TriangleFillMode, 0, this._particles.length * 6);
             }
-            engine.setAlphaMode(Engine.ALPHA_DISABLE);
 
             return this._particles.length;
         }
 
         /**
+         * Renders the particle system in its current state.
+         * @returns the current number of particles
+         */
+        public render(): number {
+            // Check
+            if (!this.isReady() || !this._particles.length) {
+                return 0;
+            }
+
+            var engine = this._scene.getEngine();
+            engine.setState(false);
+
+            let outparticles = 0;
+
+            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLYADD) {
+                outparticles = this._render(ParticleSystem.BLENDMODE_MULTIPLY) + this._render(ParticleSystem.BLENDMODE_ADD);    
+            }
+            outparticles = this._render(this.blendMode);
+
+            engine.unbindInstanceAttributes();
+            engine.setAlphaMode(Engine.ALPHA_DISABLE);
+
+            return outparticles;
+        }
+
+        /**
          * Disposes the particle system and free the associated resources
          * @param disposeTexture defines if the particule texture must be disposed as well (true by default)
          */