ソースを参照

Merge remote-tracking branch 'upstream/master'

sebastien 7 年 前
コミット
d6bdfb3cb7

ファイルの差分が大きいため隠しています
+ 9251 - 9225
Playground/babylon.d.txt


ファイルの差分が大きいため隠しています
+ 10594 - 10532
dist/preview release/babylon.d.ts


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/babylon.js


ファイルの差分が大きいため隠しています
+ 122 - 19
dist/preview release/babylon.max.js


ファイルの差分が大きいため隠しています
+ 122 - 19
dist/preview release/babylon.no-module.max.js


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/babylon.worker.js


ファイルの差分が大きいため隠しています
+ 124 - 21
dist/preview release/es6.js


+ 1 - 1
dist/preview release/gui/babylon.gui.d.ts

@@ -1,6 +1,6 @@
 /*BabylonJS GUI*/
 // Dependencies for this module:
-//   ../../../../Tools/gulp/babylonjs
+//   ../../../../Tools/Gulp/babylonjs
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 2 - 2
dist/preview release/gui/babylon.gui.module.d.ts

@@ -1,6 +1,6 @@
 /*BabylonJS GUI*/
 // Dependencies for this module:
-//   ../../../../Tools/gulp/babylonjs
+//   ../../../../Tools/Gulp/babylonjs
 
 declare module 'babylonjs-gui' {
     export * from "babylonjs-gui/2D";
@@ -2812,7 +2812,7 @@ declare module 'babylonjs-gui/3D/materials/fluentMaterial' {
 
 /*BabylonJS GUI*/
 // Dependencies for this module:
-//   ../../../../Tools/gulp/babylonjs
+//   ../../../../Tools/Gulp/babylonjs
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {

+ 1 - 1
dist/preview release/inspector/babylon.inspector.d.ts

@@ -1,6 +1,6 @@
 /*BabylonJS Inspector*/
 // Dependencies for this module:
-//   ../../../../Tools/gulp/babylonjs
+//   ../../../../Tools/Gulp/babylonjs
 declare module INSPECTOR {
 }
 declare module INSPECTOR {

+ 2 - 2
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -1,6 +1,6 @@
 /*BabylonJS Inspector*/
 // Dependencies for this module:
-//   ../../../../Tools/gulp/babylonjs
+//   ../../../../Tools/Gulp/babylonjs
 
 declare module 'babylonjs-inspector' {
     export * from 'babylonjs-inspector/adapters';
@@ -1340,7 +1340,7 @@ declare module 'babylonjs-inspector/treetools/SoundInteractions' {
 
 /*BabylonJS Inspector*/
 // Dependencies for this module:
-//   ../../../../Tools/gulp/babylonjs
+//   ../../../../Tools/Gulp/babylonjs
 declare module INSPECTOR {
 }
 declare module INSPECTOR {

+ 161 - 4
dist/preview release/viewer/babylon.viewer.d.ts

@@ -4,8 +4,8 @@
 declare module "babylonjs-loaders"{ export=BABYLON;}
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
-//   ../../../../../Tools/gulp/babylonjs
-//   ../../../../../Tools/gulp/babylonjs-loaders
+//   ../../../../../Tools/Gulp/babylonjs
+//   ../../../../../Tools/Gulp/babylonjs-loaders
 declare module BabylonViewer {
     /**
         * BabylonJS Viewer
@@ -515,10 +515,167 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
+    /**
+        * The current state of the model
+        */
+    export enum ModelState {
+            INIT = 0,
+            LOADING = 1,
+            LOADED = 2,
+            ENTRY = 3,
+            ENTRYDONE = 4,
+            COMPLETE = 5,
+            CANCELED = 6,
+            ERROR = 7
+    }
+    /**
+        * The viewer model is a container for all assets representing a sngle loaded model.
+        */
+    export class ViewerModel implements BABYLON.IDisposable {
+            /**
+                * The loader used to load this model.
+                */
+            loader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync;
+            /**
+                * This model's root mesh (the parent of all other meshes).
+                * This mesh does not(!) exist in the meshes array.
+                */
+            rootMesh: BABYLON.AbstractMesh;
+            /**
+                * ParticleSystems connected to this model
+                */
+            particleSystems: Array<BABYLON.IParticleSystem>;
+            /**
+                * Skeletons defined in this model
+                */
+            skeletons: Array<BABYLON.Skeleton>;
+            /**
+                * The current model animation.
+                * On init, this will be undefined.
+                */
+            currentAnimation: IModelAnimation;
+            /**
+                * Observers registered here will be executed when the model is done loading
+                */
+            onLoadedObservable: BABYLON.Observable<ViewerModel>;
+            /**
+                * Observers registered here will be executed when the loader notified of a progress event
+                */
+            onLoadProgressObservable: BABYLON.Observable<BABYLON.SceneLoaderProgressEvent>;
+            /**
+                * Observers registered here will be executed when the loader notified of an error.
+                */
+            onLoadErrorObservable: BABYLON.Observable<{
+                    message: string;
+                    exception: any;
+            }>;
+            /**
+                * Will be executed after the model finished loading and complete, including entry animation and lod
+                */
+            onCompleteObservable: BABYLON.Observable<ViewerModel>;
+            /**
+                * Observers registered here will be executed every time the model is being configured.
+                * This can be used to extend the model's configuration without extending the class itself
+                */
+            onAfterConfigure: BABYLON.Observable<ViewerModel>;
+            /**
+                * The current model state (loaded, error, etc)
+                */
+            state: ModelState;
+            /**
+                * A loadID provided by the modelLoader, unique to ths (Abstract)Viewer instance.
+                */
+            loadId: number;
+            loadInfo: BABYLON.GLTF2.IAsset;
+            constructor(_observablesManager: ObservablesManager, modelConfiguration: IModelConfiguration, _configurationContainer?: ConfigurationContainer | undefined);
+            shadowsRenderedAfterLoad: boolean;
+            getViewerId(): string | undefined;
+            /**
+             * Set whether this model is enabled or not.
+             */
+            enabled: boolean;
+            loaderDone: boolean;
+            /**
+                * Add a mesh to this model.
+                * Any mesh that has no parent will be provided with the root mesh as its new parent.
+                *
+                * @param mesh the new mesh to add
+                * @param triggerLoaded should this mesh trigger the onLoaded observable. Used when adding meshes manually.
+                */
+            addMesh(mesh: BABYLON.AbstractMesh, triggerLoaded?: boolean): Promise<ViewerModel> | undefined;
+            /**
+                * get the list of meshes (excluding the root mesh)
+                */
+            readonly meshes: BABYLON.AbstractMesh[];
+            /**
+             * (Re-)set the model's entire configuration
+             * @param newConfiguration the new configuration to replace the new one
+             */
+            configuration: IModelConfiguration;
+            /**
+                * Update the current configuration with new values.
+                * Configuration will not be overwritten, but merged with the new configuration.
+                * Priority is to the new configuration
+                * @param newConfiguration the configuration to be merged into the current configuration;
+                */
+            updateConfiguration(newConfiguration: Partial<IModelConfiguration>): void;
+            /**
+                * Add a new animation group to this model.
+                * @param animationGroup the new animation group to be added
+                */
+            addAnimationGroup(animationGroup: BABYLON.AnimationGroup): void;
+            /**
+                * Get the ModelAnimation array
+                */
+            getAnimations(): Array<IModelAnimation>;
+            /**
+                * Get the animations' names. Using the names you can play a specific animation.
+                */
+            getAnimationNames(): Array<string>;
+            /**
+                * Get an animation by the provided name. Used mainly when playing n animation.
+                * @param name the name of the animation to find
+                */
+            protected _getAnimationByName(name: string): BABYLON.Nullable<IModelAnimation>;
+            /**
+                * Choose an initialized animation using its name and start playing it
+                * @param name the name of the animation to play
+                * @returns The model aniamtion to be played.
+                */
+            playAnimation(name: string): IModelAnimation;
+            setCurrentAnimationByName(name: string): IModelAnimation;
+            /**
+                * Apply a material configuration to a material
+                * @param material BABYLON.Material to apply configuration to
+                * @hidden
+                */
+            _applyModelMaterialConfiguration(material: BABYLON.Material): void;
+            /**
+             * Begin @animations with the specified @easingFunction
+             * @param animations The BABYLON Animations to begin
+             * @param duration of transition, in seconds
+             * @param easingFunction An easing function to apply
+             * @param easingMode A easing mode to apply to the easingFunction
+             * @param onAnimationEnd Call back trigger at the end of the animation.
+             */
+            transitionTo(animations: BABYLON.Animation[], duration: number, easingFunction: any, easingMode: number | undefined, onAnimationEnd: () => void): void;
+            /**
+                * Stops and removes all animations that have been applied to the model
+                */
+            stopAllAnimations(): void;
+            /**
+                * Will remove this model from the viewer (but NOT dispose it).
+                */
+            remove(): void;
+            /**
+                * Dispose this model, including all of its associated assets.
+                */
+            dispose(): void;
+    }
 }
 declare module BabylonViewer {
     /**
-        * Animation play mode enum - is the animation looping or playing once
+        * BABYLON.Animation play mode enum - is the animation looping or playing once
         */
     export const enum AnimationPlayMode {
             ONCE = 0,
@@ -600,7 +757,7 @@ declare module BabylonViewer {
                 */
             readonly currentFrame: number;
             /**
-                * Animation's FPS value
+                * BABYLON.Animation's FPS value
                 */
             readonly fps: number;
             /**

ファイルの差分が大きいため隠しています
+ 2 - 2
dist/preview release/viewer/babylon.viewer.js


ファイルの差分が大きいため隠しています
+ 5 - 5
dist/preview release/viewer/babylon.viewer.max.js


+ 165 - 3
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -5,8 +5,8 @@ declare module "babylonjs-loaders"{ export=BABYLON;}
 
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
-//   ../../../../../Tools/gulp/babylonjs
-//   ../../../../../Tools/gulp/babylonjs-loaders
+//   ../../../../../Tools/Gulp/babylonjs
+//   ../../../../../Tools/Gulp/babylonjs-loaders
 
 declare module 'babylonjs-viewer' {
     import { mapperManager } from 'babylonjs-viewer/configuration/mappers';
@@ -566,7 +566,169 @@ declare module 'babylonjs-viewer/loader/modelLoader' {
 }
 
 declare module 'babylonjs-viewer/model/viewerModel' {
-    
+    import { ISceneLoaderPlugin, ISceneLoaderPluginAsync, AnimationGroup, AbstractMesh, Observable, SceneLoaderProgressEvent, IParticleSystem, Skeleton, IDisposable, Nullable, Animation, Material } from "babylonjs";
+    import { GLTF2 } from "babylonjs-loaders";
+    import { IModelConfiguration } from "babylonjs-viewer/configuration/interfaces/modelConfiguration";
+    import { IModelAnimation } from "babylonjs-viewer/model/modelAnimation";
+    import { ObservablesManager } from "babylonjs-viewer/managers/observablesManager";
+    import { ConfigurationContainer } from "babylonjs-viewer/configuration/configurationContainer";
+    /**
+        * The current state of the model
+        */
+    export enum ModelState {
+            INIT = 0,
+            LOADING = 1,
+            LOADED = 2,
+            ENTRY = 3,
+            ENTRYDONE = 4,
+            COMPLETE = 5,
+            CANCELED = 6,
+            ERROR = 7
+    }
+    /**
+        * The viewer model is a container for all assets representing a sngle loaded model.
+        */
+    export class ViewerModel implements IDisposable {
+            /**
+                * The loader used to load this model.
+                */
+            loader: ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+            /**
+                * This model's root mesh (the parent of all other meshes).
+                * This mesh does not(!) exist in the meshes array.
+                */
+            rootMesh: AbstractMesh;
+            /**
+                * ParticleSystems connected to this model
+                */
+            particleSystems: Array<IParticleSystem>;
+            /**
+                * Skeletons defined in this model
+                */
+            skeletons: Array<Skeleton>;
+            /**
+                * The current model animation.
+                * On init, this will be undefined.
+                */
+            currentAnimation: IModelAnimation;
+            /**
+                * Observers registered here will be executed when the model is done loading
+                */
+            onLoadedObservable: Observable<ViewerModel>;
+            /**
+                * Observers registered here will be executed when the loader notified of a progress event
+                */
+            onLoadProgressObservable: Observable<SceneLoaderProgressEvent>;
+            /**
+                * Observers registered here will be executed when the loader notified of an error.
+                */
+            onLoadErrorObservable: Observable<{
+                    message: string;
+                    exception: any;
+            }>;
+            /**
+                * Will be executed after the model finished loading and complete, including entry animation and lod
+                */
+            onCompleteObservable: Observable<ViewerModel>;
+            /**
+                * Observers registered here will be executed every time the model is being configured.
+                * This can be used to extend the model's configuration without extending the class itself
+                */
+            onAfterConfigure: Observable<ViewerModel>;
+            /**
+                * The current model state (loaded, error, etc)
+                */
+            state: ModelState;
+            /**
+                * A loadID provided by the modelLoader, unique to ths (Abstract)Viewer instance.
+                */
+            loadId: number;
+            loadInfo: GLTF2.IAsset;
+            constructor(_observablesManager: ObservablesManager, modelConfiguration: IModelConfiguration, _configurationContainer?: ConfigurationContainer | undefined);
+            shadowsRenderedAfterLoad: boolean;
+            getViewerId(): string | undefined;
+            /**
+             * Set whether this model is enabled or not.
+             */
+            enabled: boolean;
+            loaderDone: boolean;
+            /**
+                * Add a mesh to this model.
+                * Any mesh that has no parent will be provided with the root mesh as its new parent.
+                *
+                * @param mesh the new mesh to add
+                * @param triggerLoaded should this mesh trigger the onLoaded observable. Used when adding meshes manually.
+                */
+            addMesh(mesh: AbstractMesh, triggerLoaded?: boolean): Promise<ViewerModel> | undefined;
+            /**
+                * get the list of meshes (excluding the root mesh)
+                */
+            readonly meshes: AbstractMesh[];
+            /**
+             * (Re-)set the model's entire configuration
+             * @param newConfiguration the new configuration to replace the new one
+             */
+            configuration: IModelConfiguration;
+            /**
+                * Update the current configuration with new values.
+                * Configuration will not be overwritten, but merged with the new configuration.
+                * Priority is to the new configuration
+                * @param newConfiguration the configuration to be merged into the current configuration;
+                */
+            updateConfiguration(newConfiguration: Partial<IModelConfiguration>): void;
+            /**
+                * Add a new animation group to this model.
+                * @param animationGroup the new animation group to be added
+                */
+            addAnimationGroup(animationGroup: AnimationGroup): void;
+            /**
+                * Get the ModelAnimation array
+                */
+            getAnimations(): Array<IModelAnimation>;
+            /**
+                * Get the animations' names. Using the names you can play a specific animation.
+                */
+            getAnimationNames(): Array<string>;
+            /**
+                * Get an animation by the provided name. Used mainly when playing n animation.
+                * @param name the name of the animation to find
+                */
+            protected _getAnimationByName(name: string): Nullable<IModelAnimation>;
+            /**
+                * Choose an initialized animation using its name and start playing it
+                * @param name the name of the animation to play
+                * @returns The model aniamtion to be played.
+                */
+            playAnimation(name: string): IModelAnimation;
+            setCurrentAnimationByName(name: string): IModelAnimation;
+            /**
+                * Apply a material configuration to a material
+                * @param material Material to apply configuration to
+                * @hidden
+                */
+            _applyModelMaterialConfiguration(material: Material): void;
+            /**
+             * Begin @animations with the specified @easingFunction
+             * @param animations The BABYLON Animations to begin
+             * @param duration of transition, in seconds
+             * @param easingFunction An easing function to apply
+             * @param easingMode A easing mode to apply to the easingFunction
+             * @param onAnimationEnd Call back trigger at the end of the animation.
+             */
+            transitionTo(animations: Animation[], duration: number, easingFunction: any, easingMode: number | undefined, onAnimationEnd: () => void): void;
+            /**
+                * Stops and removes all animations that have been applied to the model
+                */
+            stopAllAnimations(): void;
+            /**
+                * Will remove this model from the viewer (but NOT dispose it).
+                */
+            remove(): void;
+            /**
+                * Dispose this model, including all of its associated assets.
+                */
+            dispose(): void;
+    }
 }
 
 declare module 'babylonjs-viewer/model/modelAnimation' {

+ 71 - 0
src/Animations/babylon.animationGroup.ts

@@ -362,5 +362,76 @@ module BABYLON {
                 this.onAnimationGroupEndObservable.notifyObservers(this);
             }
         }
+
+        // Statics
+        /**
+         * Returns a new AnimationGroup object parsed from the source provided.
+         * @param {Object} parsedAnimationGroup - is the source.
+         * @param {Scene} scene - is the scene that will receive the animationGroup
+         * Example of an expected source
+         * {
+                "name": "Run",
+                "from": 0.0,
+                "to": 1.0,
+                "targetedAnimations": [{
+                    "animation": {
+                        "name": "rotationQuaternion animation",
+                        "property": "rotationQuaternion",
+                        "dataType": 2,
+                        "enableBlending": false,
+                        "blendingSpeed": 0.01,
+                        "loopBehavior": 1,
+                        "framePerSecond": 30,
+                        "keys": [{
+                            "frame": 0,
+                            "values": [-0.7071, -0.002, 0.0022, 0.7071]
+                        }, {
+                            "frame": 1,
+                            "values": [-0.7082, -0.0485, 0.0026, 0.7043]
+                        }]
+                    },
+                    "targetId": "d64f9288-d06a-4a70-872f-edbb5a3779c6"
+                }]
+            }
+         */
+        public static Parse(parsedAnimationGroup: any, scene: Scene): AnimationGroup {
+            var animationGroup = new BABYLON.AnimationGroup(parsedAnimationGroup.name, scene);
+            for (var i = 0; i < parsedAnimationGroup.targetedAnimations.length; i++){
+                var targetedAnimation = parsedAnimationGroup.targetedAnimations[i];
+                var animation = Animation.Parse(targetedAnimation.animation);
+                var id = targetedAnimation.targetId;
+                var targetNode = scene.getNodeByID(id);
+                
+                if(targetNode != null)
+                    animationGroup.addTargetedAnimation(animation,targetNode);
+            }
+            
+            if(parsedAnimationGroup.from !== null && parsedAnimationGroup.from !== null)
+                animationGroup.normalize(parsedAnimationGroup.from, parsedAnimationGroup.to);
+
+            return animationGroup;
+        }
+
+        public getClassName(): string {
+            return "AnimationGroup";
+        }
+
+        /**
+         * @param {boolean} fullDetails - support for multiple levels of logging within scene loading
+         */
+        public toString(fullDetails?: boolean): string {
+            var ret = "Name: " + this.name;
+            ret += ", type: " + this.getClassName();
+            if (fullDetails) {
+                ret += ", from: " + this._from;
+                ret += ", to: " + this._to;
+                ret += ", isStarted: " + this._isStarted;
+                ret += ", speedRatio: " + this._speedRatio;
+                ret += ", targetedAnimations length: " + this._targetedAnimations.length;
+                ret += ", animatables length: " + this._animatables;
+            }
+            return ret;
+        }
+
     }
 }

+ 4 - 0
src/Bones/babylon.skeleton.ts

@@ -558,6 +558,10 @@
                 var rest: Nullable<Matrix> = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;
                 var bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest);
                 
+                if (parsedBone.id !== undefined && parsedBone.id !== null) {
+                    bone.id = parsedBone.id;
+                }
+
                 if (parsedBone.length) {
                     bone.length = parsedBone.length;
                 }

+ 14 - 3
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -220,6 +220,17 @@
                 }
             }
 
+            // Animation Groups
+            if(parsedData.animationGroups !== undefined && parsedData.animationGroups !== null) {
+                for (index = 0, cache = parsedData.animationGroups.length; index < cache; index++){
+                    var parsedAnimationGroup = parsedData.animationGroups[index];
+                    var animationGroup = AnimationGroup.Parse(parsedAnimationGroup, scene);
+                    container.animationGroups.push(animationGroup);
+                    log += (index === 0 ? "\n\tAnimationGroups:" : "");
+                    log += "\n\t\t" + animationGroup.toString(fullDetails);
+                }
+            }
+            
             // Browsing all the graph to connect the dots
             for (index = 0, cache = scene.cameras.length; index < cache; index++) {
                 var camera = scene.cameras[index];
@@ -236,7 +247,7 @@
                     light._waitingParentId = null;
                 }
             }
-
+            
             // Sounds
             // TODO: add sound
             var loadedSounds: Sound[] = [];
@@ -322,9 +333,9 @@
                     light._includedOnlyMeshesIds = [];
                 }
             }
-
+            
             AbstractScene.Parse(parsedData, scene, container, rootUrl);
-
+            
             // Actions (scene)
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
                 ActionManager.Parse(parsedData.actions, null, scene);

+ 27 - 4
src/Math/babylon.math.ts

@@ -386,10 +386,22 @@
          * @returns a new Color3 object
          */
         public static Lerp(start: Color3, end: Color3, amount: number): Color3 {
-            var r = start.r + ((end.r - start.r) * amount);
-            var g = start.g + ((end.g - start.g) * amount);
-            var b = start.b + ((end.b - start.b) * amount);
-            return new Color3(r, g, b);
+            var result = new Color3(0.0, 0.0, 0.0);
+            Color3.LerpToRef(start, end, amount, result);
+            return result;
+        }
+
+        /**
+         * Creates a new Color3 with values linearly interpolated of "amount" between the start Color3 and the end Color3
+         * @param left defines the start value
+         * @param right defines the end value
+         * @param amount defines the gradient factor
+         * @param result defines the Color3 object where to store the result
+         */
+        public static LerpToRef(left: Color3, right: Color3, amount: number, result: Color3): void {
+            result.r = left.r + ((right.r - left.r) * amount);
+            result.g = left.g + ((right.g - left.g) * amount);
+            result.b = left.b + ((right.b - left.b) * amount);
         }
 
         /**
@@ -810,6 +822,17 @@
             result.a = left.a + (right.a - left.a) * amount;
         }
 
+        
+        /**
+         * Creates a new Color4 from a Color3 and an alpha value
+         * @param color3 defines the source Color3 to read from
+         * @param alpha defines the alpha component (1.0 by default)
+         * @returns a new Color4 object
+         */
+        public static FromColor3(color3: Color3, alpha: number = 1.0): Color4 {
+            return new Color4(color3.r, color3.g, color3.b, alpha);
+        }
+
         /**
          * Creates a new Color4 from the starting index element of the given array
          * @param array defines the source array to read from

+ 2 - 2
src/Particles/babylon.IParticleSystem.ts

@@ -436,13 +436,13 @@ module BABYLON {
          * @param color defines the color to affect to the specified gradient
          * @returns the current particle system
          */
-        addRampGradient(gradient: number, color: Color4): IParticleSystem;     
+        addRampGradient(gradient: number, color: Color3): IParticleSystem;     
         /**
          * Gets the current list of ramp gradients.
          * You must use addRampGradient and removeRampGradient to udpate this list
          * @returns the list of ramp gradients
          */
-        getRampGradients(): Nullable<Array<ColorGradient>>;             
+        getRampGradients(): Nullable<Array<Color3Gradient>>;             
         
         /**
          * Adds a new color remap gradient

+ 1 - 1
src/Particles/babylon.baseParticleSystem.ts

@@ -258,7 +258,7 @@ module BABYLON {
         protected _dragGradients: Nullable<Array<FactorGradient>> = null;
         protected _emitRateGradients: Nullable<Array<FactorGradient>> = null;
         protected _startSizeGradients: Nullable<Array<FactorGradient>> = null;
-        protected _rampGradients: Nullable<Array<ColorGradient>> = null;
+        protected _rampGradients: Nullable<Array<Color3Gradient>> = null;
         protected _colorRemapGradients: Nullable<Array<FactorGradient>> = null;
         protected _alphaRemapGradients: Nullable<Array<FactorGradient>> = null;        
 

+ 2 - 2
src/Particles/babylon.gpuParticleSystem.ts

@@ -512,7 +512,7 @@
          * @param color defines the color to affect to the specified gradient
          * @returns the current particle system
          */
-        public addRampGradient(gradient: number, color: Color4): IParticleSystem {
+        public addRampGradient(gradient: number, color: Color3): IParticleSystem {
             //Not supported by GPUParticleSystem          
 
             return this;
@@ -533,7 +533,7 @@
          * Not supported by GPUParticleSystem
          * @returns the list of ramp gradients
          */
-        public getRampGradients(): Nullable<Array<ColorGradient>> {
+        public getRampGradients(): Nullable<Array<Color3Gradient>> {
             return null;
         }             
         

+ 10 - 10
src/Particles/babylon.particleSystem.ts

@@ -728,18 +728,18 @@
             }
 
             let data = new Uint8Array(this._rawTextureWidth * 4);
-            let tmpColor = Tmp.Color4[0];
+            let tmpColor = Tmp.Color3[0];
 
             for (var x = 0; x < this._rawTextureWidth; x++) {
                 var ratio = x / this._rawTextureWidth;
 
                 Tools.GetCurrentGradient(ratio, this._rampGradients, (currentGradient, nextGradient, scale) => {
 
-                    Color4.LerpToRef((<ColorGradient>currentGradient).color1, (<ColorGradient>nextGradient).color1, scale, tmpColor);
+                    Color3.LerpToRef((<Color3Gradient>currentGradient).color, (<Color3Gradient>nextGradient).color, scale, tmpColor);
                     data[x * 4] = tmpColor.r * 255;
                     data[x * 4 + 1] = tmpColor.g * 255;
                     data[x * 4 + 2] = tmpColor.b * 255;
-                    data[x * 4 + 3] = tmpColor.a * 255;
+                    data[x * 4 + 3] = 255;
                 });
 
             }
@@ -752,7 +752,7 @@
          * You must use addRampGradient and removeRampGradient to udpate this list
          * @returns the list of ramp gradients
          */
-        public getRampGradients(): Nullable<Array<ColorGradient>> {
+        public getRampGradients(): Nullable<Array<Color3Gradient>> {
             return this._rampGradients;
         }
 
@@ -762,14 +762,14 @@
          * @param color defines the color to affect to the specified gradient
          * @returns the current particle system
          */
-        public addRampGradient(gradient: number, color: Color4): ParticleSystem {
+        public addRampGradient(gradient: number, color: Color3): ParticleSystem {
             if (!this._rampGradients) {
                 this._rampGradients = [];
             }
 
-            let rampGradient = new ColorGradient();
+            let rampGradient = new Color3Gradient();
             rampGradient.gradient = gradient;
-            rampGradient.color1 = color;
+            rampGradient.color = color;
             this._rampGradients.push(rampGradient);
 
             this._rampGradients.sort((a, b) => {
@@ -1836,7 +1836,7 @@
             }
             if (this._rampGradients) {
                 this._rampGradients.forEach((v) => {
-                    result.addRampGradient(v.gradient, v.color1);
+                    result.addRampGradient(v.gradient, v.color);
                 });
             }
             if (this._colorRemapGradients) {
@@ -1960,7 +1960,7 @@
                 for (var rampGradient of rampGradients) {
                     var serializedGradient: any = {
                         gradient: rampGradient.gradient,
-                        color1: rampGradient.color1.asArray()
+                        color: rampGradient.color.asArray()
                     };
 
                     serializationObject.rampGradients.push(serializedGradient);
@@ -2224,7 +2224,7 @@
 
             if (parsedParticleSystem.rampGradients) {
                 for (var rampGradient of parsedParticleSystem.rampGradients) {
-                    particleSystem.addRampGradient(rampGradient.gradient, Color4.FromArray(rampGradient.color1));
+                    particleSystem.addRampGradient(rampGradient.gradient, Color3.FromArray(rampGradient.color1));
                 }
             }
 

+ 5 - 3
src/Shaders/particles.fragment.fx

@@ -24,13 +24,15 @@ void main(void) {
 	vec4 baseColor = (textureColor * textureMask + (vec4(1., 1., 1., 1.) - textureMask)) * vColor;
 
 	#ifdef RAMPGRADIENT
-		float alpha = textureColor.a;
+		float alpha = baseColor.a;
 		float remappedColorIndex = clamp((alpha - remapRanges.x) / remapRanges.y, 0.0, 1.0);
 
-		baseColor.rgb *= texture2D(rampSampler, vec2(remappedColorIndex, 0.)).rgb;
+		vec4 rampColor = texture2D(rampSampler, vec2(1.0 - remappedColorIndex, 0.));
+		baseColor.rgb *= rampColor.rgb;
 
 		// Remapped alpha
-		baseColor.a = clamp((alpha - remapRanges.z) / remapRanges.w, 0.0, 1.0);
+		float finalAlpha = baseColor.a;
+		baseColor.a = clamp((alpha * rampColor.a - remapRanges.z) / remapRanges.w, 0.0, 1.0);
 	#endif
 
 	#ifdef BLENDMULTIPLYMODE

+ 13 - 1
src/Tools/babylon.tools.ts

@@ -12,7 +12,7 @@
         gradient: number;
     }
 
-    /** Class used to store color gradient */
+    /** Class used to store color4 gradient */
     export class ColorGradient implements IValueGradient {
         /**
          * Gets or sets the gradient value (between 0 and 1)
@@ -42,6 +42,18 @@
         }
     }
 
+    /** Class used to store color 3 gradient */
+    export class Color3Gradient implements IValueGradient {
+        /**
+         * Gets or sets the gradient value (between 0 and 1)
+         */
+        public gradient: number;
+        /**
+         * Gets or sets the associated color
+         */
+        public color: Color3;
+    }    
+
     /** Class used to store factor gradient */
     export class FactorGradient implements IValueGradient {
         /**