Trial includes a high performance particle simulation system that performs almost all of the work on the GPU, allowing you to create particles with hundreds of thousands of particles (if needed).
NOTE: This section refers to particles used for visual effects. For particles as used in physics simulations (Verlet, etc) see Mass Aggregate Physics.
NOTE: This system requires OpenGL 4.2 or later. Most of the engine is built around OpenGL 3.3, but that would proclude using Compute Shaders, which are required for this approach. In order to use these particle systems, make sure to construct your context with
:version '(4 2). If you want to run particles on OpenGL 3.3 see the section below.
In order to create a particle system, simply create a
gpu-particle-emitter and enter it into a scene. You can then use
emit to burst particles on demand, or set the
particle-rate to create a continuous stream of particles.
NOTE: In order for the system to work correctly you need a standard renderer derived renderer in your scene such as the
pbr-render-pass. The particles aren't actually shaded by the renderer, but they require the environment information that the pass also takes care of providing.
Particles have a variety of attributes that can be set either with the
:particle-options initarg on the construction of the emitter, or using accessors:
The size of the particle when it is created (affected by
The scaling factor of the particle over its lifetime.
The rotation factor of the particle over its lifetime (affected by
The multiplicative color mask of the particle. This must be a
The randomness factor. If 0 all particles will receive the same properties. This randomness also applies to the distribution of the origin of each particle over the emitter's surface.
The initial velocity of a particle when it is created (affected by
The default lifespan of a particle in seconds.
The randomness factor applied to the particle's lifespan. This is separate from the other randomness factor.
Can be either
:quad. In the former case the sprite always faces the camera, whereas in the latter case it uses the emitter's model matrix and behaves as a normal quad otherwise. Please note that this also means that already emitted particles in quad mode will be influenced by changes to the emitter's transform.
Can be either
NIL(default) for no flipping,
:xfor horizontal flipping,
:yfor vertical flipping, or
Tfor both. Whether the particle's texture is flipped or not is randomised subject to this flip option.
The texture used for each particle's quad. Note that this is applied for every particle and a change also applies to already emitted particles.
Besides the per-particle properties, the emitter itself also has a number of useful properties:
This sets the surface across which particles are emitted. By default this is a unit square.
NOTE: It must be a triangle mesh with position and normals and it must have an index buffer.
The location of the particle emitter surface. Changing this will only affect particles that are emitted in the future (unless in
:quadmode, see above).
The orientation of the particle emitter surface. Changing this will only affect particles that are emitted in the future (unless in
:quadmode, see above).
The scaling of the particle emitter surface. Changing this will only affect particles that are emitted in the future (unless in
:quadmode, see above).
The rate in particles per second that are emitted from this emitter.
How many particles to emit on next tick. You should probably use the
If set to non-zero, particle quads will be stretched along their motion vector to simulate motion blur. Note that this will not actually interpolate positions, but may lend the illusion of motion blur due to the stretching of the texture.
The number of local work group threads run on the GPU.
NOTE: Setting this to too high a value may signal an error in development mode if the hardware does not support it. In release mode Trial will simply truncate the setting to the maximum allowed value. OpenGL only guarantees a value of up to 1024.
The maximum number of particles the emitter can display. This cannot be changed once the emitter has been created. Trying to create more particles than this will simply "drop" them. In order to set this you must pass it as an initarg.
NOTE: There is a system maximum of particles that can be supported by the hardware. If
max-particlesis set higher than can be supported by
local-threadsand the underlying hardware, an error is signalled in development mode. In release mode Trial will simply truncate the setting to the maximum allowed value.
Due to the high flexibility afforded by the emitter, you can probably re-use the same emitter to spawn particles in multiple places. To do so, simply use the
emit function, which also allows you to conveniently place the emitter.
One of the factors that makes particles so fast is that they typically don't interact with the environment. However, it can still be useful to be able to make the particles be affected by various forces, whether to simulate gravity, wind, or other interactions.
To do so you can set the
particle-force-fields on the emitter. This can either be a
shader-storage-buffer backing a
particle-force-fields structure, in which case the force fields can be shared between multiple emitters, or simply a list of force field descriptions to update the existing buffer. Each field should be a plist with the following attributes:
The type of field that is defined. Can be one of:
Has no effect.
A point field, with the strength being linear to the distance within its spherical range.
A directional field, exerting a constant force in its direction everywhere.
A planar field, with the force in the direction of the plane and the strength being linear to the distance within its spherical range.
A vortex field, applying a tangential force along its normal, proportional to the distance from its centre normal.
A field that simulates a smooth sphere. Particles that go within its spherical range are rebounded and receive a tangential force to cause them to "slip" off.
A gravitational field with infinite extent. If the range is positive, particles that would go within the spherical range receive a sphere force instead.
The world-space position of the field.
The "strength" of the field's force.
The world-space range of the field if it has an extent.
The world-space normal vector if the field has a directionality.
If you would like your particles to bounce off of geometry, you can use a
depth-colliding-particle-emitter and connect it to the render pass like so:
(connect my-standard-render-pass my-emitter-instance scene)
Note that the bounce is determined directly from the depth buffer and not from real geometry, and as such anything that isn't visible from the camera's point of view will not cause the particles to bounce as expected.
By default the emitter uses additive blending, which is a lot cheaper to simulate, as particles can be rendered in any order. If you require standard alpha blending for your particles, then you should use the
sorted-particle-emitter instead, which runs a bitonic sort after simulation to ensure that all particles are drawn back to front.
The default emitter only allows using a single texture per particle. Sometimes it can be useful to vary the texture a little between particles. To do so you can use the
texture must be a
texture-2d-array. You can then use this particle option to configure the sprite selection:
The sprite index to be used. This is useful if multiple textures are attached and the displayed sprite should be a specific one. You may use up to 15 different sprites, or
:randomif it should be shuffled.
On systems with restricted GPU capabilities (GL 3.3) or for particle systems with a very small number of particles it can be more useful to simulate on the CPU instead of the GPU. In this case you can use the
cpu-particle-emitter. The interface of the emitter is the same as for the
gpu-particle-emitter, though it has one crucial difference: particles in both quad render modes can be spawned at different places and still work fine. This means that you can spawn particles from different locations and directions with the same emitter without the simulation going awry.