Jump to content

Is one particle at a time an abuse of particle system?


qqdarren
 Share

Recommended Posts

I want a box to spit out words. After trying it with a custom plane, and not getting very far in two hours, I realized particles already do everything I am trying to do, and in 5 minutes I had hacked one of the playground demos:

 

    http://www.babylonjs-playground.com/#1SHP80

 

Q1. How inefficient is this? Particles are fun, but I can get away with just one at a time, so how much am I paying for what I don't need? (I need the final animation to work on mobile... just tried the above on a Nexus 7, and get between 25fps and 58fps - very sensitive to screen size and orientation, it seems.)

 

Q2. Do I need to run one ParticleSystem instance for each word (i.e. for each texture)? As you can see in the above demo I tried to change the texture, dynamically, on mouse click, but it does not work.

 

 

Link to comment
Share on other sites

just an idea about this, issuing from my knowledge of Phaser which uses a webGL renderer also:

maybe could we (could I ?) investigate about a texture atlas, as for sprites, for particules, so different textures could be use per particle

 

example here : http://phaser.io/examples/v2/particles/collision

here the texture atlas is a spritesheet

Link to comment
Share on other sites

The optimization David refers to (I am guessing) is that all visible particles must use the same texture. But the texture itself can be changed at any time, it seems:

 

    http://www.babylonjs-playground.com/#1SHP80#6

 

Click the box to rotate between four text strings and an image. Notice that the active particles change as soon as you click. (That may be desirable, it may not...)

Link to comment
Share on other sites

Hack:  http://urbanproductions.com/wingy/babylon/particlefun/splode/pharticles02.htm  (stutters badly these days on my new puter, dunno why)

 

To get to the grit... http://urbanproductions.com/wingy/babylon/particlefun/splode/js/particleSystem2_02.js

 

Search for // Add new ones

 

See the particle = BABYLON.Mesh.CreateBox("box", .2, this._scene)   ?

 

Sure ya do.  Also notice the turned-off vertexBuffer (vbo). There's lots of things turned-off... because emitting BJS standard mesh... is quite a bit different from transforming little geo-sections of dynamicVertexBuffers.  My box particles really don't fly.  They just fall out of the emitter.  The standard particleSystem "flyer funcs" are not ready for flying standard BJS CreatedShapes.  So that's one part of this hack... that is not complete.  Sorry.

 

This (my code/way) is a terrible abuse of a particle system, and it's cpu-heavy as hell.  Let it be known that this code was my first-ever attempt to emit standard BJS mesh... instead of quads that are all stored in the same dynamicVertexBuffer...  separated only by the lack of indices connecting them together.  

 

And, of course, putting a particleSystem on each particle of a particleSystem (the smoke)... is just plain demented.  :)

 

In a way, particles are a single ground grid... with half of its indices missing, right? 

 

They are grid cells that are detached from each other (yet still part of a single mesh, sort-of).  And that's why they are FAST!  Vrrrooooooooomm!  A single ground-grid object... exploded into separate 2-triangle face-pairs.   (huh?)  Quads.  StupidPlanes.  :)

 

So, Wingy, how do we FLY (position/rotate/scale) the cell grids of a ground... without moving each other? 

 

TransformCoodinates!  Wow!  Why position, rotate and scale an entire mesh... when you can do such things to only 4 points of a mesh, right?  Do enough 4-point transforms, and you are flying particles!  YAY!  https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Particles/babylon.particleSystem.js#L74  Lines 78 and 84 are the transformers, and I can feel the power radiating from them, can't you?  They are beefy dynamicVertexBuffer-bending power tools, not intended for children or drunks.  Hard hats and steel-toed boots, please!  :)

 

Ain't it amazing?  I recently told somebody how to make hexagon-shaped particles... hundreds of them... for a map grid-o-hexagons.  I hope he tries it... because I have a feeling it is going to be friggin' blazing fast... just like our standard particles.  I don't know why our hex-grid-making friend would need it to be lightning fast, but by-gosh, he's got the speed if he needs it.  heh   And, he's got HUGE grid-size capabilities... because particles are lightweight.

 

But now, back to you, Fen.  Wanna do it more correctly?  Then DON'T use standard Babylon mesh for particles.  The fastest way is to build the mesh "geometry" in a single vertexBuffer just like standard particles... but make it whatever shape you wish. 

 

IF YOUR wanted particle shape and indices "pattern" that is used to make your mesh... isn't based-upon 4-point geometries, then you need to rewrite the transformers in the BJS particle code (the geometry flyers). 

 

For example... each particle trajectory, scale, z-spin, color/texture transforms, and all the indices of a standard particle... are 4-point related/specialized.  If you want to use 3d things like boxes... it will take all 8-point transforms (things that get updated).  It will take a more-serious particleSystem hack... to get it to do speeds comparable-with our current particles.  You will find out quickly... that you lose 50% of the particleSystem speed... by using BJS standard mesh.  Using thin-mesh like our current particleSystem does... it will cook... but it's harder to code, I suspect.

 

You probably know most of this already, Fen.  Sorry for the over-explaining, if so.  Be well.

Link to comment
Share on other sites

fenomas Which part of the particle system did you want to be 3D-ified? In a sense, this demo is full of 3D mesh "particles":   http://www.sitepoint.com/understanding-collisions-physics-babylon-js-oimo-js/   (I *think* that if you specify no bounding box, or a very tiny one in the middle of the balls, then they will pass through each other, and in that case you just use the physics engine for the trajectory and gravity aspects of the particles.)

(Going in a different direction, the poor man's version might be to render a 3D view of your mesh to a 2D canvas, and use that as the particle texture.)

Link to comment
Share on other sites

Hi chaps, sorry I should have been more clear. 

 

I just want to have some particles that composite normally (i.e. don't get drawn on top of meshes with alpha). I suppsed the quickest way would be to make a quad with the particle texture, then spawn lots of instances (or clones? not sure it matters) that float around and then disappear. So that's what I was about to write, but I wondered if it had been done already.

 

qqdarren, that's a killer demo, I'd forgotten about it. Well beyond what I was going to do though ;)

 

Wingy: to be honest you lost me there somewhat. ;) If I'm just using simple quads for particles (with billboard mode, I expect), do you think managing all their vertices in a VBO would work out better than just making meshes? I guess it would take a custom shader, right? Can that be done without the draw becoming a separate step (as with the built-in particles)?

Link to comment
Share on other sites

Just to wrap up my original question, here is a particle system that spits out 4 different sentences at the same time:   http://www.babylonjs-playground.com/#1KDJUH#1

 

It is simply 4 particle system objects with the same settings! They are in sync because the lifetime is not randomized. This version adds that random factor, to set them free: http://www.babylonjs-playground.com/#1KDJUH#2

You can increase capacity to have more than one of each sentence on screen at the same time.

 

(These demos are just thrown together; I'd love feedback on ways I'm being inefficient with either CPU or memory, by someone who understands the underlying code better than me.)

Link to comment
Share on other sites

@fenomas :

I just read quickly the particle system code.

As you imagined it, each particle seem to be a quad (I don't really know what is a quad therefore :) ), at least a tiny square composed with two triangles :

https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Particles/babylon.particleSystem.ts#L97

 

then textured further ...

 

The used blend mode is set at the start with this line (see constant values lines 14 and 15) :

https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Particles/babylon.particleSystem.ts#L43

 

The draw order and draw call are done here :

https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Particles/babylon.particleSystem.ts#L385

 

it's based on forceDepthWrite boolean and blendmode value.

 

So maybe could you just do a test with changing the blend mode value of the blendmode public property to BLENDMODE_STANDARD and forceDepthWrite to true and check if it behaves as you expect ?

Don't really know... but I believe it's almost what you suggested about quads and normal compositing

Link to comment
Share on other sites

 

Wingy: to be honest you lost me there somewhat. ;) If I'm just using simple quads for particles (with billboard mode, I expect), do you think managing all their vertices in a VBO would work out better than just making meshes? I guess it would take a custom shader, right? Can that be done without the draw becoming a separate step (as with the built-in particles)?

 

Ohhh, yeah, you wanted a different material on each particle, or the freedom to do that?  Or was that qqdarren?  I'm confused now.  :)

 

 

projects that implement particle effects using regular meshes

 

Careful here,  "particle effects" is an extra feature of particleSystems.  :)  But I think you mean making standard mesh act like particles used in particleSystems.

 

Materials get limits when using the VBO method, it seems. But this talk is at my edu-edge, so I could be saying all sorts of wrong things.  :)

 

The VBO system gives you less versatility per particle, but it gives what appears to be MUCH faster performance.  So, if your mesh emitter/sprayer needs FEW particles, no problems.  You can fly a few parabola trajectories with standard shapes, and call it a day.  (Jerome recently made a cannon with cannonball bounce, and showed it to us in The Wingnut Chronicles, so that might be usable for you.)

 

But if you are putting 10,000 particles on-screen at once, then it might be wise to look at different (and industrial-grade) options (like VBO and transformCoords).

 

In certain situations (not too many particles), you can make a physics explosion, too.  For example, stack a pile of invisible boxes, then BOOM!  SetPhysicsState on all boxes, make them all visible, and applyImpulse in a random upward direction on all of them... instantly.  Actually, you make the stack, setPhysicsState on all, and then SLAM another mesh into the bottom of them, using a powerful applyImpulse on that "impactor" mesh.  :)

 

They'll fly and bounce at about half the speed of Jerome's non-physics-yet-still-bounces cannon shot.  *shrug*  Its another possible option to get standard mesh flying.

 

Sorry for the topic swerve, QQD.  That was my fault.  That text sprayer looks kind of cool, eh?  I like it.  Quite an advertising machine.  :o  Stack a few more PS atop, spraying confetti, streamers, and balloons, and you have a serious "hoopla" generator.

Link to comment
Share on other sites

I read again the particle system code.

I believe I understand some things so far and don't understand others ...

 

AFAI, the particle system is to be seen as a single big mesh. Its faces are pair of triangles making small squared which are then textured. These squares aren't stuck to others like in a classical volume mesh but have their own coordinates (positions) evolving with time.

So many little independant squares in a big mesh.

Am I right so far ?

 

The idea coming to my mind is that it wouldn't be maybe not that complex to set UV for each vertex at creation so we could use a kind of texture atlas instead of a unique image for the particles. The goal would be to have different images within the same emitter for different particles.

 

The thing I don't get, reading the code, is where the particule orientation (ever facing the cam...like billboard mode) is done ? Perhaps, it even doesn't exist and as we use usually small images for particles, we just believe they all face us but they don't !  :P

 

However looking closely at qqdaren's PG  http://www.babylonjs-playground.com/#1KDJUH#2 , the large text particles seemto always face the cam. 

Link to comment
Share on other sites

Wow! Thanks for doing deep thinking about this Wingy and Jerome.

 

QQ, sorry I kind of hijacked your thread - I thought you were done with it and I was adding a trivial footnote. ;) Hope your side is taken care of.

 

Wingy: concerning VBOs and whatnot, I barely understand this stuff but I think what's going on here is: for typical meshes the vertices go into a VBO and never change, and the mesh is moved around with a transform matrix, which changes each frame. So for lots of plain quads you have lots of small static VBOs and lots of transform matrices. With particle system, instead it fills a VBO with particle locations and then updates them each frame, but in return there's only one transform matrix for the whole system, rather than each particle. Thus the whole set of particles can then be drawn in one call (i.e. as far as the GPU is concerned the particle system is like a single mesh whose vertices move around). 

 

However, since the system's one draw call takes place after the rest of the scene is drawn, it doesn't composite, except with pixels that are opaque (which I guess works due to the depth buffer). I don't know how forceDepthWrite fits into all this - no idea what it does, but I guess it's not something relevant to this. (Thanks for the demo jerome! I'd wanted to try that.)

 

Finally, Jerome for your question about orientation, I believe ParticleSystem particles never get their orientation fixed because they never had it set to begin with. For normal meshes their 3d position and rotation get transformed, and afterwards if they have a billboard mode they are then oriented towards the camera. But particles undergo a separate process, and don't have any 3d rotation to transform. Their position is transformed to screen coords and then their texture is drawn in screenspace.

 

Anyway that's how I take this to work. Code and solutions in a follow-up post.

Link to comment
Share on other sites

Ok understood about the different process for particle system (no 3d rotation to transform and direct clipping)

I think I will try something mesh based : an updatable mesh wich will be the "emitter"

it will be build with many independent faces, billboarded or not, (or pyramids - the most little volume doable with triangles - or cubes) which will be the particles

 

then some stress tests will be done to check how much such a system could be loaded with this kind of particles

Link to comment
Share on other sites

On to code: when I asked this question I had in mind something like this:

 

http://www.babylonjs-playground.com/#156EO#3

 

Nothing interesting, just a bunch of instances of a mesh with a texture being added, moved around, and then disposed. For small numbers of particles (i.e. dozens) this shouldn't kill performance, and obviously it composites normally since it's just regular meshes. If the meshes have transparency then it would get heavier due to sorting their draw order. 

 

(I'm not sure using a blend mode for regular meshes like this. I guess it could be done but as I understand it there are no mesh properties to set, you'd have to hook into the render function and dynamically twiddle engine settings depending on which mesh was about to be rendered, so it'd be pretty unwieldy.)

 

Now with all that said, if particles like this were to scale well they'd have to be drawn like particle system does - with one VBO for the system, but drawn during scene composition rather than on top afterwards. But knowing whether this would be possible goes beyond my understanding of BJS internals. If it can be done it'd be a neat hack.

Link to comment
Share on other sites

here is my first test today (too bored to write an article about BJS ;) ) : http://www.babylonjs-playground.com/#11VPQD

This test runs faster outside the PG (as for computeNormals optimization, I noticed the PG editor may have side effects on performance) on my computer.

It runs at 60 fps in Chrome and 37fps+ in FF on my computer.

 

What do we have here ?

Only a single mesh.

Each of its faces (triangles) are independent and their positions are updated each frame. I just set it to BILLBOARDMODE_Y

Since it is a real mesh, it is managed by BJS as other meshes in terms of z-depth and compositing, as you can check with the two boxes (transparent and opaque).

 

In this PG, 5000 particles are emitted and permanently recycled. So there are always 5000 flying particles.

 

Line 80 :

  // Particle system  var PS = new ParticleSystem(5000, 1, mat, scene);  PS.start(1.5);

5000 : particle number

1 : triangle size

mat : particle material, please note the normals ARE recomputed on each particle each frame here (may be disabled)

 

on start, 1.5 is the particle initial velocity

Link to comment
Share on other sites

stress test of this model here in Chrome :

particle size = 1

 

20K particles => 60 fps

25K particles => 50 fps

 

Well, this is not as powerful as the current particle system, but it has the advantages of a real mesh (and therefore only 1 draw call like the current system).

 

So it might be an alternative for those needing accuracy over power.

 

I will try to make squares (quads ?) instead of triangle and implement a way to set UV on these squares, so we will be able to use an image as a texture atlas, and so have different textures per particle

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...