Designing a Particle System

Hello Everyone,
I wanted to start the discussion about how we should go about implementing a particle system for amethyst. I have been thinking about starting this project but I wanted to talk to the community about some of the possible methods of implementing the system. These are some of the features I want to support (eventually):

  • Customizable Rendering( Sprites/Meshes, Tints, Size)
  • Customizable Standard Physics ( Position, Velocity, Forces/Aceleration, Rotation, Angular Velocity)
  • Customizable Particle Properties( Emission rate, lifetime, emission position ( point, line, area),etc)
  • Changing Parameters based on other Parameters ( Size shrinks over time, Tint based of velocity, Sprite index based on angular Rotation)
  • Modifiers of the Parameters ( Random between constants, Curves,etc)
  • Emission space (Local or World)
  • Shaders ( lightning, noise textures, custom)
  • Looping and One shot modes
  • Pre-warming and off screen pausing
  • Max particle count / Memory usage

I am looking to get input on any features that I am missing here this is mostly based on unities features.

In order to achieve this I will suggest a few different implementations that could achieve this.

  • Emitters create new entities in the primary world with effects handled by systems:
    Pros: The particles are entities and can interacted with everything else in the world super easily
    Cons: can lead to major data fragmentation and could be very inefficient

  • Emitters contain a collection of all the particles the maintain with fixed functions to handle effects:
    Pros: fairly efficient and compact
    Cons: Fairly rigid in the functionality ( Some of the changing particle effects could be impossible)

  • Emitters emit into a shared sub_world with effects handled by systems:
    Pros: A lot of customization options for particles as systems can be added to the entire system, tags could also be used to differentiate between types
    Cons: A different world from the main would cause issue if you needed entities to interact with world objects( particles avoiding player,etc)

  • Emitters contain individual subs worlds with effects handled by systems:
    Pros: A lot of customization options for particles as systems can be added by the end user on a per emitter basis
    Cons: Individual sub-worlds could be memory intensive and systems would need to be run on each world causing some efficiency loss. Separate world would cause even more issues with interaction.

Please let me know if there are any other implementations I am missing.

Personally I am leaning towards a single sub world as I think it’s the best trade off between functionality and efficiency.

Rendering could be handled by a customizable render pass similar to Base_3d.

Please let me know your thoughts on this and if this is even the place to have this discussion ( discord seemed to informal and RFC seemed like over kill )

Thank you for you time.

5 Likes

I can’t provide any feedback on the technical side but it sounds very exciting!

Veloren have recently been working on a basic particle system. Maybe it can provide some inspiration.
Blog link.
Another blog link.

3 Likes

Thanks for the links. It showed me that handling some aspects in the shader ( compute or render) is a possibility I hadn’t thought of. It would be fairly fixed in functionality and some aspects would have to be handled elsewhere ( changing meshes for example).

I could see there being benefits for large particle counts but it being slowed by overhead on small particle counts.

In talking about this to @jojolepro who is currently doing most of the work towards the v0.16 (Legion) release, he proposed the following:

I’d encourage people to design and make schemas for future features and how they will be integrated in the engine + used by the user. I’d also ask what the user “api” would look like. But I would tell them to wait before starting the implementation.

4 Likes

And that basically is exactly my goal here, I want to establish an underlying structure/design then work towards an api/ux as it could be highly impacted by the core design.

My hope here is to figure out all of the details needed for implementation so development can start once v0.16 is ready. This module will only ever use legion.

4 Likes

As I write this, I want to make it clear that I fully understand that a lot of this can’t be perfectly applied to Amethyst. Especially given its DIY nature when it comes to many aspects such as collision detection. I also can’t speak much on the implementation side, but I am a heavy user of particle systems, so I just want to briefly go about how I personally use particles. I’ll try to omit features already listed in the OP.

Always use:

  • Vector Fields
  • Lighting as in particles emitting light, Particle Lights
  • Emission shapes / masks

Often use:

  • Particle collision, for particles that are visually expected to bounce off of other objects
  • Attractors, Expellers, Orbiters, as part of the system/emitter
  • Ribbons / Trails

Have used at least once:

  • Events for particles (collision, spawn, destruction, …)
  • Killer objects, destroys particles when they fit its criteria/specifications (e.g. Spark hits Water)
  • Particle LOD

I probably forgot a lot of it, as it has been a while since I last worked with VFX, but I’ll make sure to come back and add whatever I may have missed.

3 Likes

Thank you.

I really like hearing about these kind of use cases.

I am am thinking of designing the particle system as a pipeline of sorts. The stages would be:

  1. Particle creation

  2. Motion/Update

  3. Deletion check

  4. Deletion Handler

The idea is that each step would have default/prebuilt stages but all would be customizable, Standard effects like line/area emitters, particle physics, vector fields, particle lifetimes, etc could be prebuild.

If the particles system uses separate worlds them there would need to be a way to pass data back and worth between the them or at least for the main world to iterate over the particles.

I believe everything that you described would be possible but I am unsure about how the lightning system works.

1 Like

Not sure what you meant by that, if you are unsure about Amethyst’s lighting system or about what I meant by it. So just to illustrate in case it’s the second, here’s the Unreal (arbitrarily chosen by search engine) docs for what I meant by Particle Lights.

https://docs.unrealengine.com/en-US/Engine/Rendering/ParticleSystems/ParticleLights/index.html

By my understanding of this, using separate worlds means we would need a tight sync between them, or 100% independence. Independent seems harder, the emitters (I assume) would be in the main world, parented to possibly mobile entities, making it hard to work with local coords.

If there was a way to actually affect said separate world, and maybe add entities to it, even if on a limited manner, it would be possible for us to create an object in the main world and add a particle collider in the particle world, keep both in sync somehow and done. Not sure how I would go about it, if one would explicitly add an entity there or simply add the entity to the main world, with a VectorFieldComponent, and it would automagically be used in the particle world… heck, I don’t even know how to properly use states yet.

I had meant that I don’t understand how lightning in amethyst works. I haven’t done much work in 3d in amethyst.

The more I think about everything, the more I am seeing that methods of coupling between worlds are definitely required.

Obviously if the particles are created in the main world , then its super easy to perform effects on them.

If they are owned by the emitter then it would be possible to get a iterator over all the particles in the main world by fetching the emitter. that way standard effects can still be handled by the particle systems but everything is accessible if you need tight coupling.

I am going to do some more research.

2 Likes