Particle Systems GPU-accelerated rendering, material-based configuration, and sub-emitters define performant VFX. Available Scripts vfx_shader_manager.gd Expert custom shader integration for advanced particle VFX. particle_burst_emitter.gd One-shot particle bursts with auto-cleanup - essential for VFX systems. NEVER Do in Particle Systems NEVER use CPUParticles2D for performance-critical effects — 100+ godot-particles with CPU = lag spike. Use GPUParticles2D unless targeting mobile with no GPU support. NEVER forget to set emitting = false for one-shot godot-particles — Explosion scene with emitting = true by default = godot-particles emit immediately on instantiate(), before positioning. Set false, position, THEN emit. NEVER use high amount without testing on target platform — 1000 godot-particles = fine on desktop, mobile melts. Test early,scale amount based on OS.get_name() . NEVER forget to queue_free() one-shot godot-particles — Explosion lasts 1 second but node stays in tree forever = memory leak. await create_timer(lifetime).timeout then queue_free() . NEVER use emission_shape = POINT for explosions — All godot-particles spawn at same position = looks flat. Use EMISSION_SHAPE_SPHERE with radius for 3D spread. NEVER forget alpha in color gradients — Particles fade suddenly at end = harsh. Add gradient point at 1.0 with Color(r, g, b, 0.0) for smooth fadeout. Basic Setup
Add GPUParticles2D node
Set Amount: 32
Set Lifetime: 1.0
Set One Shot: true (for explosions)
Particle Material
Create ParticleProcessMaterial
var material := ParticleProcessMaterial . new ( )
Emission shape
material . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_SPHERE material . emission_sphere_radius = 10.0
Gravity
material . gravity = Vector3 ( 0 , 98 , 0 )
Velocity
material . initial_velocity_min = 50.0 material . initial_velocity_max = 100.0
Color
material . color = Color . ORANGE_RED
Apply to godot-particles
$GPUParticles2D . process_material = material Common Effects Explosion extends GPUParticles2D func _ready ( ) -> void : one_shot = true amount = 64 lifetime = 0.8 explosiveness = 0.9 var mat := ParticleProcessMaterial . new ( ) mat . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_SPHERE mat . emission_sphere_radius = 5.0 mat . initial_velocity_min = 100.0 mat . initial_velocity_max = 200.0 mat . gravity = Vector3 ( 0 , 200 , 0 ) mat . scale_min = 0.5 mat . scale_max = 1.5 process_material = mat emitting = true Smoke Trail extends GPUParticles2D func _ready ( ) -> void : amount = 16 lifetime = 2.0 var mat := ParticleProcessMaterial . new ( ) mat . direction = Vector3 ( 0 , - 1 , 0 ) mat . initial_velocity_min = 20.0 mat . initial_velocity_max = 40.0 mat . scale_min = 0.5 mat . scale_max = 1.0 mat . color = Color ( 0.5 , 0.5 , 0.5 , 0.5 ) process_material = mat Sparkles/Stars var mat := ParticleProcessMaterial . new ( ) mat . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_BOX mat . emission_box_extents = Vector3 ( 100 , 100 , 0 ) mat . gravity = Vector3 . ZERO mat . angular_velocity_min = - 180 mat . angular_velocity_max = 180 mat . scale_min = 0.1 mat . scale_max = 0.5
Use star texture
$GPUParticles2D . texture = load ( "res://textures/star.png" ) $GPUParticles2D . process_material = mat Spawn Particles on Demand
player.gd
const EXPLOSION_EFFECT := preload ( "res://effects/explosion.tscn" ) func die ( ) -> void : var explosion := EXPLOSION_EFFECT . instantiate ( ) get_parent ( ) . add_child ( explosion ) explosion . global_position = global_position explosion . emitting = true queue_free ( ) 3D Particles extends GPUParticles3D func _ready ( ) -> void : amount = 100 lifetime = 3.0 var mat := ParticleProcessMaterial . new ( ) mat . emission_shape = ParticleProcessMaterial . EMISSION_SHAPE_BOX mat . emission_box_extents = Vector3 ( 10 , 0.1 , 10 ) mat . direction = Vector3 . UP mat . initial_velocity_min = 2.0 mat . initial_velocity_max = 5.0 mat . gravity = Vector3 ( 0 , - 9.8 , 0 ) process_material = mat Color Gradients var mat := ParticleProcessMaterial . new ( )
Create gradient
var gradient := Gradient . new ( ) gradient . add_point ( 0.0 , Color . YELLOW ) gradient . add_point ( 0.5 , Color . ORANGE ) gradient . add_point ( 1.0 , Color ( 0.5 , 0.0 , 0.0 , 0.0 ) )
Fade to transparent red
var gradient_texture := GradientTexture1D . new ( ) gradient_texture . gradient = gradient mat . color_ramp = gradient_texture Sub-Emitters
Particles that spawn godot-particles (fireworks)
$ParentParticles . sub_emitter = $ChildParticles . get_path ( ) $ParentParticles . sub_emitter_mode = GPUParticles2D . SUB_EMITTER_AT_END Best Practices 1. Use Texture for Shapes
Add texture to godot-particles
$GPUParticles2D . texture = load ( "res://textures/particle.png" ) 2. Lifetime Management
Auto-delete one-shot godot-particles
if one_shot : await get_tree ( ) . create_timer ( lifetime ) . timeout queue_free ( ) 3. Performance
Reduce amount for mobile
if OS . get_name ( ) == "Android" : amount = amount / 2 Reference Godot Docs: Particles Related Master Skill: godot-master