Skip to content

Support animated particles (per-particle frames from a sprite sheet) #1610

Description

@obiot

Summary

A particle draws one whole image with fixed UVs. There is no way to give it a frame from a sprite sheet, so particles cannot be animated, and cannot vary their appearance across a burst.

Current state

ParticleEmitterSettings.image is a single HTMLCanvasElement | HTMLImageElement, and Particle.draw blits all of it:

renderer.drawImage(this.image, 0, 0, w, h, 0, 0, w, h);

No frame, no atlas region, no per-particle UVs. Every particle of an emitter is visually identical apart from tint, scale, rotation and alpha.

What this would enable

  • animated particles — smoke that curls, sparks that flicker, an explosion playing a frame sequence, each particle advancing through the sheet over its own lifetime
  • variety within a burst — several debris shapes drawn from one sheet, picked per particle at birth, so a burst does not read as N copies of one sprite
  • Both are common enough that their absence is usually worked around by running several emitters with different images, which multiplies the per-emitter cost for what should be one batch.

Shape of the API

Roughly what a Sprite already accepts, so the vocabulary carries over:

  • a frame size (or a named region set) alongside image
  • per-particle frame selection: a sequence advanced over the particle's life, or a random frame chosen at birth
  • the existing lifetime/scale/rotation machinery unchanged

Why this is filed now, before it is built

It constrains #1404 (GPU-instanced particle rendering). Instancing carries a per-instance record, and per-particle UVs must be reserved in that record from the start — a UV rect is four floats, and the existing instance record (src/video/gpu/instancerecord.ts) already documents a spare four-float slot with "an atlas offset" named as an intended use.

Retrofitting UVs after an instanced batcher exists means changing the vertex layout, the shader and both GPU backends. Reserving the slot up front costs nothing.

Worth noting instancing does not otherwise conflict: particles on different frames of the same sheet batch in one draw. The constraint it does impose is one texture per instanced draw, so particles drawn from genuinely different images would still need separate draws — which is already true of the current quad batcher.

Not urgent

Filed to record the constraint, not to schedule the work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions