فهرست منبع

temp state for particle noise textures

David Catuhe 7 سال پیش
والد
کامیت
d10643af04

+ 6 - 14
src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.ts

@@ -3,25 +3,19 @@ module BABYLON {
      * Class used to generate noise procedural textures
      */
     export class NoiseProceduralTexture extends ProceduralTexture {
-        private _time = new Vector2();
+        private _time = 0;
 
         /** Gets or sets a value between 0 and 1 indicating the overall brightness of the texture (default is 0.2) */
         public brightness = 0.2;
 
-        /** Defines the first octave to start from (default is 3) */
-        public firstOctave = 3;
-
         /** Defines the number of octaves to process */
-        public octaves = 8;
+        public octaves = 3;
 
         /** Defines the level of persistence (0.8 by default) */
         public persistence = 0.8;
 
-        /** Gets or sets animation speed factor for X axis (default is 1) */
-        public animationSpeedFactorX = 1;
-
-        /** Gets or sets animation speed factor for Y axis (default is 1) */
-        public animationSpeedFactorY = 1;
+        /** Gets or sets animation speed factor (default is 1) */
+        public animationSpeedFactor = 1;
 
         /**
          * Creates a new NoiseProceduralTexture
@@ -43,14 +37,12 @@ module BABYLON {
                 return;
             }
 
-            this._time.x += scene.getAnimationRatio() * this.animationSpeedFactorX * 0.001;
-            this._time.y += scene.getAnimationRatio() * this.animationSpeedFactorY * 0.001;
+            this._time += scene.getAnimationRatio() * this.animationSpeedFactor * 0.01;
 
             this.setFloat("brightness", this.brightness);
-            this.setInt("firstOctave", this.firstOctave);
             this.setInt("octaves", this.octaves);
             this.setFloat("persistence", this.persistence);
-            this.setVector2("timeScale", this._time);
+            this.setFloat("timeScale", this._time);
         }
 
         /** Generate the current state of the procedural texture */

+ 31 - 0
src/Particles/babylon.particleSystem.ts

@@ -157,6 +157,15 @@
         public preventAutoStart: boolean = false;
 
         /**
+         * Gets or sets a texture used to add random noise to particle positions
+         */
+        public noiseTexture: Texture;
+
+        public noiseGridSize = new Vector2(1, 1);
+
+        public noiseStrength = 50;
+
+        /**
          * This function can be defined to provide custom update for active particles.
          * This function will be called instead of regular update (age, position, color, etc.).
          * Do not forget that this function will be called on every frame so try to keep it simple and fast :)
@@ -511,6 +520,14 @@
             this.particleEmitterType = new BoxParticleEmitter();
 
             this.updateFunction = (particles: Particle[]): void => {
+                let noiseTextureData: Nullable<Uint8Array> = null;
+                let noiseTextureSize: Nullable<ISize> = null;
+
+                if (this.noiseTexture) { // We need to get texture data back to CPU
+                    noiseTextureData = <Nullable<Uint8Array>>(this.noiseTexture.readPixels());
+                    noiseTextureSize = this.noiseTexture.getSize();
+                }
+
                 for (var index = 0; index < particles.length; index++) {
                     var particle = particles[index];
                     particle.age += this._scaledUpdateSpeed;
@@ -570,6 +587,20 @@
                         particle.direction.scaleToRef(directionScale, this._scaledDirection);
                         particle.position.addInPlace(this._scaledDirection);
 
+                        if (noiseTextureData && noiseTextureSize) {
+                            let fetchedColorR = Tools.FetchR(particle.position.x / this.noiseGridSize.x, particle.position.y / this.noiseGridSize.y, noiseTextureSize.width, noiseTextureSize.height,  noiseTextureData);
+                            let fetchedColorG = Tools.FetchR(particle.position.x / this.noiseGridSize.x + 0.33, particle.position.y / this.noiseGridSize.y + 0.66, noiseTextureSize.width, noiseTextureSize.height,  noiseTextureData);
+                            let fetchedColorB = Tools.FetchR(particle.position.x / this.noiseGridSize.x + 0.66, particle.position.y / this.noiseGridSize.y + 0.33, noiseTextureSize.width, noiseTextureSize.height,  noiseTextureData);
+                            
+                            let force = Tmp.Vector3[0];
+                            let scaledForce = Tmp.Vector3[1];
+
+                            force.copyFromFloats(2 * fetchedColorR - 1, 2 * fetchedColorG - 1, 2 * fetchedColorB - 1);
+
+                            force.scaleToRef(this._scaledUpdateSpeed * this.noiseStrength, scaledForce);
+                            particle.direction.addInPlace(scaledForce);
+                        }
+
                         this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
                         particle.direction.addInPlace(this._scaledGravity);
 

+ 23 - 37
src/Shaders/noise.fragment.fx

@@ -2,53 +2,39 @@
 
 // Uniforms
 uniform float brightness;
-uniform int firstOctave;
 uniform int octaves;
 uniform float persistence;
-uniform vec2 timeScale;
+uniform float timeScale;
 
 // Varyings
 varying vec2 vUV;
 
 // Functions
-float noise(int x,int y)
-{   
-    float fx = float(x);
-    float fy = float(y);
-    
-    return 2.0 * fract(sin(dot(vec2(fx, fy), vec2(12.9898, 78.233))) * 43758.5453) - 1.0;
-}
-
-float smoothNoise(int x,int y)
-{
-    return noise(x, y) / 4.0 + (noise(x + 1, y) + noise(x - 1,y) + 
-           noise(x, y + 1) + noise(x, y - 1)) / 8.0 + (noise(x + 1, y + 1) +
-           noise(x + 1,y - 1) + noise(x - 1, y + 1) + noise(x - 1,y - 1)) / 16.0;
-}
-
-float cosInterpolation(float x,float y,float n)
+vec2 hash22(vec2 p)
 {
-    float r = n * 3.1415926;
-    float f = (1.0 - cos(r)) * 0.5;
-    return x * (1.0 - f) + y * f;    
+    p = p * mat2(127.1, 311.7, 269.5, 183.3);
+	p = -1.0 + 2.0 * fract(sin(p) * 43758.5453123);
+	return sin(p * 6.283 + timeScale);
 }
 
-float interpolationNoise(float x, float y)
+float interpolationNoise(vec2 p)
 {
-    int ix = int(x);
-    int iy = int(y);
-    float fracx = x - float(int(x));
-    float fracy = y - float(int(y));
+	vec2 pi = floor(p);
+    vec2 pf = p-pi;
     
-    float v1 = smoothNoise(ix, iy);
-    float v2 = smoothNoise(ix + 1, iy);
-    float v3 = smoothNoise(ix, iy + 1);
-    float v4 = smoothNoise(ix + 1, iy + 1);
+    vec2 w = pf * pf * (3.-2. * pf);
     
-   	float i1 = cosInterpolation(v1, v2, fracx);
-    float i2 = cosInterpolation(v3, v4, fracx);
+    float f00 = dot(hash22(pi + vec2(.0,.0)), pf-vec2(.0,.0));
+    float f01 = dot(hash22(pi + vec2(.0,1.)), pf-vec2(.0,1.));
+    float f10 = dot(hash22(pi + vec2(1.0,0.)), pf-vec2(1.0,0.));
+    float f11 = dot(hash22(pi + vec2(1.0,1.)), pf-vec2(1.0,1.));
+     
+    float xm1 = mix(f00,f10,w.x);
+    float xm2 = mix(f01,f11,w.x);
     
-    return cosInterpolation(i1, i2, fracy);    
+    float ym = mix(xm1,xm2,w.y); 
+    return ym;
+   
 }
 
 float perlinNoise2D(float x,float y)
@@ -56,11 +42,11 @@ float perlinNoise2D(float x,float y)
     float sum = 0.0;
     float frequency = 0.0;
     float amplitude = 0.0;
-    for(int i = firstOctave; i < octaves + firstOctave; i++)
+    for(int i = 0; i < octaves; i++)
     {
         frequency = pow(2.0, float(i));
         amplitude = pow(persistence, float(i));
-        sum = sum + interpolationNoise(x * frequency, y * frequency) * amplitude;
+        sum = sum + interpolationNoise(vec2(x * frequency, y * frequency)) * amplitude;
     }
     
     return sum;
@@ -69,8 +55,8 @@ float perlinNoise2D(float x,float y)
 // Main
 void main(void)
 {
-    float x = abs(vUV.x + timeScale.x);
-    float y = abs(vUV.y + timeScale.y);
+    float x = abs(vUV.x);
+    float y = abs(vUV.y);
 
     float noise = brightness + (1.0 - brightness) * perlinNoise2D(x,y);
 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 37 - 0
src/Tools/babylon.tools.ts