Over the last month I’ve been working on developing a completely new particle system backend that uses the GPU to perform particle simulation. This system allows for massive amounts of particles to be simulated at once (tens or hundreds of thousands), allowing for some very interesting effects.
The initial version of this system is available right now on the master branch! To enable GPU simulation, just enable
ParticleSystemSettings::gpuSimulation on the same
CParticleSystem component you would use for normal CPU particle simulation.
HParticleSystem = ...; ParticleSystemSettings psSettings; psSettings.gpuSimulation = true; particleSystem->setSettings(psSettings);
The GPU simulation supports all existing emitter types and options, but it does not support evolvers you would use for CPU simulation. You instead control the simulation through
ParticleGpuSimulationSettings object which offers a fixed set of options you can use to customize the particle behaviour.
ParticleGpuSimulationSettings gpuSimSettings; /// ... enable some options particleSystem->setGpuSimulationSettings(gpuSimSettings);
The current system is in early stages and only supports some of the basic emitter properties and a vector field simulation.
Vector fields represent a three dimensional grid of vectors which can be exported from applications like Vectoraygen or Maya Fluids. This grid of vectors can then be used to apply velocities or forces as particles pass through the grid, often resulting in fluid-like behaviour.
I’ve added support for vector fields imported from the
.fga format. Vector fields are represented with the
VectorField resource and can be imported into the framework as any other resource.
HVectorField vectorField = gImporter().import<VectorField>("MyVectorField.fga")
Vector field simulation
To enable GPU simulation using vector fields, simply assign the imported resource to
ParticleGpuSimulationSettings::vectorField and set other relevant properties like intensity, rotation rate and others.
ParticleGpuSimulationSettings gpuSimSettings; gpuSimSettings.vectorField.vectorField = vectorField; gpuSimSettings.vectorField.intensity = 3.0f; gpuSimSettings.vectorField.tightness = 0.0f; particleSystem->setGpuSimulationSettings(gpuSimSettings);
The gif in the header of this post was created by using a GPU simulated vector field. Vector fields are very flexible and by creating your own a huge variety of effects can be created.
Aside from the GPU particle simulation, these minor improvements were also added in the last month:
- Low-level rendering API now allows index & vertex buffers to be populated by compute shaders. This ensures GPU generated geometry can be rendered without requiring an expensive CPU readback.
- Plain type serialization and core object syncing have been added helper code that allows them to specify serializable fields just once instead of three times (read, write, calculate size), reducing the amount of boilerplate code significantly in those cases.
- Added a
Bitfieldcontainer utility class
Editor & scripting runtime
I’ve also been improving the editor and the scripting runtime:
- Resources used in scripts are no longer referenced directly, but instead use a
RRefwrapper type by default. This was a major refactor but allows some really cool features. Resources can now be referenced without having to be loaded, adding a lot of flexibility to the user on when and how to load a part of a scene (i.e. stuff can be loaded-in partially). You can also use those references to retrieve resources from non-standard locations (e.g. by fetching them from a network).
- More work on getting a generic curve editor window and color gradient window functional, in order to start integrating the particle system in the editor.
I’m hoping to release the next stable version of the editor by the end of the year.
I need to keep improving the GPU particle simulation. It was a bit of a rush to build the whole foundation for the system in just a month, and there’s still a lot more left to do:
- Support all basic particle emitter properties (like size/color)
- Add more GPU simulated effects like point attractors and generic forces
- Add screen-space depth buffer based collisions
- Particle sorting (back to front for materials that require it)
And there are things left to do for the CPU particle system as well:
- More evolver types
- 3D particle rendering
- Emitter bursts
- Soft particle rendering
With the GPU simulation done that’s a lot of the hard work out of the way. Majority of the left-over tasks are minor and I will probably start spending my time on some of the other new features planned for v1.1 which are: decals, emissive materials and a bloom effect. But possibly more on those in the next update!
Finally, huge thanks to my patrons for supporting the development! If you aren’t one already please consider becoming one - even the smallest amounts can help me out invest more time in the project.
Until next time!