Overview
Atlas provides a flexible particle system for creating effects like fire, smoke, rain, snow, explosions, and more.
Particle Emitter
The ParticleEmitter class manages and renders particles:
#include "atlas/particle.h"
// Create emitter with max particle count
ParticleEmitter emitter ( 200 );
// Set position
emitter . setPosition ({ 0.0 f , 2.0 f , 0.0 f });
// Initialize GPU buffers
emitter . initialize ();
// Add to scene
window . addObject ( & emitter);
Emission Types
Fountain Emission
Particles emit in a direction with spread:
emitter . setEmissionType ( ParticleEmissionType ::Fountain);
emitter . setDirection ({ 0.0 f , 1.0 f , 0.0 f }); // Upward
emitter . setSpawnRadius ( 0.5 f ); // Radius around origin
Ambient Emission
Particles emit uniformly in all directions (snow, rain):
emitter . setEmissionType ( ParticleEmissionType ::Ambient);
emitter . setSpawnRadius ( 5.0 f ); // Large spawn area
Particle Settings
Configure particle behavior with ParticleSettings:
ParticleSettings settings;
settings . minLifetime = 1.0 f ; // Min lifetime in seconds
settings . maxLifetime = 3.0 f ; // Max lifetime in seconds
settings . minSize = 0.05 f ; // Min particle size
settings . maxSize = 0.1 f ; // Max particle size
settings . fadeSpeed = 0.5 f ; // Alpha fade rate
settings . gravity = - 9.81 f ; // Gravitational force
settings . spread = 1.0 f ; // Velocity spread
settings . speedVariation = 0.5 f ; // Speed randomization
emitter . setParticleSettings (settings);
Minimum lifetime of a particle in seconds
Maximum lifetime of a particle in seconds
Minimum size of a particle
Maximum size of a particle
Speed at which particles fade out (alpha reduction per second)
Gravitational force applied to particles (negative = down)
Spread of particles from the emitter direction
How much the particle speed is randomized (0 = uniform, 1 = varied)
Spawn Control
Spawn Rate
Control how many particles spawn per second:
emitter . setSpawnRate ( 20.0 f ); // 20 particles/second
Emission Modes
// Continuous emission (default)
emitter . emitContinuously ();
// Single burst then stop
emitter . emitOnce ();
// Manual burst
emitter . emitBurst ( 50 ); // Emit 50 particles immediately
// Start/stop emission
emitter . startEmission ();
emitter . stopEmission ();
Particle Appearance
Color
Set particle color tint:
emitter . setColor ( Color ( 1.0 f , 0.5 f , 0.2 f , 1.0 f )); // Orange tint
Texture
Attach sprite texture to particles:
// Create or load texture
Texture particleTexture = Texture :: fromResourceName (
"ParticleSprite" ,
TextureType ::Color
);
// Attach to emitter
emitter . attachTexture (particleTexture);
emitter . enableTexture ();
For rain particles, use the built-in streak texture:
Texture rainStreak = Texture :: createRainStreak ( 64 , 256 );
emitter . attachTexture (rainStreak);
emitter . enableTexture ();
Particle Structure
Individual particles have these properties:
struct Particle {
Position3d position; // Current position
Magnitude3d velocity; // Velocity vector
Color color; // Particle color
float life; // Current life (seconds)
float maxLife; // Maximum life (seconds)
float size; // Size/scale
bool active; // Is particle alive?
};
Complete Examples
Fire Effect
ParticleEmitter fire ( 500 );
fire . setPosition ({ 0.0 f , 0.0 f , 0.0 f });
fire . setEmissionType ( ParticleEmissionType ::Fountain);
fire . setDirection ({ 0.0 f , 1.0 f , 0.0 f });
fire . setSpawnRadius ( 0.3 f );
fire . setSpawnRate ( 100.0 f );
ParticleSettings fireSettings;
fireSettings . minLifetime = 0.5 f ;
fireSettings . maxLifetime = 1.5 f ;
fireSettings . minSize = 0.1 f ;
fireSettings . maxSize = 0.3 f ;
fireSettings . fadeSpeed = 2.0 f ;
fireSettings . gravity = - 2.0 f ; // Slight upward force
fireSettings . spread = 0.3 f ;
fireSettings . speedVariation = 0.8 f ;
fire . setParticleSettings (fireSettings);
fire . setColor ( Color ( 1.0 f , 0.5 f , 0.1 f , 1.0 f )); // Orange-red
fire . initialize ();
window . addObject ( & fire);
Snow Effect
ParticleEmitter snow ( 1000 );
snow . setPosition ({ 0.0 f , 10.0 f , 0.0 f });
snow . setEmissionType ( ParticleEmissionType ::Ambient);
snow . setSpawnRadius ( 10.0 f );
snow . setSpawnRate ( 50.0 f );
ParticleSettings snowSettings;
snowSettings . minLifetime = 5.0 f ;
snowSettings . maxLifetime = 8.0 f ;
snowSettings . minSize = 0.02 f ;
snowSettings . maxSize = 0.05 f ;
snowSettings . fadeSpeed = 0.2 f ;
snowSettings . gravity = - 1.0 f ; // Gentle fall
snowSettings . spread = 2.0 f ;
snowSettings . speedVariation = 0.3 f ;
snow . setParticleSettings (snowSettings);
snow . setColor ( Color :: white ());
snow . initialize ();
window . addObject ( & snow);
Rain Effect
ParticleEmitter rain ( 2000 );
rain . setPosition ({ 0.0 f , 20.0 f , 0.0 f });
rain . setEmissionType ( ParticleEmissionType ::Ambient);
rain . setSpawnRadius ( 15.0 f );
rain . setSpawnRate ( 200.0 f );
ParticleSettings rainSettings;
rainSettings . minLifetime = 2.0 f ;
rainSettings . maxLifetime = 4.0 f ;
rainSettings . minSize = 0.03 f ;
rainSettings . maxSize = 0.05 f ;
rainSettings . fadeSpeed = 0.5 f ;
rainSettings . gravity = - 20.0 f ; // Fast fall
rainSettings . spread = 0.5 f ;
rainSettings . speedVariation = 0.2 f ;
rain . setParticleSettings (rainSettings);
// Use streak texture for rain
Texture rainStreak = Texture :: createRainStreak ( 64 , 256 );
rain . attachTexture (rainStreak);
rain . enableTexture ();
rain . setColor ( Color ( 0.7 f , 0.7 f , 0.9 f , 0.6 f )); // Light blue, transparent
rain . initialize ();
window . addObject ( & rain);
Explosion Effect
ParticleEmitter explosion ( 300 );
explosion . setPosition ({ 5.0 f , 2.0 f , 0.0 f });
explosion . setEmissionType ( ParticleEmissionType ::Fountain);
explosion . setSpawnRadius ( 0.1 f );
ParticleSettings explosionSettings;
explosionSettings . minLifetime = 0.5 f ;
explosionSettings . maxLifetime = 1.0 f ;
explosionSettings . minSize = 0.1 f ;
explosionSettings . maxSize = 0.4 f ;
explosionSettings . fadeSpeed = 3.0 f ;
explosionSettings . gravity = - 5.0 f ;
explosionSettings . spread = 3.0 f ; // Wide spread
explosionSettings . speedVariation = 1.5 f ; // High variation
explosion . setParticleSettings (explosionSettings);
explosion . setColor ( Color ( 1.0 f , 0.7 f , 0.2 f , 1.0 f )); // Bright orange
explosion . initialize ();
// Emit once as a burst
explosion . emitOnce ();
window . addObject ( & explosion);
Rendering
Particles use billboarding to always face the camera:
void ParticleEmitter :: render (
float dt ,
std :: shared_ptr < opal :: CommandBuffer > commandBuffer ,
bool updatePipeline
) override ;
Particles are rendered with:
Alpha blending enabled
Depth test enabled, depth write disabled
Billboard orientation (always face camera)
Particle Count Limit active particles based on target hardware:
Mobile: 100-500 particles
Desktop: 500-2000 particles
High-end: 2000+ particles
Texture Size Use small particle textures (64x64 or 128x128) to reduce memory bandwidth.
Deferred Rendering Particles use forward rendering and cannot participate in deferred shading: bool canUseDeferredRendering () override { return false ; }
Best Practices
The emitter automatically reuses dead particles, so setting maxParticles creates a fixed pool.
Use different min/max lifetimes for more natural-looking effects.
Vary particle sizes to add depth and realism.
Adjust gravity for different effects: negative for upward (fire), positive for downward (rain).
Use alpha values < 1.0 for translucent effects like smoke or fog.
See Also