API reference

Every public class, method, and event in @codexo/exojs. Generated from source.

C

classUpdateModule

@codexo/exojs-particles / particles / stable

Per-frame, per-batch mutator. Operates on the live particles through their named channels - typically a single tight loop over `[0, particles.count)` that reads and writes the channel arrays it needs. Implementations must always provide a CPU `apply()`. To make a module GPU-eligible (executed inside the system's composite compute shader on WebGPU backends), additionally implement wgsl and writeUniforms. Modules that declare a WgslContribution may also opt to declare a 1D texture binding via the `textures` field (used by `Curve` / `ColorGradient`-driven modules) - in which case uploadTextures runs once at compile time to upload the data. Implementation pattern (CPU-only module): ```ts class MyModule extends UpdateModule { apply(particles, dt) { const { x: velX, y: velY } = particles.velocity; for (let i = 0; i < particles.count; i++) { velX[i] *= 0.99; velY[i] *= 0.99; } } } ``` Implementation pattern (GPU-eligible module): ```ts class MyForce extends UpdateModule { constructor(public ax: number, public ay: number) { super(); } apply(particles, dt) { const { x: velX, y: velY } = particles.velocity; for (let i = 0; i < particles.count; i++) { velX[i] += this.ax * dt; velY[i] += this.ay * dt; } } wgsl(): WgslContribution { return { key: 'MyForce', uniforms: [{ name: 'ax', type: 'f32' }, { name: 'ay', type: 'f32' }], body: `velX[idx] += u_MyForce.ax * dt; velY[idx] += u_MyForce.ay * dt;`, }; } writeUniforms(view, offset) { view.setFloat32(offset + 0, this.ax, true); view.setFloat32(offset + 4, this.ay, true); } } ``` If *any* registered update module on a system lacks `wgsl()`, the system forces CPU mode regardless of backend - preserving the contract that `apply()` is always honoured. Built-in modules ship both implementations; custom modules can opt into GPU acceleration at their authors' discretion. Update modules run after integration each frame. Multiple modules execute in registration order; later modules see the effects of earlier ones.

0
props
5
methods
0
events
Import
import { UpdateModule } from '@codexo/exojs-particles'

Per-frame, per-batch mutator. Operates on the live particles through their named channels - typically a single tight loop over `[0, particles.count)` that reads and writes the channel arrays it needs.

Implementations must always provide a CPU `apply()`. To make a module GPU-eligible (executed inside the system's composite compute shader on WebGPU backends), additionally implement wgsl and writeUniforms. Modules that declare a WgslContribution may also opt to declare a 1D texture binding via the `textures` field (used by `Curve` / `ColorGradient`-driven modules) - in which case uploadTextures runs once at compile time to upload the data.

Implementation pattern (CPU-only module):

```ts class MyModule extends UpdateModule { apply(particles, dt) { const { x: velX, y: velY } = particles.velocity; for (let i = 0; i < particles.count; i++) { velX[i] *= 0.99; velY[i] *= 0.99; } } } ```

Implementation pattern (GPU-eligible module):

```ts class MyForce extends UpdateModule { constructor(public ax: number, public ay: number) { super(); }

apply(particles, dt) { const { x: velX, y: velY } = particles.velocity; for (let i = 0; i < particles.count; i++) { velX[i] += this.ax * dt; velY[i] += this.ay * dt; } }

wgsl(): WgslContribution { return { key: 'MyForce', uniforms: [{ name: 'ax', type: 'f32' }, { name: 'ay', type: 'f32' }], body: `velX[idx] += u_MyForce.ax * dt; velY[idx] += u_MyForce.ay * dt;`, }; }

writeUniforms(view, offset) { view.setFloat32(offset + 0, this.ax, true); view.setFloat32(offset + 4, this.ay, true); } } ```

If *any* registered update module on a system lacks `wgsl()`, the system forces CPU mode regardless of backend - preserving the contract that `apply()` is always honoured. Built-in modules ship both implementations; custom modules can opt into GPU acceleration at their authors' discretion.

Update modules run after integration each frame. Multiple modules execute in registration order; later modules see the effects of earlier ones.

Constructors1
new(): UpdateModule
Methods5
Mutates the live particles for one frame. Runs only on the CPU path: a system whose modules are all GPU-eligible executes wgsl bodies inside its compute shader instead, and never calls this.
destroy(): void
Optional cleanup hook called from ParticleSystem.destroy.
uploadTextures?(device: GPUDevice, textures: ReadonlyMap<string, GPUTexture>): void
Upload texture data (Curve/ColorGradient lookup tables) to the GPU at compile time. Receives the GPUDevice and a map of texture bindings keyed by the name in WgslContribution.textures. Called once after pipeline creation. Required when wgsl declares textures.
Override to declare a GPU contribution. Returning a WgslContribution makes this module GPU-eligible; omitting (or returning undefined) forces CPU mode for any system that uses this module.
writeUniforms?(view: DataView, byteOffset: number, dt: number): void
Write this module's current uniform values into the shared uniform buffer at byteOffset. Layout must match the field declarations returned by wgsl (in the same order). Receives the current frame dt (seconds). Modules tracking accumulated time (e.g. noise/turbulence) should advance their internal counter here to stay in sync when running in GPU mode (where apply is not called). Required when wgsl declares uniforms. Called every frame by the system before dispatching compute.
Source