Jump to content

mesh based particle system


jerome
 Share

Recommended Posts

A new topic seems better for continuing this :http://www.html5gamedevs.com/topic/15088-is-one-particle-at-a-time-an-abuse-of-particle-system/?p=85787

 

So, here's a very little improvement (nano seconds !) : http://www.babylonjs-playground.com/#11VPQD#2

the normals aren't recomputed on triangles each frame

the triangle material has an enabled backFaceCulling, since there is BILLBOARDMODE_ALL also (back face is never visible)

 

Something I don't understand : I can't active freezeWorldMatrix else nothing is rendered

PS.emitter.freezeWorldMatrix();

The mesh isn't yet translated, rotated, or scaled. It is changed only in its local system, so its WorldMatrix should keep fixed.

Am I missing something ?

Link to comment
Share on other sites

mmhh.. the BILLBOARDMODEs have side effect if we choose big sized triangles... because this mode applies to the global mesh (not only on each face, I guess), so it can crop a part of the emitted particles

So I think the way to display particles  (billboarded x, y, z, all, none) will be a parameter in the final function... or maybe nothing at all since the underlying mesh is accessible, users will do whatever they want/need because there is no universal best option imho :

PS.emitter.billboardMode = BABYLON.Mesh.BILLBOARDMODE_ALL;

Well... if we have a mesh based particle system, so why not to use by ourselves then all the Mesh properties when they are needed ? nope ?

Thus the PS would be agnostic about user preferences or needs. Just a (weird) mesh.

Link to comment
Share on other sites

quick texture + alpha test : http://www.babylonjs-playground.com/#11VPQD#4

 

this is a mesh... so it can lookAt the cam position ! better than billboardmode : http://www.babylonjs-playground.com/#11VPQD#5

or not ... don't really know

 

 

[EDIT] gotcha : BILLBOARD or lookAt rotates the whole mesh for it to face the cam, so it looks like some particle are cropped... actually, they are still emitted in the rotated orientation

Link to comment
Share on other sites

Hey!

 

I've been following your discussions and found it really interesting. One thing that may help: have you looked into the SpriteManager class? Its principle is close to the particle system as it is only constituted of one big mesh with many quads, but these quads can be positioned manually by the user and their UV coordinates can be changed individually (through the use of cellIndex).

 

Good luck!

Link to comment
Share on other sites

After have read the Sprite code, and as far as I understand, it's quite similar to the current Particle code... except the way the sprites are rendered.

Well, as for the particles, the sprites don't rely on the classic local-world-view-screen transformation flow used for meshes.

However they seem to be z-sorted : https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Sprites/babylon.spriteManager.ts#L150

 

I guess a Sprite manager could be used as it is for rendering particles : we just need to implement an emitter (trajectory + recycler). So these sprite-based particles would have the same features than current sprites in terms of sorting and alpha-blending.

 

So... well ... I feel confused now in my approach ...

 

We have 3 levels from the most powerful (nb elements + speed) to the most accurate (sorting / alpha) :

 

<== +++ power  ---                                                                 --- accuracy +++ ==> 

   current Particle system     /  current Sprite system      /  current Mesh system 

 

 

As a particle or a sprite could be technically the same thing, we can yet use Particle or Sprite system to handle particles (just code an emitter)

So I believe I will go on investigating about the third way : a real mesh in the mesh flow with faces/subparts used as particles/sprites

Link to comment
Share on other sites

:)  You're just the coolest, Jerome!  And Jahow, good lead.  Yep, sprites have that same "vrooom" as particles, don't they?

 

I bet I know where Jerome is headed, soon.  Exploding mesh, one of the coolest 3D Max animat-able "modifiers" ever.

 

(The urge to blow-up things is almost a requirement for being a guy) .  :)

 

Think about the code.  erf.  Take your basic, simple mesh like a torus knot (not simple at all), and tell its vertexBuffer to "adjust" in a way that makes all of its faces... separated (like sprites and particles).  Then blast 'em with a hemisphere of physics engine applyImpulse (put plane imposters on each face), or put Jerome's cannonball-flying code on every face.  Wow!

 

Newbie:  "Hey Jerome, why are your triangles bouncing like cannonballs?"

 

Jerome:  "Nobody likes you, newbie."  :)

 

I guess they would be flown like particles, eh?   I guess it's all parabola, when push comes to shove.

(ar ar ar - push/shove... particle-flying terms) 

 

 

When I first saw the name "timeline.js", I thought we had a scene.timeline that we could "hang" all sorts of scene events and triggers onto.  That wasn't the case, but wouldn't that be interesting?  An actionManager with a deltaTimer. (koshs per hour?)  hehe 

 

onSceneTimelineTrigger(name, elapsedMillisecs, action, etc).  Explosion scheduler.  :)  FuseManager  heh

 

Hey Jerome... are you married?  Probably not anymore, eh?   Does she know that "the other woman" is 37,000 lines of code called BJS?  :)

Link to comment
Share on other sites

Well... we can hack BJS with no computer... in our head.

Today, I had 5 meters cube of stove wood to stack along my house wall for next winter. Quite a hard, physical, repetitive work to do a day long...

So my brain opened its internal editor and went on :P 

 

I guess I have now a computional lead to make the particles (quads or any planes) face the cam... with no global mesh rotation and only one global calculation done once (won't be efficient to compute an angle per particle !).

 

So my idea is now to provide to users an updatable mesh made of many similar geometric animatable basic parts (few vertices) : planes facing or not the cam (triangles, quads, or discs) or basic volumes (triangular pyramids or cubes).

This "mesh" (I really need a better name) will provide methods to define the part trajectories, to recycle them, to start the animation and to stop it.

And some methods to set different textures (or colors, need to investigate this topic) per parts

This could be used for accurate but not so numerous particles, idem for sprites or for any other animation (big parts explosion, etc ;) )

 

I hope I'm clear enough  :mellow:

 

So, people, I'm looking for a pertinent name for this "mesh" ... PartsAnimation ? (ugly)

Link to comment
Share on other sites

Funny!  Good to hear that you have good wood, now.  ;)

Let's see, triangle animatables would be...  umm...  trannies.  heh  (ahem)

Let's have a look at a basic ground (flat heightMap) and see what's what.  http://playground.babylonjs.com/#1TYVSP

If a guy wanted to "fly" every triangle, a guy might want to notice a few things about how these triangles interact with each other.

1.  The most upper-right, and most lower-left vertices... (2) will not be doubled (no vertex added).  Each of those two vertex... are used by ONE triangle face.

2.  The most upper-left, and most lower-right vertices... (2) will be doubled (another vertex added).  Each of those two vertex... are used for TWO triangle faces.

3.  All other BORDER vertices... (60) will need to be tripled (2 vertex added).  Each of those sixty vertices... are used by THREE triangle faces.

4.  ALL "internal" non-border vertices.. (225) will need to be sextupled (5 vertex added).  Each of those 225 vertices... are used by SIX triangle faces.

Wow, huh?  Trannies.   Tranny Blasting.  Or how about "Space Faces?"  Faces that can get launched into space, or that have SPACE around them. 

What?   Cutesy sucks?   *nod fine*  Ok, how about "facettes" ?  Too close to fascists?  (Aren't we all?).  ;)

hmmm.  I'll think-up some more... give me a few hours.  :)

Warning:  Kids, programmatically breaking-up heightMaps into constituent pieces, and then blasting them into the cosmos... should ONLY be done under adult supervision.  The LAST thing ANY of us want... is some youngster getting an eyeful of tranny.  :o

Link to comment
Share on other sites

textured (+alpha) quad particles done : http://www.babylonjs-playground.com/#UKYFP

 

300 particles here, sized 2, no more BILLBOARD (need to implement the system to face the cam)

60 fps (outside PG) on FF and Chrome here

 

 

stress test on chrome (particle size = 2) :

10000 particles => 60 fps

20000 particles => 43 fps

 

well, a bit less powerful than just triangles with no textures : http://www.html5gamedevs.com/topic/15088-is-one-particle-at-a-time-an-abuse-of-particle-system/?p=85791

 

 

 

I think about FragmentMesh for the name. Thoughts ?

Link to comment
Share on other sites

Fragment is the term used for pixels drawn on screen by a fragment shader, so I'd advise against that.

 

I think it's important to stop and think about the end user's perspective here. Jerome, what you did basically answers the question "I need a particle/sprite system where the 'quads' (ie sprites or particles) are indeed part of the scene and not drawn over it".

 

Now the fact is that BJS has been designed with its particle and sprite systems to be completely separate from the regular meshes of the scene. This goes deep into the render code and (as DK already pointed out IIRC) is not easy to change. Still, it wouldn't be right to just make a "new" particle system on top of the existing one for obvious reasons.

 

I think what would be interesting is providing the end user an alternative to these existing systems through the use of a mesh which is basically a collection of clones, merged together. This system may even support other kind of geometries, as long as every "particle" is always exactly the same (at least in geometry).

 

How about something like that:

var original_mesh = /* load existing mesh */var mesh = new DuplicateMesh("bla", scene);mesh.setCustomBaseMesh(original_mesh); /* this defines the shape of the mesh that will be duplicated */mesh.setBaseMeshAsQuad(); /* set the base mesh to be a quad (would be logical to be the default mesh) */mesh.addNewDuplicate( /* provide position, billboard info, uv offset... */ );mesh.removeDuplicate( /* provide a duplicate index */ );var data = mesh.getDuplicateData(index);   /* returns position etc. of current duplicate */mesh.setDuplicateData(index, data);

All this with a nice garbage collection in the background for duplicates (just like a particle system, recycling old particles), and a special shader to display all the duplicates based on the data provided.

 

Just a suggestion! :)

Link to comment
Share on other sites

I like this.

 

Heuu, I don't want to override the current hyper-powerful particle or sprite systems but as you said, just propose an updatable global mesh containing many similar (geometrically) animatable and recyclabe parts (what I suggested as "fragments").

So this will be for another usage : in scene parts/particles/quads/what_ever_you_want animation.

Far less powerful than current particle/sprite systems and far more accurate, in terms of z-sorting and alpha blending, with all features of a standard mesh 

 

Do you think it is would be useful to have the ability to use an existing mesh as a model for sub-parts ? Why not ? the performance would probably crumble really quickly with a model with many vertices and a collection of thousands of instances then.

Need to check... interesting idea however.

 

Initially I intended to provide only pre-computed basic geometries for subparts (we really need a name, grrr) : say, 3 types of planes (triangles for highest performance, quads for easy texturing and a pseudo-circle, maybe a hexagon) and 3 types of volumes (triangular pyramids -so only 4 vertices as for quads-, cubes and maybe pseudo-sphere).

Having pre-computed basic geometries for this elementary elements allow to highly optimize the number of vertices used and re-used, what is critical to have very numerous instances, and to set nice UVs for texturing (circles and spheres).

Moreover knowing the order of indices (how the faces are built) allow to reduce the iterations on vertices and eases the way to re-set variables in place, so to reduce garbage collection at its lowest. For now, this is what I did in these two (triangles and quads) algos : no new memory allocation once the render loop is run.

 

I really like the idea to use an existing mesh as a model for subparts.

 

Well... your suggestion is really exciting... arrg, this means the complexity of my implementation will just multiply by 3 :D 

 

So a step after the other if we want the things to be achieved. I will probably start with pre-computed shapes as planned 

Link to comment
Share on other sites

You're right, step after step! Having a functional system with simple quads would be a great start.

 

I've read a few times people asking for "mesh particles", so yeah I think it's a nice goal to have. Could be great for debris flying after an explosion, or detailed particles. Also, a thousand meshes displayed like this would be much more efficient that a thousand meshes generated with clone(), since for BJS there would be only one big mesh, which means no time spent in mesh selection.

 

As for the vertices/indices count on each mesh-particle, if it's not more than 50 or even 100 I think it should be alright. A vertex buffer can hold a lot of data :D It also depends on how much separate data is kept for each mesh-particle: color, angle, other... Anyway, in theory this system would work for meshes with over a thousand vertices, even though you wouldn't be able to duplicate it more than a few times.

 

A reminder: from my experience in BJS, it is the amount of separate meshes on screen much more than the amount of vertices that kills performance.

 

Anyway, I've already coded some similar stuff so I can definitely help you with this :)

Link to comment
Share on other sites

For performance, well, it's only one updatable mesh, so only one draw call  :) : that's the good new !

 

The real point is more the number of instances to iterate on..., CPU side.

The results are therefore pretty good with hundreds or two or three thousands of parts.

I don't know who really needs more than 10K visible parts at the same time in the screen (this would go over the screen pixel number !?!)

 

For now, I will start with some pre-computed planes (triangles and quads, almost done) and add the ability to make them always face the screen : billboard rotates the whole mesh so it doesn't fit. I need to orientate only parts... at least computational cost, so all parts together... but not forget to take in account an eventual global mesh rotation also, gloups

 

Then I will add a cube : a textured backfaceculled cube will ever show one face at least to the user, so no need for orientation

 

Then think about adding part rotations (far more calculations, because a rotation to compute per subpart )

 

Then only think about your suggestion ;) : use any mesh geometry as a model for subparts.

 

Thank you for the help proposal :) , you'll see PG soon, we can argue

Link to comment
Share on other sites

I put the camera in a better position :-)
   http://www.babylonjs-playground.com/#UKYFP#2

 

I also set backFaceCulling to false, so you can rotate around it. Curiously on my machine, using Firefox, the average FPS with backFaceCulling switched on might actually be lower (e.g. 45-55fps vs. 43-53ps; the numbers are very noisy). I wondered if this is a case where the cost of the optimization outweighs the cost of not doing it?   (It runs at 60fps either way in Chrome.)

Link to comment
Share on other sites

You should probably be able to do it on the GPU with a vertex shader. Also BJS sprites are billboarded and there is no heavy computation in the code, although I must admit I haven't completely figured that out yet.

 

I couldn't resist trying some things along what I was suggesting above: http://www.babylonjs-playground.com/#1OMHRR#10

200 spheres flying around and changing color along the way, 5700 vertices, 22000 indices.

 

That's not a lot and it gets laggy very quickly though... Maybe even simple spheres like that are already too complex to be duplicated many times in a single mesh.

Link to comment
Share on other sites

just got an idea for the ever screen facing rotations :

 

I will define quickly a system relative to the cam.position (mesh-cam axis + 2 cross vectors from world axis and this cam axis : multiplications only once per frame)

I will then report the local quad coordinates into this system : only additions, this is as fast as adding velocities per vertex

 

If the whole mesh is rotated, I will just unrotate the (fake)cam position by this mesh rotation value (only a un-rotation computation per frame), so my (fake)cam position will be as I hadn't rotated the local system... this means the light previous process (additions only) should still work.

 

Not sure I'm very clear to everyone.

 

I will test tomorrow.

Link to comment
Share on other sites

Wow guys, this stuff is great! I haven't really had a chance to dig into the internals but it looks terrific. The last piece of the puzzle is the camera-facing behavior. I assume that the default ParticleSystem solves this by drawing particles in screen space, but I guess this isn't an option here. But even if the solution was to calculate a single (billboarded) worldmatrix for the system, and then use that to transform each particle, I guess that still might be very fast for systems of ~1000 particles, if it uses the "single mesh" thing you have going.

 

Incidentally for names, I'd suggest MeshParticle, or perhaps SolidParticle. The only real difference between what you've got here and "real" particles is that they aren't alpha-blended, right? But these will be useful for essentially the same kinds of purposes that normal "particles" are useful, so I think it will be easiest for everyone to understand if they're called FooParticles (for some value of Foo).

Link to comment
Share on other sites

You're right : current particles (and sprites) are drawn in the screen space, that's why the camera-facing behavior is quite obvious there.

The difference between this prototype and real particle is more than just alpha-blending. This proto will be a real mesh, so it will have all the mesh class properties. The parts (particles) will have normals for example and will reflect light, etc.

 

I have a lead, that I will test today, to make all the particles rotate at once orthogonally to the camera-system axis : this would be only one calculation for the whole system, so all the particles should have the same orientation.

I don't know yet if it's valuable or if I really need to compute a rotation per particle. In this case, the dedicated worldMatrix would be a good option.

Let's test. :)

 

I'll ask Raanan for a repo in BJSX.

[EDIT] here : https://github.com/BabylonJSX/SolidParticleSystem

 

I like the name "SolidParticles" too.

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...