2D Particles
The particle system renders textured quads in bulk. It is independent of lighting — particles can be lit (LightDraw.litSprite) or unlit (ParticleDraw.particles).
Separation of concerns
Particle rendering is split into two layers:
- Simulation — your update function handles velocities, lifetimes, physics
- Render — writes
Particle2Dsnapshots,ParticleDraw.particlesadds them to the buffer
Particle2D
[<Struct>]
type Particle2D = {
Position: Vector2 // center position (world or screen)
Size: Vector2 // width and height
Rotation: float32 // degrees
SourceRect: Rectangle // source rect on the texture
Color: Color // tint + alpha
}
Rendering
// Pre-allocate a pool in your model
let particles = Array.zeroCreate<Particle2D> 1024
let mutable particleCount = 0
// Each frame, write active particles into the array, then draw:
buffer
|> ParticleDraw.particles particleTexture particles particleCount 10<RenderLayer>
ParticleDraw.particles adds a single command to the buffer that draws all particles in a loop. All particles share one texture.
Simulation helpers
ParticleSimulation.fadeAndCompact fades particles by reducing alpha and compacts dead ones out of the array:
open Mibo.Elmish.Graphics2D.Lighting
// In your update (e.g., Tick handler):
ParticleSimulation.fadeAndCompact
particles // Particle2D array
&particleCount // byref — updated after compaction
60f // fade speed (alpha/sec — 60 = fully faded in 1s)
dt // delta time
Particles with alpha ≤ 0 are removed in a single pass. The array is compacted in-place (no allocation).
Performance
- All particles share one texture and one draw call — efficient for hundreds of particles.
- Pre-allocate your array to max expected count.
fadeAndCompactreuses slots. - Particles don't interact with the lighting system by default. For lit particles, draw them individually via
LightDraw.litSprite(see Lighting).
See Also
- Lighting & Shadows — Lit particles via
LightDraw.litSprite - Buffer & Commands — General drawing reference
Multiple items
type StructAttribute = inherit Attribute new: unit -> StructAttribute
--------------------
new: unit -> StructAttribute
type StructAttribute = inherit Attribute new: unit -> StructAttribute
--------------------
new: unit -> StructAttribute
[<Struct>]
type Particle2D =
{
Position: obj
Size: obj
Rotation: float32
SourceRect: obj
Color: obj
}
Multiple items
val float32: value: 'T -> float32 (requires member op_Explicit)
--------------------
type float32 = System.Single
--------------------
type float32<'Measure> = float32
val float32: value: 'T -> float32 (requires member op_Explicit)
--------------------
type float32 = System.Single
--------------------
type float32<'Measure> = float32
val particles: Particle2D array
module Array
from Microsoft.FSharp.Collections
val zeroCreate: count: int -> 'T array
val mutable particleCount: int
Mibo.Raylib