Overview
Godot provides powerful particle systems for creating visual effects like fire, smoke, sparks, magic effects, and more. Particles can be processed on the CPU or GPU, each with different capabilities and performance characteristics.
Particle types
GPUParticles2D
GPU-accelerated 2D particles:
var particles = GPUParticles2D . new ()
particles . amount = 100
particles . lifetime = 2.0
particles . one_shot = false
particles . explosiveness = 0.0
particles . randomness = 0.0
particles . emitting = true
# Set process material
var material = ParticleProcessMaterial . new ()
particles . process_material = material
add_child ( particles )
GPUParticles3D
GPU-accelerated 3D particles:
var particles = GPUParticles3D . new ()
particles . amount = 500
particles . lifetime = 3.0
particles . one_shot = false
particles . explosiveness = 0.0
particles . emitting = true
# Set process material
var material = ParticleProcessMaterial . new ()
particles . process_material = material
# Set draw passes
var quad_mesh = QuadMesh . new ()
particles . draw_pass_1 = quad_mesh
add_child ( particles )
GPUParticles are processed on the GPU and can handle thousands of particles efficiently. They’re only available with Forward+ and Mobile renderers.
CPUParticles2D
CPU-processed 2D particles:
var particles = CPUParticles2D . new ()
particles . amount = 50
particles . lifetime = 2.0
particles . one_shot = false
particles . emitting = true
# Configure emission
particles . emission_shape = CPUParticles2D . EMISSION_SHAPE_SPHERE
particles . emission_sphere_radius = 10.0
# Particle properties
particles . direction = Vector2 ( 0 , - 1 )
particles . spread = 45.0
particles . initial_velocity_min = 50.0
particles . initial_velocity_max = 100.0
add_child ( particles )
CPUParticles3D
CPU-processed 3D particles:
var particles = CPUParticles3D . new ()
particles . amount = 100
particles . lifetime = 3.0
particles . emitting = true
# Configure emission
particles . emission_shape = CPUParticles3D . EMISSION_SHAPE_BOX
particles . emission_box_extents = Vector3 ( 2 , 2 , 2 )
# Particle properties
particles . direction = Vector3 ( 0 , 1 , 0 )
particles . spread = 45.0
particles . gravity = Vector3 ( 0 , - 9.8 , 0 )
add_child ( particles )
Use CPUParticles for compatibility with all rendering backends, including the Compatibility renderer and web exports.
ParticleProcessMaterial
Configure particle behavior for GPU particles:
Emission settings
var material = ParticleProcessMaterial . new ()
# Emission shape
material . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_SPHERE
material . emission_sphere_radius = 5.0
# Direction and spread
material . direction = Vector3 ( 0 , 1 , 0 )
material . spread = 45.0
material . flatness = 0.0
# Initial velocity
material . initial_velocity_min = 10.0
material . initial_velocity_max = 20.0
Emission shapes
All particles emit from a single point.
Particles emit from within or on the surface of a sphere.
Particles emit only from the sphere’s surface.
Particles emit from within a box volume.
Particles emit from an array of specified points.
Emit from points with specific directions.
Emit from a ring shape (3D only).
Gravity and forces
# Gravity
material . gravity = Vector3 ( 0 , - 9.8 , 0 )
# Radial acceleration
material . radial_accel_min = 0.0
material . radial_accel_max = 0.0
# Tangential acceleration
material . tangential_accel_min = 0.0
material . tangential_accel_max = 0.0
# Damping
material . damping_min = 0.0
material . damping_max = 0.0
Color and scale over lifetime
# Color gradient
var gradient = Gradient . new ()
gradient . add_point ( 0.0 , Color . WHITE )
gradient . add_point ( 0.5 , Color . YELLOW )
gradient . add_point ( 1.0 , Color . RED )
var gradient_texture = GradientTexture1D . new ()
gradient_texture . gradient = gradient
material . color_ramp = gradient_texture
# Scale curve
var curve = Curve . new ()
curve . add_point ( Vector2 ( 0.0 , 1.0 ))
curve . add_point ( Vector2 ( 0.5 , 1.5 ))
curve . add_point ( Vector2 ( 1.0 , 0.0 ))
var curve_texture = CurveTexture . new ()
curve_texture . curve = curve
material . scale_curve = curve_texture
Rotation and angular velocity
# Initial angle
material . angle_min = 0.0
material . angle_max = 360.0
# Angular velocity
material . angular_velocity_min = 0.0
material . angular_velocity_max = 180.0
# Orbital velocity (3D)
material . orbit_velocity_min = 0.0
material . orbit_velocity_max = 0.0
Animation
# For sprite sheet animations
material . anim_speed_min = 1.0
material . anim_speed_max = 1.0
material . anim_offset_min = 0.0
material . anim_offset_max = 1.0
Particle attractors (3D)
Create forces that attract or repel particles:
GPUParticlesAttractorSphere3D
var attractor = GPUParticlesAttractorSphere3D . new ()
attractor . radius = 5.0
attractor . strength = 10.0
attractor . attenuation = 1.0
attractor . directionality = 0.0 # 0 = radial, 1 = directional
add_child ( attractor )
GPUParticlesAttractorBox3D
var attractor = GPUParticlesAttractorBox3D . new ()
attractor . size = Vector3 ( 10 , 10 , 10 )
attractor . strength = 5.0
attractor . attenuation = 2.0
add_child ( attractor )
GPUParticlesAttractorVectorField3D
var attractor = GPUParticlesAttractorVectorField3D . new ()
attractor . size = Vector3 ( 10 , 10 , 10 )
attractor . texture = preload ( "res://vector_field.bmp" ) # 3D texture
attractor . strength = 1.0
add_child ( attractor )
Particle collisions (3D)
Make particles collide with objects:
GPUParticlesCollisionSphere3D
var collision = GPUParticlesCollisionSphere3D . new ()
collision . radius = 5.0
add_child ( collision )
# Enable collision in particle material
material . collision_mode = ParticleProcessMaterial . COLLISION_RIGID
material . collision_friction = 0.5
material . collision_bounce = 0.5
GPUParticlesCollisionBox3D
var collision = GPUParticlesCollisionBox3D . new ()
collision . size = Vector3 ( 10 , 1 , 10 )
add_child ( collision )
GPUParticlesCollisionHeightField3D
var collision = GPUParticlesCollisionHeightField3D . new ()
collision . size = Vector3 ( 100 , 10 , 100 )
collision . resolution = GPUParticlesCollisionHeightField3D . RESOLUTION_1024
collision . update_mode = GPUParticlesCollisionHeightField3D . UPDATE_MODE_WHEN_MOVED
add_child ( collision )
GPUParticlesCollisionSDF3D
var collision = GPUParticlesCollisionSDF3D . new ()
collision . size = Vector3 ( 20 , 20 , 20 )
collision . resolution = GPUParticlesCollisionSDF3D . RESOLUTION_256
collision . texture = signed_distance_field_texture
collision . thickness = 1.0
add_child ( collision )
Particle collisions are GPU-intensive. Use them sparingly and with appropriate resolution settings.
Common particle effects
Fire effect
var fire = GPUParticles3D . new ()
fire . amount = 200
fire . lifetime = 1.5
fire . emitting = true
var material = ParticleProcessMaterial . new ()
material . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_SPHERE
material . emission_sphere_radius = 0.5
material . direction = Vector3 ( 0 , 1 , 0 )
material . spread = 25.0
material . initial_velocity_min = 2.0
material . initial_velocity_max = 4.0
material . gravity = Vector3 ( 0 , 0 , 0 )
material . scale_min = 0.5
material . scale_max = 1.0
# Fire colors
var gradient = Gradient . new ()
gradient . add_point ( 0.0 , Color ( 1.0 , 1.0 , 0.8 , 1.0 )) # White-yellow
gradient . add_point ( 0.3 , Color ( 1.0 , 0.8 , 0.0 , 1.0 )) # Orange
gradient . add_point ( 0.7 , Color ( 1.0 , 0.2 , 0.0 , 0.5 )) # Red
gradient . add_point ( 1.0 , Color ( 0.1 , 0.0 , 0.0 , 0.0 )) # Dark transparent
var gradient_texture = GradientTexture1D . new ()
gradient_texture . gradient = gradient
material . color_ramp = gradient_texture
fire . process_material = material
fire . draw_pass_1 = QuadMesh . new ()
Smoke effect
var smoke = CPUParticles3D . new ()
smoke . amount = 50
smoke . lifetime = 3.0
smoke . emission_shape = CPUParticles3D . EMISSION_SHAPE_SPHERE
smoke . emission_sphere_radius = 0.3
smoke . direction = Vector3 ( 0 , 1 , 0 )
smoke . spread = 15.0
smoke . initial_velocity_min = 1.0
smoke . initial_velocity_max = 2.0
smoke . gravity = Vector3 ( 0 , 0.5 , 0 ) # Slight upward drift
smoke . scale_amount_min = 1.0
smoke . scale_amount_max = 2.0
smoke . scale_amount_curve = create_growth_curve ()
smoke . color_ramp = create_smoke_gradient ()
Rain effect
var rain = GPUParticles3D . new ()
rain . amount = 1000
rain . lifetime = 5.0
rain . emitting = true
var material = ParticleProcessMaterial . new ()
material . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_BOX
material . emission_box_extents = Vector3 ( 20 , 0 , 20 )
material . direction = Vector3 ( 0 , - 1 , 0 )
material . spread = 0.0
material . initial_velocity_min = 10.0
material . initial_velocity_max = 15.0
material . gravity = Vector3 ( 0 , - 20 , 0 )
rain . process_material = material
Explosion effect
var explosion = GPUParticles3D . new ()
explosion . amount = 500
explosion . lifetime = 2.0
explosion . one_shot = true
explosion . explosiveness = 1.0 # All particles spawn at once
explosion . emitting = true
var material = ParticleProcessMaterial . new ()
material . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_SPHERE
material . emission_sphere_radius = 0.1
material . direction = Vector3 ( 0 , 0 , 0 )
material . spread = 180.0
material . initial_velocity_min = 5.0
material . initial_velocity_max = 15.0
material . gravity = Vector3 ( 0 , - 9.8 , 0 )
material . damping_min = 2.0
material . damping_max = 4.0
explosion . process_material = material
Magic sparkles
var sparkles = GPUParticles2D . new ()
sparkles . amount = 100
sparkles . lifetime = 1.0
sparkles . emitting = true
var material = ParticleProcessMaterial . new ()
material . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_SPHERE
material . emission_sphere_radius = 20.0
material . direction = Vector3 ( 0 , - 1 , 0 )
material . spread = 180.0
material . initial_velocity_min = 20.0
material . initial_velocity_max = 50.0
material . gravity = Vector3 ( 0 , 30 , 0 ) # Float upward
material . angular_velocity_min = - 360.0
material . angular_velocity_max = 360.0
# Twinkling effect
var scale_curve = Curve . new ()
scale_curve . add_point ( Vector2 ( 0.0 , 0.0 ))
scale_curve . add_point ( Vector2 ( 0.5 , 1.0 ))
scale_curve . add_point ( Vector2 ( 1.0 , 0.0 ))
material . scale_curve = create_curve_texture ( scale_curve )
sparkles . process_material = material
Custom particle shaders
Create advanced particle behavior with custom shaders:
shader_type particles;
uniform float orbit_speed = 1.0 ;
void process () {
// Orbital motion
float angle = TIME * orbit_speed + float (INDEX) * 0.1 ;
float radius = 5.0 ;
TRANSFORM [ 3 ]. x = cos (angle) * radius;
TRANSFORM [ 3 ]. z = sin (angle) * radius;
TRANSFORM [ 3 ]. y = sin (TIME + float (INDEX)) * 2.0 ;
// Custom color
COLOR = vec4 ( 1.0 , float (INDEX) / float (NUMBER), 0.5 , 1.0 );
}
Particle sub-emitters
Create particles that spawn other particles:
# Main particle system
var main_particles = GPUParticles3D . new ()
# Sub-emitter
var sub_emitter = GPUParticles3D . new ()
sub_emitter . amount = 10
sub_emitter . lifetime = 0.5
# Configure sub-emitter trigger
main_particles . sub_emitter = sub_emitter . get_path ()
main_particles . sub_emitter_mode = GPUParticles3D . SUB_EMITTER_AT_END
# Options: AT_END, AT_COLLISION, CONSTANT
Use appropriate particle count Start with fewer particles and increase until you achieve the desired effect.
Choose CPU vs GPU wisely Use GPU particles for large amounts, CPU particles for fewer particles or compatibility.
Optimize draw calls Batch similar particle systems and reuse materials.
Use visibility ranges Disable distant particle systems using visibility ranges.
Converting between CPU and GPU
# Convert GPU to CPU
var cpu_particles = CPUParticles3D . new ()
cpu_particles . convert_from_particles ( gpu_particles )
# Note: Conversion from CPU to GPU is not supported
Next steps
Shaders Create custom particle shaders
Environment Configure world environment