Representation-First Particles, Trails, and Effects

Representation-first Three.js WebGPU/TSL particles, trails, and effects. Use for analytic or recurrent particle motion, stable-slot or scan-compacted GPU pools, flow-conforming shells and wakes, dissolving debris, or effect-specific HDR and depth integration.

Image: Pooled effects correctness presentation. Source lab: webgpu-pooled-effects.

$threejs-particles-trails-and-effects 1 primary target 1 flagship 1 secondary surface native evidence pending Latest skill update commit 2ce13bc ↗ SKILL.md on GitHub ↗ raw (for agents) ↗

Primary target surface

These rendering routes are generated from canonical source. Native-WebGPU acceptance remains separate from entrypoint availability.

Evidence reports

Source hashes, claim verdicts, promoted same-lab media, fixed routes, exact tier contracts, and current limitations.

The approach, mathematically

Particles live on the GPU: a compute pass integrates state in storage buffers, instanced geometry reads it directly — zero CPU round trips:

$$\mathbf v' = \mathbf v + \big(\mathbf g + \mathbf F_{field}(\mathbf p)/m\big)dt, \qquad \mathbf p' = \mathbf p + \mathbf v'\,dt$$

Lifetimes drive everything through normalized age $u = t_{age}/t_{life}$: size, color ramp, and alpha are functions of $u$, and dead slots recycle through a dense-swap pool so the draw range stays tight. Reentry plasma conforms to the ship: emission points sample the hull surface, intensity follows a ram-pressure proxy $I \propto \rho\,v^2 \cdot \max(0, \hat{\mathbf n}\cdot\hat{\mathbf v})$.

Emission is scene-relative HDR through MRT: a spark is bright relative to the sun, and bloom reveals that hierarchy rather than inventing one.

Preview and evidence ledger

Every image identifies what it proves. Page screenshots demonstrate the published presentation only; generated inputs demonstrate asset channels only; rendering acceptance still requires same-lab readback and a schema-v2 bundle.

Canonical runtime evidence pending8 published images
Native WebGPU runtime evidence preview

WebGPU Pooled Effects

Evidence pending
visualCorrectness
INSUFFICIENT_EVIDENCE
mechanismCorrectness
INSUFFICIENT_EVIDENCE
performanceCompliance
NOT_CLAIMED
gpuAttribution
NOT_CLAIMED
lifecycleStability
INSUFFICIENT_EVIDENCE
  • Current-source correctness capture validates under lab validate:artifacts with legacy-v2 evidence-manifest bound to canonical sourceHash.
  • Mechanism/visual claims remain INSUFFICIENT_EVIDENCE; GPU timestamps NOT_CLAIMED.
  • Not a publishable release-bundle.

The full skill

The complete SKILL.md as loaded by agents, rendered verbatim.

Representation-First Particles, Trails, and Effects

Own GPU-resident object- and world-space effects: spawn, motion, lifetime, compaction, draw representation, depth/blend behavior, and scene-linear HDR emission. Route viewport history to $threejs-dynamic-surface-effects, weather accumulation to $threejs-rain-snow-and-wet-surfaces, authored event motion to $threejs-procedural-motion-systems, and shared post ownership to $threejs-image-pipeline or $threejs-bloom.

When an effect consumes collision, forcing, or exchange owned by another system, close this local handoff before step 1:

  • name the quantity and units, producer frame/origin, transform revision, and origin generation;
  • name the half-open source interval, cadence, sample phase, immutable producer version, and permitted pool consumer;
  • declare support/filter, validity, staleness, error, and missing/overflow policy;
  • mark one-way reads or name the two-way source/reaction owners, application order, and applied state version;
  • bind the GPU resource generation, producing and consuming passes, completion dependency, and reset on discontinuity, rebase, or generation change while keeping the steady frame readback-free.

The source owner retains authority; the pool consumes immutable publications. Invoke $threejs-choose-skills when the route needs additional system owners. Then read coupled inputs for effect-specific ownership and degradation rules.

Process

1. Define the observable and its owners

Write one effect contract containing:

  • the event interval, deterministic seed, effect class, transform, and flow/impact direction;
  • the coordinate frame, distance/time units, lifetime clock, and seek/reset behavior;
  • the visible roles: silhouette, motion, illumination, residue, or occlusion;
  • the depth-test, depth-write, blend/order, HDR signal, and final-output owner;
  • any external producer and whether the pool is presentation-only or backed by a separately owned physical body.

The step is complete when every visible or physical claim has one owner and every input has a frame, time, validity policy, and consumer.

2. Select motion and neighborhood representation

Choose the least writable state that represents the mechanism:

Mechanism Representation
Pose and appearance are pure functions of spawn data and time Immutable spawn records; evaluate analytically in vertex TSL
State recurs independently per particle Structure-of-arrays hot state; one named compute integration stage
Collision or field feedback changes state Recurrent state plus the owning GPU field/proxy at the same frame and sample time
Neighbor interactions matter Spatial grid/hash or sort-and-scan before bounded local interaction

Select allocation independently:

Occupancy behavior Allocation/compaction
Holes cost less than scan/scatter traffic Stable slots, generation-bearing identity, alive flag, and bounded visible range
Dense output materially reduces later work mark -> exclusive scan -> scatter -> publish indirect count into a second state set
Removal is serialized with unique source/destination ownership Dense tail swap may be used; move every state and identity lane atomically

For recurrent or compacted pools, read state and compaction before implementation. The step is complete when every writable lane and every compaction phase is justified by a downstream consumer or measured saving.

3. Specify the state transition and identity lifecycle

Keep the order explicit:

ordered event packets
  -> deterministic spawn/range allocation
  -> analytic evaluation or one recurrent update
  -> optional ordered compaction
  -> draw from the committed state/count
  -> post consumers

Generate cold parameters once and update only recurrent lanes. Preserve stable entity identity across slot movement. Birth, death, slot reuse, teleport, representation change, and unavailable prior state invalidate motion vectors, trails, interpolation, and temporal history before presentation. Analytic particles evaluate both previous and current presentation times; recurrent pools retain adjacent immutable presentation states.

Read temporal identity when the effect feeds TAA, motion vectors, trails, or multi-frame post. The step is complete when each state version has one writer, draw consumes a committed version, and a reused slot cannot inherit prior entity history.

4. Build the r185 GPU path

Use WebGPURenderer from three/webgpu, call await renderer.init(), and require renderer.backend.isWebGPUBackend === true for this canonical path. Route explicit WebGPU-unavailable teaching to $threejs-compatibility-fallbacks. Use Fn().compute(...), renderer.compute(...), storage nodes and StorageInstancedBufferAttribute for recurrent state. Render sprites with SpriteNodeMaterial; render shaped particles with InstancedMesh and a NodeMaterial family material. Dense compaction publishes an indirect command through IndirectStorageBufferAttribute and geometry.setIndirect().

computeAsync() in r185 waits for renderer initialization, not GPU completion. Express global phase dependencies as ordered dispatches and keep frame-critical counts and state GPU-resident.

Read r185 execution facts when implementing compute, indirect draw, bounds, or completion. The step is complete when spawn, update, compaction, and draw have explicit GPU ordering and the steady frame path performs no readback or per-particle object update.

5. Bind representation, depth, and output

Use sprites or instanced quads for camera-facing sparks, instanced lit meshes for shaped debris, hull-derived geometry for conforming plasma, and generated capsule/profile geometry for wakes. For flow-conforming work, read shells and wakes. For spark or debris work, read analytic sparks and dissolving debris.

Give each draw class an explicit depth and transparency contract. Use chunked analytic bounds or a GPU reduction for storage-driven motion. Keep beauty in scene-linear HDR through one tone-map/output conversion owner. Full-scene bloom reads HDR beauty; allocate a selective emissive MRT only for an authored inclusion/exclusion requirement with a valid transparent blend and measured attachment cost.

Read depth, HDR, and output before accepting transparent or emissive effects. The step is complete when occlusion, ordering, bounds, HDR contribution, and final conversion each have one tested owner.

6. Prove the mechanism and budget

Capture seeded fixed-time states and expose event/spawn count, live/slot count, overflow, identity mapping, age/velocity, compaction count, bounds, depth mode, raw HDR, optional selective signal, bloom contribution, overdraw, and GPU time per compute/draw class. Compare analytic versus recurrent cost, and stable slots versus compaction, at the same occupancy.

Verify the beauty path with bloom disabled. Preserve readable silhouette, layer roles, depth, and motion without halo support. Scale by stopping idle work, removing unnecessary writable state or compaction, then reducing active count, field bandwidth, transparent layers, and post extent while preserving the selected motion class and owners.

Read resource accounting and diagnostics and failure signatures for the applicable branches. The skill is complete when the seeded result is repeatable; event, update, compaction, and draw order is evidenced; stable identity and reset controls pass; the frame path has zero required readbacks; depth and output ownership are singular; the bloom-off image remains legible; and the complete scene meets its named resource and timing budget.