Forráskód Böngészése

Better noise support for particles

David Catuhe 7 éve
szülő
commit
31f1105e3e

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 8511 - 8519
dist/preview release/babylon.d.ts


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 31 - 31
dist/preview release/babylon.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 24 - 32
dist/preview release/babylon.max.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 24 - 32
dist/preview release/babylon.no-module.max.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 31 - 31
dist/preview release/babylon.worker.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 24 - 32
dist/preview release/es6.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 37 - 37
dist/preview release/viewer/babylon.viewer.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 24 - 32
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -192,6 +192,8 @@
          */
         public gravity = Vector3.Zero();
 
+        private _emitterWorldMatrix: Matrix;
+
         private _colorGradients: Nullable<Array<ColorGradient>> = null;
         private _sizeGradients: Nullable<Array<FactorGradient>> = null;
         private _lifeTimeGradients: Nullable<Array<FactorGradient>> = null;
@@ -590,9 +592,15 @@
 
                         // Noise
                         if (noiseTextureData && noiseTextureSize) {
-                            let fetchedColorR = Tools.FetchR(particle.position.y, particle.position.z, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
-                            let fetchedColorG = Tools.FetchR(particle.position.x + 0.33, particle.position.z + 0.33, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
-                            let fetchedColorB = Tools.FetchR(particle.position.x - 0.33, particle.position.y - 0.33, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
+                            let localPosition = Tmp.Vector3[0];
+                            let emitterPosition = Tmp.Vector3[1];
+
+                            this._emitterWorldMatrix.getTranslationToRef(emitterPosition);
+                            particle.position.subtractToRef(emitterPosition, localPosition);
+
+                            let fetchedColorR = this._fetchR(localPosition.y, localPosition.z, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
+                            let fetchedColorG = this._fetchR(localPosition.x + 0.33, localPosition.z + 0.33, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
+                            let fetchedColorB = this._fetchR(localPosition.x - 0.33, localPosition.y - 0.33, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
                             
                             let force = Tmp.Vector3[0];
                             let scaledForce = Tmp.Vector3[1];
@@ -627,6 +635,17 @@
             }
         }
 
+        private _fetchR(u: number, v: number, width: number, height: number, pixels: Uint8Array): number {
+            u = Math.abs(u) * 0.5 + 0.5;
+            v = Math.abs(v) * 0.5 + 0.5;
+
+            let wrappedU = ((u * width) % width) | 0;
+            let wrappedV = ((v * height) % height) | 0;
+
+            let position = (wrappedU + wrappedV * width) * 4;
+            return pixels[position] / 255;
+        }          
+
         private _addFactorGradient(factorGradients: FactorGradient[], gradient: number, factor: number, factor2?: number) {
             let newGradient = new FactorGradient();
             newGradient.gradient = gradient;
@@ -1102,19 +1121,17 @@
             // Update current
             this._alive = this._particles.length > 0;
 
-            this.updateFunction(this._particles);
-
-            // Add new ones
-            var worldMatrix;
-
             if ((<AbstractMesh>this.emitter).position) {
                 var emitterMesh = (<AbstractMesh>this.emitter);
-                worldMatrix = emitterMesh.getWorldMatrix();
+                this._emitterWorldMatrix = emitterMesh.getWorldMatrix();
             } else {
                 var emitterPosition = (<Vector3>this.emitter);
-                worldMatrix = Matrix.Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
+                this._emitterWorldMatrix = Matrix.Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
             }
 
+            this.updateFunction(this._particles);
+
+            // Add new ones
             var particle: Particle;
             for (var index = 0; index < newParticles; index++) {
                 if (this._particles.length === this._capacity) {
@@ -1129,17 +1146,17 @@
                 let emitPower = Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
 
                 if (this.startPositionFunction) {
-                    this.startPositionFunction(worldMatrix, particle.position, particle);
+                    this.startPositionFunction(this._emitterWorldMatrix, particle.position, particle);
                 }
                 else {
-                    this.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
+                    this.particleEmitterType.startPositionFunction(this._emitterWorldMatrix, particle.position, particle);
                 }
 
                 if (this.startDirectionFunction) {
-                    this.startDirectionFunction(worldMatrix, particle.direction, particle);
+                    this.startDirectionFunction(this._emitterWorldMatrix, particle.direction, particle);
                 }
                 else {
-                    this.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
+                    this.particleEmitterType.startDirectionFunction(this._emitterWorldMatrix, particle.direction, particle);
                 }
 
                 if (emitPower === 0) {

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

@@ -274,9 +274,11 @@ void main() {
     outDirection = direction + gravity * timeDelta;
 
 #ifdef NOISE
-    float fetchedR = texture(noiseSampler, vec2(outPosition.y, outPosition.z)).r;
-    float fetchedG = texture(noiseSampler, vec2(outPosition.x + 0.33, outPosition.z + 0.33)).r;
-    float fetchedB = texture(noiseSampler, vec2(outPosition.z - 0.33, outPosition.y - 0.33)).r;
+    vec3 localPosition = outPosition - emitterWM[3].xyz;
+
+    float fetchedR = texture(noiseSampler, vec2(localPosition.y, localPosition.z) * vec2(0.5) + vec2(0.5)).r;
+    float fetchedG = texture(noiseSampler, vec2(localPosition.x + 0.33, localPosition.z + 0.33) * vec2(0.5) + vec2(0.5)).r;
+    float fetchedB = texture(noiseSampler, vec2(localPosition.z - 0.33, localPosition.y - 0.33) * vec2(0.5) + vec2(0.5)).r;
 
     vec3 force = vec3(2. * fetchedR - 1., 2. * fetchedG - 1., 2. * fetchedB - 1.) * noiseStrength;
 

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

@@ -169,32 +169,7 @@
             color.g = pixels[position + 1] / 255;
             color.b = pixels[position + 2] / 255;
             color.a = pixels[position + 3] / 255;
-        } 
-
-         /**
-         * Read the R component of a byte array at a specified coordinates (taking in account wrapping)
-         * @param u defines the coordinate on X axis
-         * @param v defines the coordinate on Y axis 
-         * @param width defines the width of the source data
-         * @param height defines the height of the source data
-         * @param pixels defines the source byte array
-         * @returns the R value
-         */
-        public static FetchR(u: number, v: number, width: number, height: number, pixels: Uint8Array): number {
-
-            u = Math.abs(u) + 0.5;
-            v = Math.abs(v) + 0.5;
-
-            let wrappedU = ((u * width) % width) | 0;
-            let wrappedV = ((v * height) % height) | 0;
-
-            // let wrappedU =  (Math.abs(u) - Math.floor(Math.abs(u))) * width | 0;
-            // let wrappedV =  (Math.abs(v) - Math.floor(Math.abs(v))) * height | 0;
-            
-
-            let position = (wrappedU + wrappedV * width) * 4;
-            return pixels[position] / 255;
-        }         
+        }       
 
         /**
 		 * Interpolates between a and b via alpha