Browse Source

Added velocity gradients for particles

David Catuhe 7 years ago
parent
commit
5c4ac351f6

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


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


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


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


File diff suppressed because it is too large
+ 153 - 13
dist/preview release/babylon.no-module.max.js


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


File diff suppressed because it is too large
+ 153 - 13
dist/preview release/es6.js


+ 2 - 19
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 4236,
+  "errors": 4233,
   "babylon.typedoc.json": {
-    "errors": 4236,
+    "errors": 4233,
     "AbstractScene": {
       "Property": {
         "effectLayers": {
@@ -8451,23 +8451,6 @@
             }
           }
         },
-        "render": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "subMesh": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "enableAlphaMode": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "setMaterialByID": {
           "Comments": {
             "MissingReturn": true

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


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


+ 4 - 3
src/Mesh/babylon.mesh.ts

@@ -1285,9 +1285,10 @@
         }
 
         /**
-         * Triggers the draw call for the mesh.
-         * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.   
-         * Returns the Mesh.   
+         * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
+         * @param subMesh defines the subMesh to render
+         * @param enableAlphaMode defines if alpha mode can be changed
+         * @returns the current mesh
          */
         public render(subMesh: SubMesh, enableAlphaMode: boolean): Mesh {
 

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

@@ -292,7 +292,7 @@ module BABYLON {
         getSizeGradients(): Nullable<Array<FactorGradient>>;
         /**
          * Gets the current list of angular speed gradients.
-         * You must use addAngularSpeedGradient and removeAngularGradient to udpate this list
+         * You must use addAngularSpeedGradient and removeAngularSpeedGradient to udpate this list
          * @returns the list of angular speed gradients
          */
         getAngularSpeedGradients(): Nullable<Array<FactorGradient>>;   
@@ -309,6 +309,26 @@ module BABYLON {
          * @param gradient defines the gradient to remove
          * @returns the current particle system
          */
-        removeAngularSpeedGradient(gradient: number): IParticleSystem;        
+        removeAngularSpeedGradient(gradient: number): IParticleSystem;   
+        /**
+         * Gets the current list of velocity gradients.
+         * You must use addVelocityGradient and removeVelocityGradient to udpate this list
+         * @returns the list of velocity gradients
+         */
+        getVelocityGradients(): Nullable<Array<FactorGradient>>;
+        /**
+         * Adds a new velocity gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient         
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        addVelocityGradient(gradient: number, factor: number, factor2?: number): IParticleSystem;
+        /**
+         * Remove a specific velocity gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        removeVelocityGradient(gradient: number): IParticleSystem;
     }  
 }

+ 69 - 4
src/Particles/babylon.gpuParticleSystem.ts

@@ -447,13 +447,22 @@
         
         /**
          * Gets the current list of angular speed gradients.
-         * You must use addAngularSpeedGradient and removeAngularGradient to udpate this list
+         * You must use addAngularSpeedGradient and removeAngularSpeedGradient to udpate this list
          * @returns the list of angular speed gradients
          */
         public getAngularSpeedGradients(): Nullable<Array<FactorGradient>> {
             return this._angularSpeedGradients;
         } 
 
+        /**
+         * Gets the current list of velocity gradients.
+         * You must use addVelocityGradient and removeVelocityGradient to udpate this list
+         * @returns the list of angular speed gradients
+         */
+        public getVelocityGradients(): Nullable<Array<FactorGradient>> {
+            return this._velocityGradients;
+        }         
+
         private _removeGradient(gradient: number, gradients: Nullable<IValueGradient[]>, texture: RawTexture): GPUParticleSystem {
             if (!gradients) {
                 return this;
@@ -532,6 +541,9 @@
         private _sizeGradients: Nullable<Array<FactorGradient>> = null;
         private _sizeGradientsTexture: RawTexture;     
         
+        private _velocityGradients: Nullable<Array<FactorGradient>> = null;
+        private _velocityGradientsTexture: RawTexture;    
+
         private _addFactorGradient(factorGradients: FactorGradient[], gradient: number, factor: number) {
             let valueGradient = new FactorGradient();
             valueGradient.gradient = gradient;
@@ -619,7 +631,42 @@
             (<any>this._angularSpeedGradientsTexture) = null;
 
             return this;           
-        }            
+        }           
+        
+        /**
+         * Adds a new velocity gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient    
+         * @returns the current particle system     
+         */
+        public addVelocityGradient(gradient: number, factor: number): GPUParticleSystem {
+            if (!this._velocityGradients) {
+                this._velocityGradients = [];
+            }
+
+            this._addFactorGradient(this._velocityGradients, gradient, factor);
+
+            if (this._velocityGradientsTexture) {
+                this._velocityGradientsTexture.dispose();
+                (<any>this._velocityGradientsTexture) = null;
+            }
+
+            this._releaseBuffers();   
+
+            return this;
+        }
+
+        /**
+         * Remove a specific velocity gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        public removeVelocityGradient(gradient: number): GPUParticleSystem {
+            this._removeGradient(gradient, this._velocityGradients, this._velocityGradientsTexture);
+            (<any>this._velocityGradientsTexture) = null;
+
+            return this;           
+        }          
 
         /**
          * Instantiates a GPU particle system.
@@ -666,7 +713,7 @@
                                 "direction1", "direction2", "minEmitBox", "maxEmitBox", "radius", "directionRandomizer", "height", "coneAngle", "stopFactor", 
                                 "angleRange", "radiusRange", "cellInfos"],
                 uniformBuffersNames: [],
-                samplers:["randomSampler", "randomSampler2", "sizeGradientSampler", "angularSpeedGradientSampler"],
+                samplers:["randomSampler", "randomSampler2", "sizeGradientSampler", "angularSpeedGradientSampler", "velocityGradientSampler"],
                 defines: "",
                 fallbacks: null,  
                 onCompiled: null,
@@ -910,7 +957,11 @@
 
             if (this._angularSpeedGradientsTexture) {
                 defines += "\n#define ANGULARSPEEDGRADIENTS";
-            }                 
+            }               
+            
+            if (this._velocityGradientsTexture) {
+                defines += "\n#define VELOCITYGRADIENTS";
+            }                    
             
             if (this.isAnimationSheetEnabled) {
                 defines += "\n#define ANIMATESHEET";
@@ -1022,6 +1073,10 @@
         private _createAngularSpeedGradientTexture() {
             this._createFactorGradientTexture(this._angularSpeedGradients, "_angularSpeedGradientsTexture");
         }     
+
+        private _createVelocityGradientTexture() {
+            this._createFactorGradientTexture(this._velocityGradients, "_velocityGradientsTexture");
+        }          
             
         private _createColorGradientTexture() {
             if (!this._colorGradients || !this._colorGradients.length || this._colorGradientsTexture) {
@@ -1061,6 +1116,7 @@
             this._createColorGradientTexture();
             this._createSizeGradientTexture();
             this._createAngularSpeedGradientTexture();
+            this._createVelocityGradientTexture();
 
             this._recreateUpdateEffect();
             this._recreateRenderEffect();
@@ -1128,6 +1184,10 @@
                 this._updateEffect.setTexture("angularSpeedGradientSampler", this._angularSpeedGradientsTexture);      
             }
 
+            if (this._velocityGradientsTexture) {      
+                this._updateEffect.setTexture("velocityGradientSampler", this._velocityGradientsTexture);      
+            }
+
             if (this.particleEmitterType) {
                 this.particleEmitterType.applyToShader(this._updateEffect);
             }
@@ -1293,6 +1353,11 @@
                 this._angularSpeedGradientsTexture.dispose();
                 (<any>this._angularSpeedGradientsTexture) = null;
             }             
+
+            if (this._velocityGradientsTexture) {
+                this._velocityGradientsTexture.dispose();
+                (<any>this._velocityGradientsTexture) = null;
+            }                
          
             if (this._randomTexture) {
                 this._randomTexture.dispose();

+ 13 - 1
src/Particles/babylon.particle.ts

@@ -88,6 +88,13 @@
         /** @hidden */
         public _currentAngularSpeed2 = 0;          
 
+        /** @hidden */
+        public _currentVelocityGradient: Nullable<FactorGradient>;
+        /** @hidden */
+        public _currentVelocity1 = 0;
+        /** @hidden */
+        public _currentVelocity2 = 0;             
+
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to
@@ -158,7 +165,12 @@
                 other._currentAngularSpeedGradient = this._currentAngularSpeedGradient;
                 other._currentAngularSpeed1 = this._currentAngularSpeed1;
                 other._currentAngularSpeed2 = this._currentAngularSpeed2;
-            }            
+            }        
+            if (this._currentVelocityGradient) {
+                other._currentVelocityGradient = this._currentVelocityGradient;
+                other._currentVelocity1 = this._currentVelocity1;
+                other._currentVelocity2 = this._currentVelocity2;
+            }                  
             if (this.particleSystem.isAnimationSheetEnabled) {
                 other._initialStartSpriteCellID = this._initialStartSpriteCellID;
                 other._initialEndSpriteCellID = this._initialEndSpriteCellID;

+ 89 - 4
src/Particles/babylon.particleSystem.ts

@@ -188,6 +188,7 @@
         private _sizeGradients: Nullable<Array<FactorGradient>> = null;
         private _lifeTimeGradients: Nullable<Array<FactorGradient>> = null;
         private _angularSpeedGradients: Nullable<Array<FactorGradient>> = null;
+        private _velocityGradients: Nullable<Array<FactorGradient>> = null;
 
         /**
          * Gets the current list of color gradients.
@@ -218,7 +219,7 @@
         
         /**
          * Gets the current list of angular speed gradients.
-         * You must use addAngularSpeedGradient and removeAngularGradient to udpate this list
+         * You must use addAngularSpeedGradient and removeAngularSpeedGradient to udpate this list
          * @returns the list of angular speed gradients
          */
         public getAngularSpeedGradients(): Nullable<Array<FactorGradient>> {
@@ -226,6 +227,15 @@
         } 
 
         /**
+         * Gets the current list of velocity gradients.
+         * You must use addVelocityGradient and removeVelocityGradient to udpate this list
+         * @returns the list of velocity gradients
+         */
+        public getVelocityGradients(): Nullable<Array<FactorGradient>> {
+            return this._velocityGradients;
+        }         
+
+        /**
          * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
          * This only works when particleEmitterTyps is a BoxParticleEmitter
          */
@@ -546,7 +556,18 @@
                         }                        
                         particle.angle += particle.angularSpeed * this._scaledUpdateSpeed;
 
-                        particle.direction.scaleToRef(this._scaledUpdateSpeed, this._scaledDirection);
+                        let directionScale = this._scaledUpdateSpeed;
+                        if (this._velocityGradients && this._velocityGradients.length > 0) {                  
+                            Tools.GetCurrentGradient(ratio, this._velocityGradients, (currentGradient, nextGradient, scale) => {
+                                if (currentGradient !== particle._currentVelocityGradient) {
+                                    particle._currentVelocity1 = particle._currentVelocity2;
+                                    particle._currentVelocity2 = (<FactorGradient>nextGradient).getFactor();    
+                                    particle._currentVelocityGradient = (<FactorGradient>currentGradient);
+                                }                                
+                                directionScale *= Scalar.Lerp(particle._currentVelocity1, particle._currentVelocity2, scale);
+                            });
+                        }                          
+                        particle.direction.scaleToRef(directionScale, this._scaledDirection);
                         particle.position.addInPlace(this._scaledDirection);
 
                         this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
@@ -687,7 +708,35 @@
             this._removeFactorGradient(this._angularSpeedGradients, gradient);
 
             return this;
-        }           
+        }          
+        
+        /**
+         * Adds a new velocity gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient         
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        public addVelocityGradient(gradient: number, factor: number, factor2?: number): ParticleSystem {
+            if (!this._velocityGradients) {
+                this._velocityGradients = [];
+            }
+
+            this._addFactorGradient(this._velocityGradients, gradient, factor, factor2);
+
+            return this;
+        }
+
+        /**
+         * Remove a specific velocity gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        public removeVelocityGradient(gradient: number): ParticleSystem {
+            this._removeFactorGradient(this._velocityGradients, gradient);
+
+            return this;
+        }         
 
         /**
          * Adds a new color gradient
@@ -1111,6 +1160,18 @@
                 }
                 particle.angle = Scalar.RandomRange(this.minInitialRotation, this.maxInitialRotation);
 
+                // Velocity
+                if (this._velocityGradients && this._velocityGradients.length > 0) {
+                    particle._currentVelocityGradient = this._velocityGradients[0];
+                    particle._currentVelocity1 = particle._currentVelocityGradient.getFactor();
+
+                    if (this._velocityGradients.length > 1) {
+                        particle._currentVelocity2 = this._velocityGradients[1].getFactor();
+                    } else {
+                        particle._currentVelocity2 = particle._currentVelocity1;
+                    }
+                }                
+
                 // Color
                 if (!this._colorGradients || this._colorGradients.length === 0) {
                     var step = Scalar.RandomRange(0, 1.0);
@@ -1664,6 +1725,24 @@
                     serializationObject.angularSpeedGradients.push(serializedGradient);
                 }
             }  
+
+            let velocityGradients = particleSystem.getVelocityGradients();
+            if (velocityGradients) {
+                serializationObject.velocityGradients = [];
+                for (var velocityGradient of velocityGradients) {
+
+                    var serializedGradient: any = {
+                        gradient: velocityGradient.gradient,
+                        factor1: velocityGradient.factor1
+                    };
+
+                    if (velocityGradient.factor2 !== undefined) {
+                        serializedGradient.factor2 = velocityGradient.factor2;
+                    }
+
+                    serializationObject.velocityGradients.push(serializedGradient);
+                }
+            }              
         }
 
         /** @hidden */
@@ -1758,7 +1837,13 @@
                 for (var angularSpeedGradient of parsedParticleSystem.angularSpeedGradients) {
                     particleSystem.addAngularSpeedGradient(angularSpeedGradient.gradient, angularSpeedGradient.factor1 !== undefined ?  angularSpeedGradient.factor1 : angularSpeedGradient.factor, angularSpeedGradient.factor2);
                 }
-            }               
+            }       
+            
+            if (parsedParticleSystem.velocityGradients) {
+                for (var velocityGradient of parsedParticleSystem.velocityGradients) {
+                    particleSystem.addVelocityGradient(velocityGradient.gradient, velocityGradient.factor1 !== undefined ?  velocityGradient.factor1 : velocityGradient.factor, velocityGradient.factor2);
+                }
+            }              
             
             // Emitter
             let emitterType: IParticleEmitterType;

+ 17 - 5
src/Shaders/gpuUpdateParticles.vertex.fx

@@ -96,6 +96,11 @@ uniform sampler2D sizeGradientSampler;
 uniform sampler2D angularSpeedGradientSampler;
 #endif 
 
+#ifdef VELOCITYGRADIENTS
+uniform sampler2D velocityGradientSampler;
+#endif
+
+
 #ifdef ANIMATESHEET
 uniform vec3 cellInfos;
 #endif
@@ -227,7 +232,7 @@ void main() {
     float power = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
 
     outPosition = (emitterWM * vec4(position, 1.)).xyz;
-    vec3 initial = (emitterWM * vec4(direction, 0.)).xyz;
+    vec3 initial = (emitterWM * vec4(normalize(direction), 0.)).xyz;
     outDirection = initial * power;
 #ifndef BILLBOARD        
     outInitialDirection = initial;
@@ -237,7 +242,14 @@ void main() {
 #endif
 
   } else {   
-    outPosition = position + direction * timeDelta;
+    float directionScale = timeDelta;
+    float ageGradient = age / life;
+
+#ifdef VELOCITYGRADIENTS
+    directionScale *= texture(velocityGradientSampler, vec2(ageGradient, 0)).r;
+#endif
+
+    outPosition = position + direction * directionScale;
     outAge = age + timeDelta;
     outLife = life;
     outSeed = seed;
@@ -246,7 +258,7 @@ void main() {
 #endif
 
 #ifdef SIZEGRADIENTS
-	outSize.x = texture(sizeGradientSampler, vec2(age / life, 0)).r;
+	outSize.x = texture(sizeGradientSampler, vec2(ageGradient, 0)).r;
     outSize.yz = size.yz;
 #else
     outSize = size;
@@ -255,10 +267,10 @@ void main() {
 #ifndef BILLBOARD    
     outInitialDirection = initialDirection;
 #endif
-    outDirection = direction + gravity * timeDelta;
+    outDirection = direction;// + gravity * timeDelta;
 
 #ifdef ANGULARSPEEDGRADIENTS
-    float angularSpeed = texture(angularSpeedGradientSampler, vec2(age / life, 0)).r;
+    float angularSpeed = texture(angularSpeedGradientSampler, vec2(ageGradient, 0)).r;
     outAngle = angle + angularSpeed * timeDelta;
 #else
     outAngle = vec2(angle.x + angle.y * timeDelta, angle.y);