David Catuhe %!s(int64=7) %!d(string=hai) anos
pai
achega
28af7438ef

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7108 - 7104
dist/preview release/babylon.d.ts


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 9 - 9
dist/preview release/babylon.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 48 - 25
dist/preview release/babylon.max.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 48 - 25
dist/preview release/babylon.no-module.max.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 9 - 9
dist/preview release/babylon.worker.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 48 - 25
dist/preview release/es6.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 13 - 13
dist/preview release/viewer/babylon.viewer.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 52 - 30
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 1
dist/preview release/what's new.md

@@ -10,9 +10,11 @@
 - New GUI control: the [Grid](http://doc.babylonjs.com/how_to/gui#grid) ([Deltakosh](https://github.com/deltakosh))
 - New `serialize` and `Parse` functions to serialize and parse all procedural textures from the Procedural Textures Library ([julien-moreau](https://github.com/julien-moreau))
 - Particle system improvements ([Deltakosh](https://github.com/deltakosh))
-  - Improved rendering performance (up to x2 on low end devices)
+  - Improved CPU particles rendering performance (up to x2 on low end devices)
+  - Added support for `isBillboardBased`
   - Added support for `minScaleX`, `minScaleY`, `maxScaleX`, `maxScaleY`
   - Added support for `radiusRange` for sphere emitter
+  
 
 ## Updates
 

+ 1 - 2
src/Particles/EmitterTypes/babylon.IParticleEmitterType.ts

@@ -6,12 +6,11 @@ module BABYLON {
     export interface IParticleEmitterType {
         /**
          * Called by the particle System when the direction is computed for the created particle.
-         * @param emitPower is the power of the particle (speed)
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
 
         /**
          * Called by the particle System when the position is computed for the created particle.

+ 2 - 3
src/Particles/EmitterTypes/babylon.boxParticleEmitter.ts

@@ -32,17 +32,16 @@ module BABYLON {
 
         /**
          * Called by the particle System when the direction is computed for the created particle.
-         * @param emitPower is the power of the particle (speed)
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             var randX = Scalar.RandomRange(this.direction1.x, this.direction2.x);
             var randY = Scalar.RandomRange(this.direction1.y, this.direction2.y);
             var randZ = Scalar.RandomRange(this.direction1.z, this.direction2.z);
 
-            Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
+            Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
         }
 
         /**

+ 3 - 4
src/Particles/EmitterTypes/babylon.coneParticleEmitter.ts

@@ -57,14 +57,13 @@ module BABYLON {
 
         /**
          * Called by the particle System when the direction is computed for the created particle.
-         * @param emitPower is the power of the particle (speed)
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             if (this._angle === 0) {
-                Vector3.TransformNormalFromFloatsToRef(0, emitPower, 0, worldMatrix, directionToUpdate);
+                Vector3.TransformNormalFromFloatsToRef(0, 1.0, 0, worldMatrix, directionToUpdate);
             }
             else {
                 // measure the direction Vector from the emitter to the particle.
@@ -77,7 +76,7 @@ module BABYLON {
                 direction.z += randZ;
                 direction.normalize();
 
-                Vector3.TransformNormalFromFloatsToRef(direction.x * emitPower, direction.y * emitPower, direction.z * emitPower, worldMatrix, directionToUpdate);
+                Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
             }
         }
 

+ 7 - 8
src/Particles/EmitterTypes/babylon.sphereParticleEmitter.ts

@@ -28,12 +28,11 @@ module BABYLON {
 
         /**
          * Called by the particle System when the direction is computed for the created particle.
-         * @param emitPower is the power of the particle (speed)
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
             var randX = Scalar.RandomRange(0, this.directionRandomizer);
             var randY = Scalar.RandomRange(0, this.directionRandomizer);
@@ -43,7 +42,7 @@ module BABYLON {
             direction.z += randZ;
             direction.normalize();
 
-            Vector3.TransformNormalFromFloatsToRef(direction.x * emitPower, direction.y * emitPower, direction.z * emitPower, worldMatrix, directionToUpdate);
+            Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
         }
 
         /**
@@ -53,9 +52,10 @@ module BABYLON {
          * @param particle is the particle we are computed the position for
          */
         public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
-            var phi = Scalar.RandomRange(0, 2 * Math.PI);
-            var theta = Scalar.RandomRange(0, Math.PI);
             var randRadius = this.radius - Scalar.RandomRange(0, this.radius * this.radiusRange);
+            var v = Scalar.RandomRange(0, 1.0); 
+            var phi = Scalar.RandomRange(0, 2 * Math.PI);
+            var theta = Math.acos(2 * v - 1);
             var randX = randRadius * Math.cos(phi) * Math.sin(theta);
             var randY = randRadius * Math.cos(theta);
             var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
@@ -149,16 +149,15 @@ module BABYLON {
 
         /**
          * Called by the particle System when the direction is computed for the created particle.
-         * @param emitPower is the power of the particle (speed)
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             var randX = Scalar.RandomRange(this.direction1.x, this.direction2.x);
             var randY = Scalar.RandomRange(this.direction1.y, this.direction2.y);
             var randZ = Scalar.RandomRange(this.direction1.z, this.direction2.z);
-            Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
+            Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
         }
 
         /**

+ 29 - 6
src/Particles/babylon.gpuParticleSystem.ts

@@ -57,7 +57,7 @@
 
         private _randomTexture: RawTexture;
 
-        private readonly _attributesStrideSize = 18;
+        private readonly _attributesStrideSize = 19;
         private _updateEffectOptions: EffectCreationOptions;
 
         private _randomTextureSize: number;
@@ -343,6 +343,23 @@
         public getClassName(): string {
             return "GPUParticleSystem";
         }            
+        
+        private _isBillboardBased = true;
+
+        /**
+         * Gets or sets a boolean indicating if the particles must be rendered as billboard or aligned with the direction
+         */
+        public get isBillboardBased(): boolean {
+            return this._isBillboardBased;
+        }      
+        
+        public set isBillboardBased(value: boolean) {
+            if (this._isBillboardBased === value) {
+                return;
+            }
+
+            this._isBillboardBased = value;
+        }          
 
         /**
          * Instantiates a GPU particle system.
@@ -413,8 +430,8 @@
             updateVertexBuffers["seed"] = source.createVertexBuffer("seed", 5, 1);
             updateVertexBuffers["size"] = source.createVertexBuffer("size", 6, 3);
             updateVertexBuffers["color"] = source.createVertexBuffer("color", 9, 4);
-            updateVertexBuffers["direction"] = source.createVertexBuffer("direction", 13, 3);
-            updateVertexBuffers["angle"] = source.createVertexBuffer("angle", 16, 2);
+            updateVertexBuffers["direction"] = source.createVertexBuffer("direction", 13, 4);
+            updateVertexBuffers["angle"] = source.createVertexBuffer("angle", 17, 2);
            
             let vao = this._engine.recordVertexArrayObject(updateVertexBuffers, null, this._updateEffect);
             this._engine.bindArrayBuffer(null);
@@ -429,7 +446,8 @@
             renderVertexBuffers["life"] = source.createVertexBuffer("life", 4, 1, this._attributesStrideSize, true);
             renderVertexBuffers["size"] = source.createVertexBuffer("size", 6, 3, this._attributesStrideSize, true);           
             renderVertexBuffers["color"] = source.createVertexBuffer("color", 9, 4, this._attributesStrideSize, true);
-            renderVertexBuffers["angle"] = source.createVertexBuffer("angle", 16, 2, this._attributesStrideSize, true);
+            renderVertexBuffers["direction"] = source.createVertexBuffer("direction", 13, 4, this._attributesStrideSize, true);
+            renderVertexBuffers["angle"] = source.createVertexBuffer("angle", 17, 2, this._attributesStrideSize, true);
 
             renderVertexBuffers["offset"] = spriteSource.createVertexBuffer("offset", 0, 2);
             renderVertexBuffers["uv"] = spriteSource.createVertexBuffer("uv", 2, 2);
@@ -474,7 +492,8 @@
               // direction
               data.push(0.0);
               data.push(0.0);
-              data.push(0.0);     
+              data.push(0.0);  
+              data.push(0.0);    
               
               // angle
               data.push(0.0);  
@@ -525,12 +544,16 @@
                 defines = "\n#define CLIPPLANE";
             }
 
+            if (this._isBillboardBased) {
+                defines = "\n#define BILLBOARD";
+            }            
+
             if (this._renderEffect && this._renderEffect.defines === defines) {
                 return;
             }
 
             this._renderEffect = new Effect("gpuRenderParticles", 
-                                            ["position", "age", "life", "size", "color", "offset", "uv", "angle"], 
+                                            ["position", "age", "life", "size", "color", "offset", "uv", "direction", "angle"], 
                                             ["view", "projection", "colorDead", "invView", "vClipPlane"], 
                                             ["textureSampler"], this._scene.getEngine(), defines);
         }        

+ 5 - 0
src/Particles/babylon.particle.ts

@@ -60,6 +60,11 @@
          */
         public cellIndex: number = 0;
 
+        /**
+         * Defines the energy applied to the particle direction.
+         */
+        public emitPower = 0;        
+
         private _currentFrameCounter = 0;
 
         /**

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

@@ -269,7 +269,7 @@
          * This function can be defined to specify initial direction for every new particle.
          * It by default use the emitterType defined function
          */
-        public startDirectionFunction: (emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle) => void;
+        public startDirectionFunction: (worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle) => void;
         /**
          * This function can be defined to specify initial position for every new particle.
          * It by default use the emitterType defined function
@@ -453,7 +453,7 @@
 
                         particle.angle += particle.angularSpeed * this._scaledUpdateSpeed;
 
-                        particle.direction.scaleToRef(this._scaledUpdateSpeed, this._scaledDirection);
+                        particle.direction.scaleToRef(this._scaledUpdateSpeed * particle.emitPower, this._scaledDirection);
                         particle.position.addInPlace(this._scaledDirection);
 
                         this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
@@ -749,7 +749,7 @@
 
                 this._particles.push(particle);
 
-                var emitPower = Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
+                particle.emitPower = Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
 
                 if (this.startPositionFunction) {
                     this.startPositionFunction(worldMatrix, particle.position, particle);
@@ -759,10 +759,10 @@
                 }
 
                 if (this.startDirectionFunction) {
-                    this.startDirectionFunction(emitPower, worldMatrix, particle.direction, particle);
+                    this.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 else {
-                    this.particleEmitterType.startDirectionFunction(emitPower, worldMatrix, particle.direction, particle);
+                    this.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
 
                 particle.lifeTime = Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);

+ 25 - 0
src/Shaders/gpuRenderParticles.vertex.fx

@@ -12,6 +12,7 @@ in vec3 size;
 in vec4 color;
 in vec2 offset;
 in vec2 uv;
+in vec4 direction;
 in vec2 angle;
 
 out vec2 vUV;
@@ -31,6 +32,7 @@ void main() {
 
   vec2 cornerPos = offset * size.yz * size.x;
 
+#ifdef BILLBOARD
   // Rotate
 	vec4 rotatedCorner;
 	rotatedCorner.x = cornerPos.x * cos(angle.x) - cornerPos.y * sin(angle.x);
@@ -41,6 +43,29 @@ void main() {
   // Expand position
   vec4 viewPosition = view * vec4(position, 1.0);
   gl_Position = projection * (viewPosition + rotatedCorner);
+#else
+  // Rotate
+	vec3 rotatedCorner;
+	rotatedCorner.x = cornerPos.x * cos(angle.x) - cornerPos.y * sin(angle.x);
+	rotatedCorner.y = 0.;
+	rotatedCorner.z = cornerPos.x * sin(angle.x) + cornerPos.y * cos(angle.x);
+
+	vec3 yaxis = normalize(direction.xyz);
+	vec3 xaxis = normalize(cross(vec3(0., 1.0, 0.), yaxis));
+	vec3 zaxis = normalize(cross(yaxis, xaxis));
+
+	vec3 row0 = vec3(xaxis.x, xaxis.y, xaxis.z);
+	vec3 row1 = vec3(yaxis.x, yaxis.y, yaxis.z);
+	vec3 row2 = vec3(zaxis.x, zaxis.y, zaxis.z);
+
+	mat3 rotMatrix =  mat3(row0, row1, row2);
+
+	vec3 alignedCorner = rotMatrix * rotatedCorner;
+
+  // Expand position
+  vec4 viewPosition = view * vec4(position + alignedCorner, 1.0);  
+  gl_Position = projection * viewPosition;
+#endif
 
 	// Clip plane
 #ifdef CLIPPLANE

+ 8 - 7
src/Shaders/gpuUpdateParticles.vertex.fx

@@ -49,7 +49,7 @@ in float life;
 in float seed;
 in vec3 size;
 in vec4 color;
-in vec3 direction;
+in vec4 direction;
 in vec2 angle;
 
 // Output
@@ -59,7 +59,7 @@ out float outLife;
 out float outSeed;
 out vec3 outSize;
 out vec4 outColor;
-out vec3 outDirection;
+out vec4 outDirection;
 out vec2 outAngle;
 
 vec3 getRandomVec3(float offset) {
@@ -123,7 +123,7 @@ void main() {
 
     // Position on the sphere surface
     float phi = 2.0 * PI * randoms2.x;
-    float theta = PI * randoms2.y;
+    float theta = acos(2.0 * randoms2.y - 1.0);
     float randX = cos(phi) * sin(theta);
     float randY = cos(theta);
     float randZ = sin(phi) * sin(theta);
@@ -168,19 +168,20 @@ void main() {
     direction = 2.0 * (getRandomVec3(seed) - vec3(0.5, 0.5, 0.5));
 #endif
 
-    float power = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
+    outDirection.w = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
 
     outPosition = (emitterWM * vec4(position, 1.)).xyz;
-    outDirection = (emitterWM * vec4(direction * power, 0.)).xyz;
+    outDirection.xyz = (emitterWM * vec4(direction, 0.)).xyz;
 
   } else {   
-    outPosition = position + direction * timeDelta;
+    outPosition = position + direction.xyz * timeDelta * direction.w;
     outAge = age + timeDelta;
     outLife = life;
     outSeed = seed;
     outColor = color;
     outSize = size;
-    outDirection = direction + gravity * timeDelta;
+    outDirection.w = direction.w;
+    outDirection.xyz = direction.xyz + gravity * timeDelta;
     outAngle = vec2(angle.x + angle.y * timeDelta, angle.y);
   }
 }

+ 8 - 13
src/Shaders/particles.vertex.fx

@@ -52,25 +52,20 @@ void main(void) {
 	rotatedCorner.z = cornerPos.x * sin(angle) + cornerPos.y * cos(angle);
 	rotatedCorner.y = 0.;
 
-	vec3 worldPos = position + rotatedCorner; 
-
-	vec3 yaxis = normalize(position);
+	vec3 yaxis = normalize(direction);
 	vec3 xaxis = normalize(cross(vec3(0., 1.0, 0.), yaxis));
 	vec3 zaxis = normalize(cross(yaxis, xaxis));
 
-	vec4 row0 = vec4(xaxis.x, xaxis.y, xaxis.z, 0.);
-	vec4 row1 = vec4(yaxis.x, yaxis.y, yaxis.z, 0.);
-	vec4 row2 = vec4(zaxis.x, zaxis.y, zaxis.z, 0.);
-	// vec4 row0 = vec4(1., 0., 0., 0.);
-	// vec4 row1 = vec4(0., 1., 0., 0.);
-	// vec4 row2 = vec4(0., 0., 1., 0.);
-	vec4 row3 = vec4(0., 0., 0., 1.0);
+	vec3 row0 = vec3(xaxis.x, xaxis.y, xaxis.z);
+	vec3 row1 = vec3(yaxis.x, yaxis.y, yaxis.z);
+	vec3 row2 = vec3(zaxis.x, zaxis.y, zaxis.z);
 
-	mat4 rotMatrix =  mat4(row0, row1, row2, row3);
+	mat3 rotMatrix =  mat3(row0, row1, row2);
 
-	vec4 alignedWorld = rotMatrix * vec4(worldPos, 0.0);
+	vec3 alignedCorner = rotMatrix * rotatedCorner;
+	vec3 worldPos = position + alignedCorner; 
 
-	gl_Position = projection * view * vec4(alignedWorld.xyz, 1.0);  
+	gl_Position = projection * view * vec4(worldPos, 1.0);  
 #endif	
 	vColor = color;