The extraBits you pass; they type the custom attributes that
spawn and setParticle accept.
Creates a particle system; add it under a View3D's root to draw it
The extraBits you pass; they type the custom attributes that
spawn and setParticle accept.
What to override in defaultOptions.
A fixed local-space box measured in place of this container and its subtree, or null to
measure the geometry
Set one on a large subtree whose extent you already know, such as a level chunk, to skip walking
it. getLocalBounds and the size members read it. It's pixi's
boundsArea; it doesn't change culling.
ReadonlycapacityHow many particles the pool holds, fixed at construction
Child nodes
Their order doesn't decide what draws first. Read the array, but change it through addChild and removeChild. To visit the whole subtree, use traverse.
CSS cursor shown while this node is the pointer's target
Only the target's own cursor counts, as in 2D: a hit on a 'passive' child shows its
interactive ancestor's cursor, so set it on the node with the listeners. null shows the
View3D's own cursor. Any CSS cursor value works, url(...) included.
button.cursor = 'pointer';
handle.cursor = 'grab';
blade.cursor = 'url("crosshair.png") 8 8, crosshair'; // custom, with a hotspot
https://developer.mozilla.org/en-US/docs/Web/CSS/cursor MDN Cursor Documentation
ReadonlydataTyped-array views over the vertex buffer; see ParticleContainerViews
Whether destroy has run, as in pixi's Container
How this node takes part in pointer events, as on a pixi.js Container
'none': never picked, and neither is anything below it. The subtree costs nothing per
pointer event.'passive' (default): fires no listeners and is never the target. Under an interactive
ancestor it is still picked, and the hit goes to that ancestor with this node's surface
data. So one 'static' group makes its whole subtree clickable, with the group as target.'auto': as 'passive', but ray-tested even with no interactive ancestor, which costs time
and finds no target. Prefer 'passive'.'static': picked against its hitVolume, and fires
listeners.'dynamic': as 'static', and the View3D also picks again while a mouse or pen is
still, so a node that moves under it gets its enter and leave events.The renderer's eventMode option only sets the default for 2D containers, and the View warns
once when it isn't 'passive'. Picking costs time for each node that takes part, so set the
mode on the nodes and groups that need it.
Shape the pointer ray is tested against when picking this node, like hitArea in 2D
Setting it doesn't make the node interactive; eventMode
does that. Left null, a Mesh3D uses its geometry's bounding box and a plain
Container3D has no shape, so it only hears events from its children.
A shape you set also clips the node's descendants, as hitArea does in 2D: a descendant only
hits where the hit point is inside every such shape above it, whatever those nodes'
eventMode. A clipped hit doesn't block what is behind it. A Geometry3D clips by its bounding
box, an IHitVolume3D only through its optional containsPoint, and the default
bounding box never clips. A ray that misses a Box or Sphere shape, or a Geometry3D's
bounding box, skips the exact test of every descendant under it.
mesh.interactive = true; // picked by its bounding box
mesh.hitVolume = 'geometry'; // picked per triangle
mesh.hitVolume = new Sphere(center, 0.4); // a cheaper or tighter shape
mesh.hitVolume = null; // back to the bounding box
// Children of the porthole only pick inside its sphere
porthole.hitVolume = new Sphere(new Vector3(), 1);
HitVolume3DInput For what each accepted value resolves to.
Shorthand for eventMode, as on a pixi.js Container
true sets 'static' and false sets 'passive'. It reads true for 'static' and
'dynamic'. false doesn't stop picking: under an interactive ancestor, a 'passive' node is
still picked on that ancestor's behalf. Set eventMode = 'none' to take a node and its
subtree out of picking.
Whether this node's descendants can be picked, as on a pixi.js Container
false takes the whole subtree out of picking: descendants neither hit nor block what is
behind them, and cost nothing per pointer event. The node itself still picks by its own
eventMode and volume, so it can answer for the subtree.
menu.interactiveChildren = false; // nothing in the menu can be picked
menu.interactiveChildren = true; // every button picks again, eventMode intact
// One sphere answers for the whole robot: one ray test instead of one per mesh
robot.eventMode = 'static';
robot.hitVolume = new Sphere(new Vector3(), 2);
robot.interactiveChildren = false;
Name to find the node by, with getChildByLabel
Animation tracks find their target by it too. A plain Container3D starts with null;
built-in subclasses such as Mesh3D start with their class name.
Local transform matrix, built from the position, rotation, scale and origin
It catches up with changes in the view's transform pass, or when you call updateLocalTransform. Read it, but change the components instead: the next rebuild overwrites it.
Property-based handler for the click event
Fired when a mouse click on this node completes, with any button but the right one.
mesh.eventMode = 'static';
mesh.onclick = (e) => {
if (e.hit3D) marker.position.copyFrom(e.hit3D.point);
};
IFederatedContainer3D#onpointertap For the equivalent for every pointer type.
Property-based handler for the contextmenu event
Fired when the browser is about to open its context menu over this node; call
preventDefault() to keep it closed.
Property-based handler for the globalmousemove event
Fired on every mouse move, wherever the pointer is on the page.
IFederatedContainer3D#onglobalpointermove For the equivalent for every pointer type.
Property-based handler for the globalpointermove event
Fired on every pointer move on the page, whether or not the pointer is over this node. The
node still needs eventMode 'static' or 'dynamic' to hear it.
Property-based handler for the globaltouchmove event
Fired on every touch move, wherever the touch is on the page.
IFederatedContainer3D#onglobalpointermove For the equivalent for every pointer type.
Property-based handler for the mousedown event
Fired when a mouse button other than the right one goes down over this node.
IFederatedContainer3D#onpointerdown For the equivalent for every pointer type.
Property-based handler for the mouseenter event
Fired when the mouse enters this node. Doesn't bubble.
IFederatedContainer3D#onpointerenter For the equivalent for every pointer type.
Property-based handler for the mouseleave event
Fired when the mouse leaves this node. Doesn't bubble.
IFederatedContainer3D#onpointerleave For the equivalent for every pointer type.
Property-based handler for the mousemove event
Fired while the mouse moves across this node.
IFederatedContainer3D#onpointermove For the equivalent for every pointer type.
Property-based handler for the mouseout event
Fired when the mouse moves off this node. Bubbles, unlike mouseleave.
IFederatedContainer3D#onpointerout For the equivalent for every pointer type.
Property-based handler for the mouseover event
Fired when the mouse moves onto this node. Bubbles, unlike mouseenter.
// One handler on the shelf hears every item on it
shelf.onmouseover = (e) => highlight(e.target3D);
IFederatedContainer3D#onpointerover For the equivalent for every pointer type.
Property-based handler for the mouseup event
Fired when a mouse button other than the right one is released over this node.
IFederatedContainer3D#onpointerup For the equivalent for every pointer type.
Property-based handler for the mouseupoutside event
Fired when a mouse button that went down on this node is released anywhere else.
IFederatedContainer3D#onpointerupoutside For the equivalent for every pointer type.
Property-based handler for the pointercancel event
Never called: pixi delivers no pointer cancellation, in 2D either.
Property-based handler for the pointerdown event
Fired when a pointer goes down on this node: mouse, touch or pen alike.
Property-based handler for the pointerenter event
Fired when a pointer enters this node. Doesn't bubble, so an ancestor hears it only when the pointer enters the ancestor itself.
Property-based handler for the pointerleave event
Fired when a pointer leaves this node. Doesn't bubble.
Property-based handler for the pointermove event
Fired while a pointer moves across this node.
Property-based handler for the pointerout event
Fired when a pointer moves off this node. Bubbles, unlike pointerleave.
Property-based handler for the pointerover event
Fired when a pointer moves onto this node. Bubbles, unlike pointerenter.
Property-based handler for the pointertap event
Fired when a pointer completes a tap on this node, for any pointer type and any button, right clicks included.
Property-based handler for the pointerup event
Fired when a pointer is released over this node.
Property-based handler for the pointerupoutside event
Fired when a pointer that went down on this node is released anywhere else. The event's
target3D is the node that was pressed, and hit3D is what the pointer was released over.
Property-based handler for the rightclick event
Fired when a right click completes on this node.
Property-based handler for the rightdown event
Fired when the right mouse button goes down over this node.
Property-based handler for the rightup event
Fired when the right mouse button is released over this node.
Property-based handler for the rightupoutside event
Fired when the right mouse button that went down on this node is released anywhere else.
Property-based handler for the tap event
Fired when a touch completes a tap on this node. Chrome gives each touch a new pointerId, and
detail only counts repeat taps by the same one, so it stays 1 there; time a double tap yourself.
let lastTap = 0;
mesh.ontap = (e) => {
if (e.timeStamp - lastTap < 300) focusOn(mesh); // double tap
lastTap = e.timeStamp;
};
IFederatedContainer3D#onpointertap For the equivalent for every pointer type.
Property-based handler for the touchcancel event
Never called: pixi delivers no touch cancellation, in 2D either.
Property-based handler for the touchend event
Fired when a touch lifts off this node.
IFederatedContainer3D#onpointerup For the equivalent for every pointer type.
Property-based handler for the touchendoutside event
Fired when a touch that started on this node lifts off anywhere else.
IFederatedContainer3D#onpointerupoutside For the equivalent for every pointer type.
Property-based handler for the touchmove event
Fired while a touch moves across this node.
canvasMesh.hitVolume = 'geometry'; // per triangle, so hits carry a uv
canvasMesh.ontouchmove = (e) => {
if (e.hit3D) paintAt(e.hit3D.uv);
};
IFederatedContainer3D#onpointermove For the equivalent for every pointer type.
Property-based handler for the touchstart event
Fired when a touch lands on this node.
IFederatedContainer3D#onpointerdown For the equivalent for every pointer type.
Called at the end of each update with a step above 0, playing or not, for effects the options don't cover
Write particles with setParticle, or through
data and markDirty;
the update uploads them after this returns. A particle written from scratch needs aBirth and
aLife too, or it won't draw.
Property-based handler for the wheel event
Fired when the wheel turns while the pointer is over this node.
Parent node, or null for a node with none, such as a view's root
Whether this mesh is shadowed by lights that cast shadows
Only lit materials take shadows. After changing it at runtime, call invalidate.
Where particles start and which way they head; swap it at any time
Optional ReadonlyskeletonSkeleton that deforms this mesh; undefined for a mesh that doesn't bend
Fixed at construction: to change it, build a new mesh.
ReadonlyspaceWhether particle positions are in world space or this node's, fixed at construction
ReadonlytexturesThe flipbook frames, in frame order; one entry for a single sprite
A ParticleSystem3D with frameMode 'animate' or 'overLife' holds one texture over the
whole sheet here instead.
Readonly AdvanceduidUnique id, assigned at construction
World transform: the parent's world transform times this node's localTransform
The view updates it once per frame, before drawing, for visible nodes only, and not at all while the view holds no mesh. So it can be out of date after a change this frame or while the node or an ancestor is hidden, and a node outside any view keeps the identity matrix. getGlobalTransform always works out a current one.
StaticdefaultDefaults for every new ParticleSystem3D; an option passed as undefined keeps its default
A shape set here is one object shared by every system that doesn't pass its own, so editing
its fields on one system edits them all.
rotation in degrees, as in pixi.js
It reads and writes rotation, so the two always agree. Reading converts back from radians, so
a value can come back a hair off, such as 30 as 29.999999999999996; compare with a tolerance.
Sets the Euler rotation and makes it the rotation in use, even when the values are unchanged
The new Euler angles, in degrees
Whether update runs from Ticker.shared every frame
It runs after Ticker.shared callbacks at the default priority, so particles spawn where those
left the emitter. An Application renders from its own ticker unless built with
sharedTicker: true, so new particles can show a frame late. Turn this off and call update
from app.ticker to avoid that, or to step the system from a loop of your own.
Turns automatic updates on or off
Whether to run update() every frame.
Always 'none'; particles face the camera through the billboard option instead
How particles blend over the scene; see ParticleBlendMode
Ignored unless alphaMode is 'blend'. A change rebuilds the draw state, so prefer setting it
once at construction. Fog reaches the particles only if the blend mode was 'normal' at
construction; a later change doesn't turn it on or off.
Sets the blend mode
How particles blend over the scene.
This mesh's bounding Sphere in world space, large enough for morph weights from 0 to 1
Cached until the world transform or geometry changes, so reading it often is cheap. It follows
worldTransform, so it can be out of date after a change
this frame. Dynamic geometry gives an empty sphere (radius < 0). The sphere is shared: don't
change it, and clone() it to keep a copy.
Sets whether the mesh casts shadows, from the next render
Whether the mesh casts shadows.
Depth along local z: |scale.z| × local bounds depth
Assigning writes scale.z only; see width.
Scales along z so the depth becomes value
Target depth along z
How fast velocity dies away, or null for none; ParticleSystem3DOptions.drag has the
scale
A change reshapes live particles' paths, as a change to gravity does.
Sets the drag
The drag, or null for none.
Sets the emission rate
Particles per second.
Sets the flipbook rate
Frames per second.
The geometry this mesh draws; Geometry3D.EMPTY until it's given one
Swaps the geometry, refitting a hitVolume given as 'box' or 'geometry'
A geometry with as many morph targets as there are Mesh3D#weights keeps them; one with
a different count gets new weights, all 0; one with none leaves weights undefined.
Geometry to draw.
Constant acceleration, or null for none; ParticleSystem3DOptions.gravity has the units
A change reshapes every live particle's whole path, as if the new value had held since its birth, so a big change makes particles jump. Assign a new value to change it; editing the returned vector doesn't reach the particles.
Sets the acceleration
A vector, a number for a pull straight down, or null for none.
Height along local y: |scale.y| × local bounds height
Assigning writes scale.y only; see width.
Scales along y so the height becomes value
Target height along y
The material this mesh draws with; BaseMaterial3D.EMPTY until it's given one
Many meshes can draw one material, and a value written to it shows on all of them. A
Model3D's meshes draw its source's materials, shared with every model built from that
source; Model3D#materials gives one model copies of its own. For one mesh alone, assign
mesh.material.clone({ baseColor: 0xff0000 }), and destroy the copy when you're done with it.
Swaps the material
Material to draw the geometry with.
Point in local space that rotation and scale happen around, as in pixi.js
Unlike a pivot, it leaves an unrotated, unscaled node where it is: the origin sits at
position + origin in the parent. Assigning copies the values in, and a single number sets
all three axes.
Sets the origin; a number sets all three axes
The new origin, in local space
Local position
Assigning copies the values in; the object itself never changes.
Local rotation as a unit quaternion; see rotation for which of the two is in use
Assigning copies the values in, so node.quaternion = other.quaternion doesn't link the two.
Sets the quaternion and makes it the rotation in use, even when the values are unchanged
The new rotation, as a unit quaternion
Advanced
The RenderPassBit flags of the passes that draw this mesh: its material's passes, plus
SHADOW while it casts shadows, or none while it holds Geometry3D.EMPTY or
BaseMaterial3D.EMPTY
The mesh's own Mesh3D#enablePass and Mesh3D#disablePass win over its material's, and a blended or transmissive material casts no shadow.
Local rotation as Euler angles in radians: turns around Z, then Y, then X, each about the parent's axes
The node keeps both this and quaternion, and whichever you
set last is the rotation in use. Assigning copies the values in. Writing unchanged values to
either through a component, set or copyFrom doesn't switch which one is in use; assign it
whole.
Sets the Euler rotation and makes it the rotation in use, even when the values are unchanged
The new Euler angles, in radians
Local scale
Assigning copies the values in, and a single number scales all three axes; the object itself never changes.
Sets the local scale; a number sets all three axes
The new scale
The system clock in seconds, which particle ages are measured from
It advances with each update, playing or not, and isn't the burst timeline that gotoAndPlay moves. Assign it to scrub, backwards too: the particles still in the pool show as they would at that time, and nothing is emitted.
Sets the clock
Clock time in seconds.
The uniforms the composed bits declare in their material bindings, by name
Assigning one uploads it, so particles.uniforms.uParticleTime = t is a whole per-frame update.
A vector takes an array, such as uGravity = [0, -9.8, 0]; a { x, y, z } object is silently
ignored. A vector reads back as a Float32Array, and writing one of its elements isn't
uploaded until you call particles.material.update().
The View3D this node is in, or null when it isn't in a scene
Whether this container and its descendants draw
Hiding is cheap, and a hidden node stays in the scene; to take it out, remove it with removeChild. Emits visibleChanged when the value changes.
Shows or hides this container and its descendants
Whether they draw
Morph target weights, one per target; undefined when the geometry has no morph targets
Change its values at any time rather than assigning a new array: a playing animation keeps writing the old one, and the parts a model node's mesh splits into share one array, so a new array cuts this mesh loose from both.
Replaces the weights array; does nothing when the geometry has no morph targets or value is
undefined
New weights, one per morph target.
Width along local x: |scale.x| × local bounds width
Assigning writes scale.x only. To set several axes, setSize
measures the bounds once instead of once per axis.
Scales along x so the width becomes value
Target width along x
1 when this node and every ancestor are visible, otherwise 0
The view works it out once per frame, so it lags a visible change until the next render.
Sets position.x
The new x position
Sets position.y
The new y position
Sets position.z
The new z position
Adds one or more children to the end of this container's child list
A child with another parent leaves it first. A child that is already here moves to the end, without events.
The children to add
The first added child
Adds child at index, or moves it there when it is already a child of this container
A move within this container emits no events.
The child to add or move
The destination index
The added child
Kills every particle, from the next update on
Emission and the burst timeline carry on; gotoAndPlay(0) restarts the timeline too.
Stops updating and destroys the system; options works as for
ParticleContainer3D.destroy
Optionaloptions: Destroy3DOptions
Teardown flags; see Destroy3DOptions.
Takes this mesh out of a render pass, whatever its material says
The mesh leaves the pass on the next render, and other meshes sharing the material stay in it.
disablePass('opaque') draws nothing of the mesh while it still casts its shadow. Only the
named pass is left, so a material that later turns 'blend' brings the mesh into the
transparent pass. Mesh3D#enablePass undoes it. Does nothing for a pass name nothing
has used yet.
The pass's name, such as 'opaque'.
Adds this mesh to a render pass, whatever its material says
BaseMaterial3D#enablePass for one mesh: the pass draws this mesh from the next render,
and other meshes sharing the material don't follow. It undoes this mesh's own disablePass
for the pass. 'shadow' is the same as setting castShadow.
The pass's name, such as 'outline'.
Gets the child at index
Index of the child to fetch
The child at index
Returns the first child whose label matches, or null
Each container checks its direct children before searching inside them. An unlabelled node never matches, even a pattern.
Exact label, or a pattern to test labels against
Whether to search the whole subtree, not only direct children
The first match, or null when nothing matches
Gets the index of child within this container
The child to look up
The child's index
Collects every child whose label matches, in the order Container3D.getChildByLabel visits them
Exact label, or a pattern to test labels against
Whether to search the whole subtree, not only direct children
Array the matches are appended to; a new one when omitted
out
Returns this container's position in world space: parent.toGlobal(this.position), or a copy
of position with no parent
Point the result is written into. Defaults to a new Vector3.
true to use the parent's cached world transform (see
Container3D.getGlobalTransform); this node's own position is always read as it stands.
Works out this container's current world transform into out
It walks up the parent chain, so the result is right even before the view's transform pass
has run this frame. With skipUpdate it copies the cached
worldTransform instead, which is cheaper but can be stale.
Matrix the result is written into. Defaults to a new Matrix4.
true to copy the cached world transform instead of recomputing.
Measures the bounding box of this container and its descendants, in this container's local space
A subtree with a boundsVolume counts as that box. Hidden descendants are left out; this container counts whether or not it is visible. An empty subtree measures as a zero box at the origin. Each call walks the subtree, so cache the result if you need it every frame.
Box to write into; a new one when omitted
out
Moves the burst timeline to time and plays from there
Bursts due before time count as spent, and a repeating one picks up at its next repeat.
gotoAndPlay(0) restarts the effect, drawing from a fresh
random stream. Live particles, and the
clock they're drawn at, don't change.
Seconds into the burst timeline.
Moves the burst timeline to time and stops there; gotoAndPlay
says what the move changes
Seconds into the burst timeline.
Makes the mesh rebuild its shader and draw state on the next frame
Assigning geometry, material or billboardMode does this for you, and so do most material
changes; BaseMaterial3D lists the ones that need this call. Call it too after changing
receiveShadow. It doesn't re-read vertex data edited in place;
call Geometry3D.unload for that.
Turns this node so its forward axis, local +Z, points at a world-space target
Cameras and lights aim local -Z instead. The node aims from position + origin, and uses the
parent's current world transform, so a move earlier in the frame counts.
World-space point to face
World-space up reference; defaults to (0, 1, 0)
Marks particles lo to hi, inclusive, for the next upload
Only needed after writing through data directly; the setters mark what they write. The upload is one range spanning everything marked, so two far-apart particles send all the slots between them. A range given the wrong way round marks the whole pool, and one past either end is clamped to it.
First particle in the range.
Last particle in the range, inclusive.
Resumes emitting, and the burst timeline, from where stop left them
Removes one or more children from this container; a node that isn't a child is ignored
The children to remove
The first child passed in
Removes the child at index
Index of the child to remove
The removed child
Removes the children from beginIndex up to, but not including, endIndex
First index to remove
OptionalendIndex: number
End of the range, exclusive; defaults to the child count
The removed children, last child first
Moves one or more nodes under this container without moving them in the world; see reparentChildAt
The children to reparent
The first reparented child
Moves child under this container at index without moving it in the world
Its local position, rotation and scale change so that it renders where it did, and it keeps its origin. Unlike pixi, it uses current world transforms, so a move earlier in the frame counts. A child that is already here only changes index.
The child to reparent
The destination index
The reparented child
Replaces oldChild with newChild at the same index, copying oldChild's local position,
rotation and scale onto newChild
newChild keeps its own origin, and its position is solved so it
sits exactly where oldChild did.
Moves an existing child to index within this container
The child to move
The destination index
Advanced
Writes any of a particle's attributes by name, the system's own ParticleSystemValues included; see ParticleContainer3D.setParticle
Slot to write, 0 to capacity - 1.
Attribute name to value. An undeclared name throws.
Writes one particle, to go out with the next upload
Positions are in world space unless the container was built with space: 'local'. A size
of 0 empties the slot. To write many particles with one tint, writePacked skips
packing the colour on every call.
Slot to write, 0 to capacity - 1.
Particle centre x.
Particle centre y.
Particle centre z.
World-space diameter.
Spin in the quad's plane, in radians.
0xRRGGBB tint, in display (sRGB) space.
Opacity, 0 to 1.
Flipbook frame index, wrapping past the last frame; ignored with one frame.
Rescales this container so its size matches the given width, height and depth
A missing height or depth takes the width. An axis whose local extent is zero, such as a
flat plane's depth, keeps a unit scale. The sign of each scale axis is kept, so a mirrored node
stays mirrored.
Emits count particles right now, whether or not the system is
playing
Slots are reused in spawn order, so once all are used a new particle replaces the oldest, even
if it's still alive. A count over the capacity spawns the capacity. The new particles upload
with the next update that has a step above 0.
How many to emit.
Optionaloverrides: ParticleSpawnOverrides<B>
Values for this batch in place of the system's options.
Stops emitting and freezes the burst timeline where it is
Live particles carry on until their lifetimes run out. clear removes them at once, and turning off autoUpdate freezes them in place.
Swaps the places of two children in this container's list
Converts a point from this container's local space to world space
Pass the result to View3D.worldToScreen to go on to 2D screen coordinates.
The local-space point to convert.
Optionalout: T
Point the result is written into. Defaults to a new Vector3.
true to use the cached world transform (see Container3D.getGlobalTransform).
Container3D.getGlobalPosition For this container's own world position.
Converts a point into this container's local space
The point to convert.
Optionalfrom: Container3D
Container whose local space position is in. Defaults to world space.
Optionalout: T
Point the result is written into. Defaults to a new Vector3.
true to use cached world transforms (see Container3D.getGlobalTransform).
Calls callback with this container, then with every container under it, depth first
Each container comes before its children, and hidden ones are visited too. A Skeleton's bones and a BatchedMesh3D's items aren't containers, so the walk doesn't reach them. It can't stop early or skip a subtree.
The callback may remove, destroy or replace the container it's given. A container it adds with addChild is visited only if its new parent hasn't been visited yet. Other changes to the tree during the walk can skip a container or visit one twice.
Called once with each container, this one first
Unloads this mesh's geometry now
The vertex data stays on the CPU, so the next frame that draws the mesh uploads it again. Remove the mesh from the scene first, or that happens straight away. The material is left alone, since it's usually shared: call BaseMaterial3D.unload for that, or Model3D.unload to free a model's geometry and textures together.
view.root.removeChild(mesh);
mesh.unload(); // adding it back re-uploads and re-packs the geometry
Moves the clock on by one step, emits what's due and uploads what was born
Runs every frame while autoUpdate is on; call it yourself
otherwise. A fixed-step loop keeps a Ticker of its own and sets its deltaMS before each call.
Optionalticker: Ticker
Supplies the step as its deltaMS, capped at a tenth of a second. Omitted, the
step is one 60 fps frame.
Advanced
Rebuilds localTransform from the position, rotation, scale and origin
The view calls it for each node that changed, so you only need it to read a current
localTransform before the next frame. When rotation is the
rotation in use, it updates the quaternion to match.
Sends the particles written since the last upload to the GPU; call it after each frame's writes
setParticleAt with a colour already packed by packParticleColor
Use it when a tint is fixed, or changes less often than you write particles: pack it once, then write many.
Slot to write, 0 to capacity - 1.
Particle centre x.
Particle centre y.
Particle centre z.
World-space diameter.
Spin in the quad's plane, in radians.
Tint and opacity as packParticleColor returns them.
Flipbook frame index, wrapping past the last frame; ignored with one frame.
A particle system with the movement built in: emission, lifetimes, spreads, forces and over-life ramps, all from one options object
A particle is written once, at birth, and the GPU works out where it is every frame after that. So the CPU only pays for the particles born each frame, whatever the pool size.
spin,sizeEnd,alphaEnd,colorEndand a multi-frametextureeach add GPU work, so set only what an effect needs.Rendering, capacity and blending come from ParticleContainer3D, which this extends. Drop to that layer when you want to move particles yourself.
Example
See
ParticleSystem3DOptions For the constructor options.