Its positions are corner offsets, not object-space positions: a backend
multiplies corner.xy by the per-instance size and adds it to the projected
centre, which is what makes the quads screen-aligned. Counter-clockwise seen
from +Z, matching planeGeometry and §7a.
Non-indexed on purpose (decision, WP-9.3): six vertices of a shared quad cost
nothing next to the instance stream, and drawArraysInstanced avoids putting
an element buffer into every particle vertex array.
Created on first use rather than at module load, so importing @fourjs/render
does not consume a geometry id or allocate a buffer for an application with no
particles. Never disposed: it is process-wide shared state, and disposing it
would empty the quad under every particle system at once (§83 — the creator
owns disposal, and the creator here is the module).
The per-instance mesh, lazily created and shared by every particle item: a unit quad centred on the origin, six vertices, no indices.
Its positions are corner offsets, not object-space positions: a backend multiplies
corner.xyby the per-instance size and adds it to the projected centre, which is what makes the quads screen-aligned. Counter-clockwise seen from +Z, matchingplaneGeometryand §7a.Non-indexed on purpose (decision, WP-9.3): six vertices of a shared quad cost nothing next to the instance stream, and
drawArraysInstancedavoids putting an element buffer into every particle vertex array.Created on first use rather than at module load, so importing
@fourjs/renderdoes not consume a geometry id or allocate a buffer for an application with no particles. Never disposed: it is process-wide shared state, and disposing it would empty the quad under every particle system at once (§83 — the creator owns disposal, and the creator here is the module).