Taos API Reference
    Preparing search index...

    Class ParticlePass

    GPU particle system pass (render-graph version).

    Compute (spawn -> update -> compact -> indirect-write) followed by an indirect billboard draw, either alpha-blended into the HDR target (forward mode) or additive into the GBuffer (deferred mode), driven by config.renderer.

    Hierarchy (View Summary)

    • Pass<ParticleDeps, ParticleOutputs>
      • ParticlePass
    Index

    Properties

    name: "ParticlePass" = 'ParticlePass'

    Human-readable identifier used in graph node labels and error messages.

    paused: boolean = false

    When true, the simulation is frozen: update()/addToGraph still run so the last frame keeps rendering (camera stays live), but no compute dispatches or sim bookkeeping happen. Toggle via the field; advance a single frozen step with requestStep.

    Accessors

    Methods

    • Sets the world-space center + radius of a sphere_collision modifier marked dynamic, so the collider can move at runtime (e.g. track a physics body). Radius 0 disables it. Takes effect on the next ParticlePass.update. No-op for graphs without a dynamic sphere collider (the uniform is ignored).

      Parameters

      • x: number
      • y: number
      • z: number
      • radius: number

      Returns void

    • Conservative CPU-side test for whether any particle could still be alive, so the caller can skip addToGraph (and all its GPU dispatches + draws) for an idle emitter. True while spawning continuously, while a burst is pending, or until the longest possible particle lifetime has elapsed since the last spawn. Never under-reports — a pass it returns false for has definitely emptied. Requires update to have run this frame first.

      Returns boolean

    • Parameters

      • position: { x: number; y: number; z: number }
      • color: [number, number, number, number]
      • count: number

      Returns void

    • Create a ParticlePass for config.

      Parameters

      • ctx: RenderContext
      • config: ParticleGraphConfig
      • options: ParticlePassOptions = {}

        Construction-time options for ParticlePass.create.

        • OptionalparentSplit?: {
              split: SplitNode;
              queueBuffer: GPUBuffer;
              counterBuffer: GPUBuffer;
              capacity: number;
          }

          Set by the parent pass when this instance is a sub-emitter (split) child. Internal.

        • OptionalforwardPass?: ForwardPass

          Required when the config's renderer.type === 'mesh' and renderer.renderTarget === 'hdr'. The particle pass borrows this ForwardPass's lighting+IBL bind group layout for its instanced-PBR pipeline and its bind group at draw time, so all forward-lit content shares the same light/IBL state. The host must call forwardPass.updateLights(...) before ParticlePass.addToGraph.

        • OptionalheightmapRes?: number

          Side length in cells of the block_collision heightmap storage buffer. Default 128 (matches the historical hard-coded layout). Lower values trade resolution for cheaper CPU bakes; the shader uses the same uniform for sample-position math so this is safe to vary per pass. Ignored when the particle graph has no block_collision modifier.

      Returns Promise<ParticlePass>

    • Seed a patch field from a CPU resolution × resolution grid of values (the AgentScript importDataSet — load a heightmap / density / cost raster the agents then sense). data is row-major [z*res + x], in field units (the deposit_scale fixed-point conversion is applied here). Written to BOTH ping-pong halves so it's correct from frame 0; for a STATIC field give it diffuse: 0, evaporate: 1 so it isn't smeared/decayed. No-op without a patch grid. Call after creation (and after any setConfig rebuild).

      Parameters

      Returns void

    • Read a patch field back to the CPU as a resolution × resolution grid (the AgentScript patches.exportDataSet — the measurement side of setPatchField). Returns row-major [z*res + x] values in field units (the deposit_scale fixed-point conversion is undone), reading the current agent-facing parity half. Async — copies the field block into a staging buffer, submits, and maps it; do NOT call every frame (it stalls on the GPU). Resolves to an empty array when the config has no patch grid.

      Use for plotting/measurement (population density, pheromone totals) or to snapshot a field for export.

      Parameters

      Returns Promise<Float32Array<ArrayBufferLike>>

    • Read the agent (particle) records back to the CPU — the turtle-snapshot side of the measurement layer (AgentScript's turtles accessor / model plotting). Returns a flat Float32Array of min(count, maxParticles) records, 16 floats each (the Particle struct): [0..2] position, [3] life (< 0 = dead slot — skip it when counting live agents), [4..6] velocity, [7] max_life, [8..11] color (color.a carries species/state in agent models), [12] size, [13] rotation (heading, or energy in lotka), [14] flags, [15] pad.

      Async and synchronizing — for measurement/plotting, not per-frame use. Pass count to read only the first N slots (e.g. the seeded population in a reproduction model); defaults to the full capacity.

      Parameters

      Returns Promise<Float32Array<ArrayBufferLike>>

    • Set the world transform applied to every rendered particle (default identity). A rigid + uniform-scale Mat4 mapping the sim's local space into world space — used to place a local agent/particle sim on the geospatial globe (the ENU tangent-plane transform at a lat/lon) and follow floating- origin reanchors without re-simulating. Picked up on the next update(). No effect on the deferred (gbuffer) sprite/mesh paths.

      Propagates to split children so an on-death burst (e.g. a rain splash) shares the parent's space — children spawn at the parent's death position in the same sim coordinates, so they must render through the same transform.

      Parameters

      Returns void

    • Upload the per-agent link topology (the link_springs modifier reads it). links is linksPerAgent i32 slots per agent (slot = linked particle index, < 0 = empty), laid out as [agent0 slot0..K-1, agent1 ...]. No-op when the config has no links. Call after creation and after any setConfig rebuild (the buffer is fresh each time).

      Parameters

      Returns void

    • Seed the initial population for a reproduction config: writes count live agents (each 16 floats / 64 bytes in the Particle layout: position, life, velocity, max_life, color, size, rotation, flags, trail_meta) into slots [0, count) and initializes the free-list with the remaining slots [count, maxParticles). Call once after the pass is created (and the emitter is typically disabled, spawnRate: 0). No-op without reproduction.

      Parameters

      Returns void

    • Writes only the heightmap uniform (origin xz / extent / resolution), leaving the data buffer untouched. For callers that bake the heights on GPU and only need to tell the collision shader where the heightmap is positioned in world space.

      Parameters

      Returns void

    • Updates the SDF's world transform (and uniform scale). The shader pulls world particle positions back into the SDF's local frame via transform's inverse before sampling, so this lets the host move/rotate/uniformly-scale the SDF without re-baking. No-op when the pass has no SDF bound.

      transform is a world matrix; the inverse is computed here and uploaded. scale (default 1) multiplies the sampled distance back into world units — pass the same uniform scale you used to build transform.

      Parameters

      Returns void

    • Insert the pass into graph for one frame. Implementations call graph.addPass(name, type, b => { ... }) exactly once and use the supplied PassBuilder to declare reads, writes, transient resources, and the execute callback.

      Parameters

      • graph: RenderGraph

        Graph being built this frame.

      • deps: ParticleDeps

        Pass-specific dependency record (handles, scene data, etc.).

      Returns ParticleOutputs

      Pass-specific output record (typically a set of handles downstream passes will consume).