GpuParticles sample

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
Post Reply
przemir
Halfling
Posts: 52
Joined: Sun May 11, 2014 7:55 pm
Location: Poland
x 14

GpuParticles sample

Post by przemir »

Hi! Last year I created gpu particle system for Ogre 2.3. I though that I will improve it before sharing but time passed and nothing really changed :roll:, so I decided to share it like it is now (only Direct3D shaders are right now). I only removed dependencies to my project, cleaned this a bit and fixed a bug. And wrapped this into sample, similarly to 'Terra' tutorial.

https://github.com/przemir/Ogre_Sample_GpuParticles

Image
Image

And thanks for help when I was making this particle system:
viewtopic.php?p=550810
viewtopic.php?p=550732
viewtopic.php?p=550635

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5012
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1179
Contact:

Re: GpuParticles sample

Post by dark_sylinc »

Hi!

Thanks! It looks quite polished!

Are you interested in this sample getting integrated into main OgreNext?
"How to make your own GPU particle system" gets asked a lot, so it would be nice to have this.

I'm not sure if this should be a sample (i.e. to show how it's done, no strings attached) or as a Component/Plugin.

It feels a bit too complex to just be a sample, but I'm not sure if it's polished enough to be a Component/Plugin. I haven't been able to run it yet on Linux so I haven't ran the sample yet.

I managed to compile it after a few fixed, and now I have to port the HLSL shaders to GLSL.

But before I continue I need to see if you accept and what your thoughts are.

przemir
Halfling
Posts: 52
Joined: Sun May 11, 2014 7:55 pm
Location: Poland
x 14

Re: GpuParticles sample

Post by przemir »

dark_sylinc wrote: Mon Nov 14, 2022 5:59 pm

Thanks! It looks quite polished!

Thanks!

dark_sylinc wrote: Mon Nov 14, 2022 5:59 pm

Are you interested in this sample getting integrated into main OgreNext?
"How to make your own GPU particle system" gets asked a lot, so it would be nice to have this.

Yes, I am. I also asked this question "How to make your own GPU particle system" before so I know how it is.

dark_sylinc wrote: Mon Nov 14, 2022 5:59 pm

I'm not sure if this should be a sample (i.e. to show how it's done, no strings attached) or as a Component/Plugin.

It feels a bit too complex to just be a sample, but I'm not sure if it's polished enough to be a Component/Plugin. I haven't been able to run it yet on Linux so I haven't ran the sample yet.

I though of this particle system to be similar to "Terra":

Code: Select all

        "The Terrain system is called 'Terra' and has been isolated under the Terra folder like\n"
        "a component for easier copy-pasting into your own projects.\n\n"
        "Because every project has its own needs regarding terrain rendering, we're not providing\n"
        "Terra as an official Component, but rather as a tutorial; where users can copy paste our\n"
        "implementation and use it as is, or make their own tweaks or enhancements.\n\n"  

I think it is similar here with this particle system. I wrote things that fit my needs:
I prepared system to be able do display fire particles - therefore atlas/flipbook handling multiple sprites in HlmsParticleDatablock.cpp and HlmsJsonParticleAtlas.cpp.
I wanted sparks for sword clash - therefore passing Ogre::v1::BillboardType and handling it inside fragment shader and depth texture collisions.
But there are much more possibilities people may want like mesh as emitter, non standard affectors (particle system right now does not handle affectors, just handle update job). Right now I think it is still not ready yet to be an official Component. It lacks this customization features (although perhaps it can be solved by adding listeners/subclass virtual methods which would allow to pass additional data to emitters, particles etc.).

Few thoughs:

  • There is no serialization right now: for my project I have my own data format, so I didn't implement it. I though of implementing json for this sample, but didn't finished it yet. But maybe script format similar to the one used in Ogre::ParticleSystem would be better (although it has hardcoded token ids (I mean this big enum from OgreScriptCompiler.h)).

  • There is thing concerning suboptimal memory consumption: As particles are grouped in buckets (64 particles per bucket), each started emitter will "allocate" (assign) one more bucket that is needed (so for example if there are max 60 particles at the same time for emitter instance, place for 128 will be allocated instead of 64. If emitter needs more than one buckets, this additional one won't hit as much). Thanks to that additional space it was easier for me to write shaders. But it is unoptimal for memory and I think it can be fixed. I guess I will have to look at this someday and fix it.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5012
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1179
Contact:

Re: GpuParticles sample

Post by dark_sylinc »

przemir wrote: Mon Nov 14, 2022 11:27 pm

I think it is similar here with this particle system. I wrote things that fit my needs:

OK understandable. So for the time being I'll see of making it a sample.

We'll see how it evolves.

przemir wrote: Mon Nov 14, 2022 11:27 pm

It lacks this customization features (although perhaps it can be solved by adding listeners/subclass virtual methods which would allow to pass additional data to emitters, particles etc.).

Customization in GPU particles is always hard because GPGPU doesn't like heterogeneous stuff.

Basic affectors like gravity, scalers and linear velocity are always easy to implement; but the more complex it gets; the harder it gets to make it GPU-driven. Particle Universe gives beautiful flexibility, but that kind of flexibility is very hard to implement via GPGPU.

GPU particles are best for particles that you need A LOT (like sparksm, explosions, magic effects) regardless of their customization (i.e. quantity over quality).

While CPU particles are better suited for event/script-driven effects

przemir wrote: Mon Nov 14, 2022 11:27 pm
  • There is no serialization right now: for my project I have my own data format, so I didn't implement it. I though of implementing json for this sample, but didn't finished it yet. But maybe script format similar to the one used in Ogre::ParticleSystem would be better (although it has hardcoded token ids (I mean this big enum from OgreScriptCompiler.h)).

Gotcha.

Btw speaking of serialization; libclang can automate a lot of stuff. For example we use a Python script to implement datablock cloning.

It parses the header classes and automatically generates the routine.

I have a C++ version using libclang that looks at the code's comment to spit out extra code (i.e. with libclang you can look at comments for metadata about what you want to de/serialize).

przemir
Halfling
Posts: 52
Joined: Sun May 11, 2014 7:55 pm
Location: Poland
x 14

Re: GpuParticles sample

Post by przemir »

Should I add issue/PR on github?

Given that ParticleSystemWorld is complex class, perhaps adding listener in constructor would simplify adding additional data for emitter (which are uploaded only when registered) and particles (which have data only in shaders and needs only structure size during allocation). This would behave like HlmsListener.

przemir wrote: Mon Nov 14, 2022 11:27 pm
  • There is thing concerning suboptimal memory consumption: As particles are grouped in buckets (64 particles per bucket), each started emitter will "allocate" (assign) one more bucket that is needed (so for example if there are max 60 particles at the same time for emitter instance, place for 128 will be allocated instead of 64. If emitter needs more than one buckets, this additional one won't hit as much). Thanks to that additional space it was easier for me to write shaders. But it is unoptimal for memory and I think it can be fixed. I guess I will have to look at this someday and fix it.

I have seen this additional bucket of particles and it was due to creating particles. For static emitter (emitter which is not attached to scene node and therefore, does not change position and orientation) whole bucket of particles is created ahead of time, so it needs additional space.

On the other hand for dynamic emitters it create only particles up to date so it may create even 1 particle and other 63 (remaining threads per group) will be skipped in compute shader - for each emitter instance.
Perhaps dispatching to CreateParticle job should be different therefore? Would it be more efficient to provide list of particle ids to create? Or make multiple jobs like create 64 particles starting from given id of first particle, then create 32 particles (using all threads per group so particles from two different emitters may end up there), then 16, 8, 4, 2 and finally per 1 (handling all remaining particles to create)?

Edit Alternatively during create job calculate particle pos using local transform matrix (position and orientation offset) and during first update (when particle lifetime == 0 and elepased_time > 0) apply emitter instance transform matrix. Then particles could be created ahead of time for every emitter, not only static one. But then this additional bucket of particles will be used and cannot be removed for memory efficiency.

Post Reply