API reference

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

C

classMeshParticles

@codexo/exojs-particles / particles / stable

One caller-supplied mesh per particle, drawn as a single instanced draw. The cheap counterpart to `RibbonParticles`: the relationship stays one particle, one instance, and the per-instance data is byte-identical to `QuadParticles`'s - instanceAttributes, filled by the same writer. Only the shape changes. That is what makes this mode **GPU-eligible** without touching the compute pipeline: the pipeline emits precisely that layout, so a system on the GPU path binds its instance buffer directly and never calls build. **The mesh rides in its own vertex buffer**, alongside the per-instance one. The shader is fixed and shared, so any number of `MeshParticles` compile one program per backend regardless of how many distinct shapes they draw, and a mesh is limited only by what a vertex buffer holds. **Mutating the mesh works.** Its vertices are read into a normalised `(x, y, u, v)` table - the shader binds fixed names, a caller's geometry may use any - and re-read whenever the geometry's `version` changes. Edit the geometry in place, call `invalidate()` on it, and the next draw picks it up. Changing the vertex *count* is equally fine. **Atlas frames still work.** The mesh's own UVs are treated exactly like the quad's 0..1 corners: the shader mixes them across the particle's resolved frame (`uv = mix(uvMin, uvMax, meshUV)`), so `system.frames` plus a per-particle `textureIndex` selects a frame the same way. A geometry with **no texcoord attribute** therefore carries UV `(0, 0)` on every vertex and the mix degenerates to `uvMin` - the whole mesh samples the single texel at the frame's top-left corner, which on the default 1×1 white texture is exactly "untextured, tinted by the particle's `color`". **Sizing is the mesh's own.** Unlike the quad, which derives its footprint from the texture frame, a mesh particle's footprint is whatever its vertex positions say, in system-local units, multiplied by the per-particle `scaleX`/`scaleY`. The texture only supplies colour.

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

One caller-supplied mesh per particle, drawn as a single instanced draw.

The cheap counterpart to `RibbonParticles`: the relationship stays one particle, one instance, and the per-instance data is byte-identical to `QuadParticles`'s - instanceAttributes, filled by the same writer. Only the shape changes. That is what makes this mode **GPU-eligible** without touching the compute pipeline: the pipeline emits precisely that layout, so a system on the GPU path binds its instance buffer directly and never calls build.

**The mesh rides in its own vertex buffer**, alongside the per-instance one. The shader is fixed and shared, so any number of `MeshParticles` compile one program per backend regardless of how many distinct shapes they draw, and a mesh is limited only by what a vertex buffer holds.

**Mutating the mesh works.** Its vertices are read into a normalised `(x, y, u, v)` table - the shader binds fixed names, a caller's geometry may use any - and re-read whenever the geometry's `version` changes. Edit the geometry in place, call `invalidate()` on it, and the next draw picks it up. Changing the vertex *count* is equally fine.

**Atlas frames still work.** The mesh's own UVs are treated exactly like the quad's 0..1 corners: the shader mixes them across the particle's resolved frame (`uv = mix(uvMin, uvMax, meshUV)`), so `system.frames` plus a per-particle `textureIndex` selects a frame the same way. A geometry with **no texcoord attribute** therefore carries UV `(0, 0)` on every vertex and the mix degenerates to `uvMin` - the whole mesh samples the single texel at the frame's top-left corner, which on the default 1×1 white texture is exactly "untextured, tinted by the particle's `color`".

**Sizing is the mesh's own.** Unlike the quad, which derives its footprint from the texture frame, a mesh particle's footprint is whatever its vertex positions say, in system-local units, multiplied by the per-particle `scaleX`/`scaleY`. The texture only supplies colour.

Constructors1
Methods5
_ensureCapacity(byteLength: number): void
Grow the scratch buffer to hold at least byteLength. Grow-only: a shrinking particle count reuses the larger buffer rather than reallocating, matching the renderers' existing buffer policy.
_onBufferGrown(data: ArrayBuffer): void
Re-create typed-array views after _ensureCapacity reallocates.
_setCount(count: number): void
Record the element count produced by a build.
Fill the scratch buffer from the system's live particles. particles is the simulation's own channel storage, handed in rather than read off the system: a render mode is the one consumer that legitimately works in bulk, and it runs at the point in the frame where those values are the ones being drawn.
destroy(): void
Optional cleanup, called from ParticleSystem.destroy.
Properties8
gpuEligible: true
Whether this mode can run while the system is in GPU compute mode. Mirrors UpdateModule.wgsl(): a mode that cannot forces the whole system onto the CPU path, silently and observably via ParticleSystem.gpuMode. A GPU-eligible mode's layout must match what the compute pipeline emits into gpuState.instanceBuffer - the shared 40-byte per-instance layout (instanceAttributes). QuadParticles and MeshParticles both declare exactly that layout and differ only in the shape they expand it into, which is why both are eligible without the compute shader knowing either.
instanced: true
Draw model. true issues an instanced draw, false a plain draw over the built vertex buffer. Declared here because a layout carries topology but has no instancing concept.
The geometry this mode was constructed with - the shape one particle draws. Owned by the caller: destroy leaves it alone, so one mesh can back several modes.
The normalised mesh the executors bind as the per-vertex buffer: the caller's mesh reduced to (x, y, u, v) per vertex, keeping its topology and index list. Owned by this mode and disposed with it.
count: number
Element count of the draw call this mode's last build produced. Draw-model relative: instance count when instanced, vertex count otherwise. Do not assume one meaning.
data: ArrayBuffer
The buffer the renderer uploads. Valid until the next build.
Source