{{tag>particle graphic physics collision}}
[[:start|Start Page]] >> [[:gamedev|Game Development with the Drag[en]gine]] >> **Particle Emitters**
Particle emitters allow to create particles in the game world influenced by physics. Physical behavior is not mandatory but the default behavior. Particle systems are split into two individual components to simplify the process of defining and using particles. Particle emitters are defined once and are then reused multiple times using instances. Emitters support both continuous and burst like emission of particles. For fine grained control over the properties of generated particles controllers are used. These work similar to controllers in [[gamedev:animators|animators]]. Furthermore emitters support collision emitters to simplify creating cascaded emitters like rain drops hitting the floor bursting into smaller drops upon impact. Emitters can also be set to self-destroy after the last particle has died. This allows to use particles in a deploy-and-forget manner.
====== Emitters ======
Emitters contain the definition of a single particle system. Emitters are non-resource objects hence they are not loaded from a file but build at run-time. This allows the user to use his own way of storing particle systems. An emitter should not be changed after it has been initialized and is in use by instances. Emitters can emit particles either continuously or in bursts. The default behavior is to emit particle continuously. In this mode the interval parameter is used to determine the time until the next particle is emitted. The number of particle emitted each time the interval elapses is defined using the particle count parameter. In burst mode particles are emitted once only. In burst mode the particle count parameter is also evaluated over the burst lifetime of the emitter. This lifetime defines the length of a burst. Using the progress curve of the particle parameter multiple emissions of particles can be defined along the burst lifetime. Thus it is possible to fine tune the emission behavior of particles in a burst if required. More information about this can be found in the particle count parameter section. The layer mask and group number are set to each instance the emitter is assigned to. This is required for cascaded emitters since the game code does not have access to the created instances. You can still though change the layer mask and group number in instances you have access to after you set an emitter.
^Name^Description^Type^Default^
|Emit Burst|Determines if particles are emitted continuously or in bursts|Boolean|False|
|Burst Lifetime|The life time in seconds of the emitter if using burst mode|Float|1.0|
|Layer Mask|Collision mask.|LayerMask|(empty)|
|Group Number|Collision group number|Int|0|
|Controllers|Controller definitions.|ParticleEmitterController[]| |
|Types|Particle type definitions.|ParticleEmitterType[]| |
|GraphicModuleSimulates|Determines if the Graphic Module simulates the particle system or the Physics Module. This is an internal value that only the Graphic Module has to set. Only the Physics Module and the game engine itself use this value.|Boolean|False|
====== Instances ======
Particle emitters can only emit particles if placed in the world using instances. Instances have a position and orientation in the world and are allowed to move while emitting particles. Particles are emitted along the Z-axis of the instance coordinate frame at the instance position. Particles move independently from the instance once emitted. Particles are emitted as long as Emitter is not null and **Enable Casting** is True. If Emitter has **Emit Burst** set to true particles are burst-emitted only once. To start another burst of particles call the **ResetBurst** method. Particles emitted up to this point are kept and a new burst cycle started. The old burst cycled is stopped. If **Remove After Last Particle Died** is set to True the instance removes itself from the world if the last particle died. If Emitter has **Emit Burst** set to True the **Burst Lifetime** has to have elapsed too in addition to the last particle rule for the instance to be removed. This way you can defined a burst which has a gap in between where no particles exists without the instance incorrectly being removed. The **Layer Mask** and **Group Number** are used to define which objects the particles collide with.
^Name^Description^Type^Default^
|Emitter|Emitter to use for emitting particles.|ParticleEmitter|null|
|Position|Position of the particle emission.|DVector|(0.0, 0.0, 0.0)|
|Orientation|Orientation of the particle emission.|Quaternion|(0.0, 0.0, 0.0, 1.0)|
|Enable Casting|Determines if particles are emitted or not.|Boolean|False|
|Remove After Last Particle Died|Determines if the instance removes itself from the world after the last particle died.|Boolean|False|
|Layer Mask|Collision mask.|LayerMask|(empty)|
|Group Number|Collision group number|Int|0|
|Controllers|Controllers used to modify particle parameter.|ParticleEmitterController[]| |
====== Controllers ======
Controllers provide a simple way to modify the parameters of particles. Controllers define a value range inside which the value of the controller is located at all times. The lower and upper boundaries can be chosen arbitrarily by the user. While used for evaluating parameter curves the controller value is mapped linear to the range from 0 (lower) to 1 (upper) inclusive. The user is thus not required to deal with value conversion from his game to particle emitter curves. Controller values can be clamped or non-clamped. If clamped values below lower are clamped to lower and values above upper to upper. If non-clamped values below lower or above upper are wrapped around the other end into the valid range. Imagine incrementing/decrementing controller values gradually until they spill over the lower/upper value. Doing so they wrap around. This is typically used for controllers intended to be updated with elapsed time. Most of the time though controllers are used to define a value between a lower and upper value thus by default controllers are set to be clamped. Frozen can be used to prevent a controller from changing values. This way setting or incrementing/decrementing the controller value does not alter it. Frozen is ignored if the lower or upper value is changed and the value is no more located inside the boundaries. In this case the value is always adjusted to be located again inside the valid value range.
Controllers exist in both the emitter and the instances. Upon assigning an emitter to an instance the controllers of the emitter are copied to the instance. The user can thus modify the controller on the instance no matter what the same controller in the emitter looked like. In general you only want to change the value, clamp and frozen state in a controller in an instance. Changes to controllers in emitters do not reflect back to instances using this emitter. Only with newly created instances the changes will show.
^Name^Description^Type^Default^
|Lower|Minimum value the controller value can be|Float|0.0|
|Upper|Maximum value the controller value can be|Float|1.0|
|Value|Value of the controller located always inside the lower/upper boundaries.|Float|0.0|
|Clamp|Determines if the controller value is clamped to the lower/upper boundaries or if the value wraps around if exceeding beyond any of the boundaries.|Boolean|True|
|Frozen|Determines if the value of the controller is prevented from changing except while changing the lower/upper boundaries.|Boolean|False|
====== Types ======
Emitters can emit more than one type of particles. This is useful to create complex particle systems with particles having different parameters while allowing to use the same controllers. You can always split an emitter creating a new emitter for each type. The advantage though of using multiple types in one emitter is that you can use the same controllers for various types (and thus having to set them only once) as well as not having to deal with multiple emitters in your game. Types are fully independent of each other except using the same controllers.
Particles in types are drawn using billboards. A skin object has to be set which defines the texture to use for these billboards. The first texture in the skin object is used. The billboards are scaled using the size parameter. The Physics Size property is used only for physics and is not required to match the drawn size of the particle. In general the Physics Size is less than half the size of the real size and does not change. The color, transparency and emissivity of the billboard texture can be altered using the red, green, blue, transparency and emissivity parameter. The texture properties are multiplied with these parameter values.
Particles are emitted relative to the coordinate frame of the instance which produces them. They are emitted at the origin along the Z-Axis. The **cast angle x** and **cast angle y** parameter defines the deviation from this direction. In addition a model can be defined which then is used to emit particles from. The **Cast From** parameter defines where from the model particles are emitted from. If **Vertex** is chosen particles are emitted from the vertices of the model along the vertex normals. Vertices are picked randomly. Vertex normals are not the normals defined in the model but the surface normals. If **Face** is chosen particles are cast from the faces of the model along interpolated vertex normals. Faces are chosen randomly as well as the position inside the face area. Particles are thus emitted randomly all across the entire surface defined by all faces. If **Volume** is chosen particles are cast from inside the model volume. Their normal in this case is the same as without a model as no unique normal can be defined for a point inside the model volume. If a skin is defined for the model this can be used to alter particle properties depending on where on the mode it has been emitted.
Particles collide with objects using the **Layer Mask** and **Group Number** of the parent instance. The **Collision Response** parameter defines the reaction of particles to collisions. If **Destroy** is set particles are destroy upon collision. If **Physical** is chosen particles bounce of the surface they hit using physical simulation. The **elasticity** and **roughness** parameter governs this behavior. If **Custom** is chosen the game scripts are used to determine what to do. This works similar to the callback in [[gamedev:colliders|colliders]]. Additionally upon impact new child instances can be produced. This allows to create cascading particle effects. Care has to be taken to not produce loops or producing too many particles. An emitter can be specified using **Collision Emitter**. To avoid creating too many particles in the case of **Physical** for **Collision Response** the impulse of the impact is used to limit the cases where instances are produced. Only if the impulse of the impacting particle exceeds Emit Min Impulse an instance is created. This value should be kept large to produce only instances upon heavy impacts. Once created particle parameters can be transfered to the controllers of the created instance. This allows to influence the child particles using impact properties. You can set a controller index for the lifetime, mass, linear and angular velocity of the impacting particle. If the controller is set to a valid controller in the created child instance the given particle property is set as the controller value.
Trails can be added to all particles of a type using the **Trail Emitter** parameter. The set emitter should be a continuous emitting particle emitter. Upon emitting a particle an instance of this emitter is created and attached to the particle in reverse. Hence the orientation of the instance is opposite direction than the one the particle is traveling. As soon as the particle dies the trail instance is set to remove itself one the last particle died. You can set a controller index for the lifetime, mass, linear and angular velocity of the trail emitter. If the controller is set to a valid controller in the created child instance the given particle property is set as the controller value. Trail emitters and collision emitters can be used together if required. Here too make sure to not create too many particles.
If the particle is moving at different velocities the density of the trail emitter varies. You can create a trail emitting the right amount of particles depending on the velocity using the **Trail Controllers**. Simply create a trail emitter with a single controller and set in the **Trail Controller** for **linear velocity** to the index of this controller (0 in this example). The value of the trail controller is now always set to the linear velocity of the particle it is attached to. Now use this controller on the **interval** parameter and you can control precisely the density of your trail or any other parameter as you see fit. The required interval can be easily calculated using overlap*(size/velocity). **Value** of the parameter acts as the overlap value which makes it easy to adjust the overall density. Calculate a bunch of values for different velocities inside the controller range and you have a basic curve keeping density equal.
Types can have different simulation types. Using **particle** as **Simulation Type** simulates particles the default way. Using **ribbon** all generated particles are connected using a ribbon in the order they have been cast. Use [[gamedev:skinproperties|Skin Texture Properties]] to alter how the rendering is done. In general there is a strict separation between properties affecting rendering only and properties affecting also the physics part of particles. Later ones only are stored in the emitter types. Last simulation type is **beam** which renders a beam for each particle between the cast position and the final position which is the particle simulated over the entire lifetime.
Using **Interval As Time** the usage of the **interval** parameter can be modified. By default the interval is used over time. Hence if the interval parameter for example resolves to 0.1 then a particle would be cast after 0.1 seconds. If **Interval As Time** is set to true though the usage changes to over distance instead of time. Hence with an interval value of 0.1 a particle would be cast after the emitter instance displaced by 0.1 meters from the last time a particle has been cast. This can be used for trail particles to have better control as well as for ribbons in connection with dynamically moving emitter instances.
^Name^Description^Type^Default^
|Skin|Skin object to use as texture for the particles. The first defined texture in the Skin is used.|Skin|null|
|Model|Model to use as the source position where particles are emitted from.|Model|null|
|Model Skin|Skin for the model to use. Allows to alter emission parameters depending on where a particle is emitted.|Skin|null|
|Cast From|Determines from what element of the Model (if set) particles are emitted from.|{Vertex, Face, Volume}|Vertex|
|Simulation Type|How to simulate the particle emitter. Also defines how it is rendered.|{Particle, Ribbon, Beam}|Particle|
|Interval As Distance|Determines if the interval parameter is used over time (seconds) or over distance (meters).|boolean|False|
|Trail Emitter|Emitter to use as the trail for particles.|ParticleEmitter|null|
|Trail Controllers|Defines which controller (if any) in the trail emitter instance is set with particle parameters.|Int[]|-1|
|Physics Size|Size in meters of the particle sphere used during physics.|Float|0.1|
|Collision Response|Determines how particles react to collisions.|{Destroy, Physical, Custom}|Physical|
|Collision Emitter|Emitter to use to create instance for collisions.|ParticleEmitter|null|
|Emit Min Impulse|Minimum impact impulse in kg*m/s required for particles to create a new instance.|Float|0.01|
|Emit Controllers|Defines which controller (if any) in created collision instances are set with particle parameters.|Int[]|-1|
|Parameters|Parameters defining particle properties.|ParticleEmitterParameter[]| |
|Max Linear Velocity|Used by the Physics Module to tell the Graphic Module the mapping range for linear velocities.|Float|1.0|
|Max Angular Velocity|Used by the Physics Module to tell the Graphic Module the mapping range for angular velocities.|Float|1.0|
|Squared Velocities|Used by the Physics Module to tell the Graphic Module if velocities are stored squared.|Boolean|False|
====== Internal Handling ======
Particle systems affect both the Graphic Module and the Physics Module. This requires coordination between these modules. Information about this can be found in the [[gamedev:particleemitters:modulecoordination|Module Coordination]].
====== Parameters ======
Parameters define for each particle parameter the emission value as well as how this value changes over the course of the particle life. Each parameter is calculated using the following formula:
ParamValue = Value OR CurveValue( ControllerValue )
ParamSpread = Spread OR CurveSpread( ControllerSpread )
EmitValue = ParamValue + ParamSpread * 0.5 * random()
RenderValue = EmitValue * CurveProgress( particle.lifetime )
This looks complex but is quite simple. Upon emitting a particle a random value between (**Value** - **Spread**/2)-(**Value** + **Spread**/2) is chosen whereas the value for **Value** and **Spread** are either the static values or sampled from **CurveValue** or **CurveSpread** depending if they have curve points and if **ControllerValue** or **ControllerSpread** points to a valid controller. During each update step this **EmitValue** is then multiplied by **Curve Progress** sampled over the particle lifetime. If there are no curve points in **Curve Progress** then 1 is used as the multiplication factor. Using controllers thus the user can influence the **Value** and **Spread** of individual particle parameters. See the listing of particle parameters for more information.
Curves are 2 dimensions bezier curves hence each point composes of 3 Vector2 values (point, left handle, right handle). Points are required to be sorted which the **CurveBezier** class takes care of.
^Name^Description^Type^Default^
|Value|Value to use while emitting a particle.|Float||
|Spread|Spread above and beyond Value the particle parameter. Randomly chosen for each emitted particle.|Float|0|
|Controller Value|Index of the controller to sample the Curve Value with.|Int|-1|
|Controller Spread|Index of the controller to sample the Curve Spread with.|Int|-1|
|Curve Value|Curve used to multiply Value with sampled using Controller Value.|CurveBezier|{empty}|
|Curve Spread|Curve used to multiply Spread with sampled using Controller Spread.|CurveBezier|{empty}|
|Curve Progress|Curve used to multiply particle parameter with sampled using particle lifetime.|CurveBezier|{empty}|
===== Time To Live =====
Defines the lifetime in seconds of particles. For continuous emission of particles the Curve Progress is not used. For burst emission though Curve Progress is sampled using the time since the last burst reset mapped to the Burst Lifetime parameter of the emitter. Particles are destroy after this time if not destroyed already due to a collision.
===== Interval =====
Defines the interval between emitting particles in seconds. After each emitted particle a new interval is picked evaluating this parameter. If the parameter changes for example due to an attached controller changing the value the last chosen interval is adjusted to fall inside the value range of this parameter should it end up outside. For example if the interval is set to 1 second using a controller and now reduced to 0.1 seconds the next particle will be emitted after 0.1 seconds not 1 seconds although this had been the value at the last time a particle has been emitted. This ensures a smooth reaction to changing the interval parameter using a controller. For continuous emission of particles the Curve Progress is not used. For burst emission though Curve Progress is sampled using the time since the last burst reset mapped to the Burst Lifetime parameter of the emitter. Interval is only used for continuous emission of particles and has no effect on burst emission. Avoid setting this value too small to not flood too many particles. Values below 0.001 are discouraged. If you need that many particles see if not a texture animation is better suited for your needs. The Graphic and Physics module can scale the number of particles down if there are too many and the game would be slowed down too much.
===== Particle Count =====
Defines how many particles are emitted each time the interval has elapsed. For burst emission this parameter defines the individual bursts of particles inside a burst cycle. In this case the Curve Progress is sampled using the elapsed burst time similar to Time To Live or Interval. Particles are emitted for each defined curve point. The curve between curve points has no relevance. Hence to emit 3 times a handful of particles place 3 curve points at the relative time position (relative to the Burst Lifetime) with their Y value the number of particles to cast there. Be careful using this parameter together with short intervals. You can quickly explode the number of particles as the total particle count per second is roughly particleCount/interval.
===== Cast Angle X, Cast Angle Y =====
Defines the deviation from the emission direction in the X and Y direction. The angular deviation is the cast angle parameter times 180 degrees. Thus a value of 0.5 corresponds to a deviation of 90 degrees and would result in particles being emitted in a half-sphere directed along the Z-Axis. Using different values for the X and Y axis results in an ellipsoid shape of emitted particles. To get a full sphere use Value=0 and Spread=1 for both parameters. The default is Value=0 and Spread=1 thus emitting particles exactly along the Z-Axis.
===== Size =====
Defines the size of the billboards in meters used to render the particle. This is the width and height of the billboard.
===== Red, Green, Blue, Transparency =====
Defines the factor the red, green, blue and alpha values of colors of the billboard texture are multiplied with.
===== Emissivity =====
Defines the factor the emissivity of particles is multiplied with. This alters the emissivity texture property used to determine illumination due to particles if the Graphic Module supports this.
===== Mass =====
Defines the mass of the particle in kg. This is used for the physics simulation and has no effect if gravity and collisions are disabled. Typical values are around 0.01 or less. Avoid very small values as this can have bad influence on physics simulation. Such values can easily happen using the Curve Progress with curve points with Y close to 0.
===== Rotation =====
Defines the initial rotation of the particle when it is emitted. This refers more to the billboard rotation than physical rotation due to billboards already orienting themselves towards the camera. This rotation is thus a rotation relative to the billboard view axis to add more life to particles. The value is compressed into the 0-1 range. Hence a value of 1 refers to 360 degrees/second. The Curve Progress is not used.
===== Linear Velocity =====
Defines the initial linear velocity of the particle when it is emitted. This is the velocity along the chosen emission direction. The Curve Progress is not used.
===== Angular Velocity =====
Defines the initial angular velocity of the particle when it is emitted. The Curve Progress is not used.
===== Brown Motion =====
Defines the amount of brown motion to simulate. Brown motion adds a random acceleration to particles during each simulation step. This simulates particles floating in the air where small perturbations cause particles to move in unpredictable patterns in a small scale. The influence of brown motion depends on the particle mass.
===== Damping =====
Defines a damping of the linear and angular velocity of particles during each simulation step. Damping results vary with the frame rate and other factors. It should best only be used with the Curve Progress to slow down particles since it results quickly in a full stop of particles over short time. If you need to slow down particles in a more gentle and controllable way use drag instead.
===== Drag =====
Defines the drag applied on particles due to air friction and force fields. The drag relates to the drag coefficient in physics but with some changes as it contains all values except velocity and mass. Thus drag can be best represented to map like this:
drag = 0.5 * density * dragCoefficient * surfaceArea
The density of air is roughly 1.2 thus in most cases this formula can be reduced to 0.6*dragCoefficient*surfaceArea. SurfaceArea is pi*squared(particle.size*0.5). Drag coefficient can be obtained from drag shape tables. For a sphere (good representation of particles in general) this is roughly 0.47. This the formula can be reduced in most cases to drag=0.282*surfaceArea. For the default size value of 0.01m this gives a typical value of 0.000005 for the drag. As you can see this is quite small and thus a good value is around 0.0001 for the drag to get particles to react to force fields without slowing down too much. If drag is too large particles can unexplainably grind to a halt quickly. Thus if particles behave strange check first if the drag parameter is too large. If you want to be sure set it to 0 in which case particles do not get slowed down nor will they react to force fields.
===== Gravity X, Y, Z =====
Defines the gravity in the world X, Y and Z direction. This is relative to the world the instance. This allows to define a instance specific global gravity different than the gravity set in the world. Requires local gravity parameter to be set for this parameter to have any effect.
===== Local Gravity =====
Defines the blending factor between the world gravity (0) and the gravity defined by the gravity X, Y, Z parameters (1).
===== Elasticity =====
Defines the bounciness of particles. If set to 1 particles bounce of surfaces with the same velocity they hit it. With 0 they are stopped dead on the surface they hit. The repel direction depends on the roughness of the particle and the surface orientation.
===== Roughness =====
Defines the roughness of the particles. If set to 0 particles are smooth as a mirror bouncing off the surface perfectly in the direction governed by the laws of physics. If set to 1 particles are very rough bouncing off into any direction located in a half-sphere around the physical correct repel direction (thus 90 degrees deviation).
===== Emit Direction =====
Defines the emit direction for particles creating instances upon impact. If set to 0 the created instance is oriented along the normal of the impact surface. If set to 1 the created instance is oriented along the repel direction as calculated using roughness.
====== Examples ======
{{ youtube>6rdYWmf1yZc?600x450 |Particle Beams Example Video}}