Skip to content
v0.1.0
IntroductionMeet the engine, its two packages, and the requirements for running GPU particles.Quick startCreate an effect, bind its artwork, and add particles to your Pixi stage.Configuration guideUnderstand effect fields, defaults, and their live experiments.Pixi textures & animationBind artwork and configure flipbooks in the Pixi integration.How effects workUnderstand emitters, coordinate spaces, playback, and the simulation lifecycle.CurvesShape properties over time and understand the clocks and units behind each value.DevelopmentSet up the repository, run the site and examples, and check your changes.Particle architectureUnderstand shader generation, particle storage, and resource ownership.OverviewAPI reference@reparticle/coreAPI referenceCurveAPI referenceCURVE_SEGMENTSAPI referenceCurvePointAPI referenceEffectConfigAPI referenceeffectConfigSchemaAPI referenceEffectInputAPI referenceEffectTransformAPI referenceEmitterAPI referenceEmitterConfigAPI referenceemitterConfigSchemaAPI referenceEmitterContextAPI referenceEmitterInputAPI referenceEmitterParametersAPI referenceEmitterPlaybackAPI referenceEmitterStateAPI referenceEmitterStateChangeAPI referenceEmitterStateListenerAPI referenceModifierConfigAPI referenceparseEffectConfigAPI referenceParticleBlendModeAPI referenceParticleLifetimeVisitorAPI referenceParticleSlotsAPI referenceParticleTintAPI referenceprewarmAPI referencepropertyVariationAPI referenceRenderingConfigAPI referenceRenderingInputAPI referencerenderingSchemaAPI referencesampleCurveAPI referenceSampledCurveAPI referenceScalarPropertyAPI referenceSpawnRateAPI referenceSpawnScheduleAPI referenceStopOptionsAPI referenceTransformAPI reference@reparticle/pixiAPI referenceAnimationFramesAPI referenceAnimationPlaybackAPI referenceAnimationSizeAPI referenceEffectInputAPI referenceEmitterParametersAPI referenceParticleBlendModeAPI referenceParticleEffectAPI referenceParticleEffectOptionsAPI referenceParticlePivotAPI referenceParticleRenderingAPI referenceParticleSizeModeAPI referenceParticleStateChangeAPI referenceParticleStateListenerAPI referenceParticleTextureAPI referenceParticleTintAPI referenceRenderingConfigAPI referencevalidateAnimationFramesAPI referenceEmitter: IdUnique emitter identifier within this effect. Use it to look up the emitter and bind its artwork. Renaming it does not change motion.Emitter: CapacityMaximum simultaneous particles for this emitter. When all slots are occupied, excess births are dropped and living particles are preserved. Try 64 to see the stream run out of free slots.Emitter: SeedDeterministic random seed. The same definition and playback steps reproduce the same variation. Changing the seed changes the pattern, not the configured ranges.Playback: PlaybackEmission cycle mode, duration, and duration spread. Once emits for one cycle; loop repeats. Restart to observe randomized cycle timing.Playback: Start DelayDelay before emission starts, with random variation around that delay. Restart to observe the timing.Playback: Start OffsetPrewarm the effect by advancing simulation before displaying its first frame. This performs real simulation work in fixed 1/60-second steps. Compare zero with two seconds.Transform: TransformEmitter position, rotation, and uniform scale relative to the effect. Adjust these together to place and size the emitter.Transform: SpaceWorld particles stay behind when the effect moves. Local particles follow its transform. The experiment moves the whole effect so the difference is visible.Transform: Inherit VelocityAmount of emitter movement velocity added to newborn particles. Zero adds none; one inherits the full measured velocity. Existing particles keep their own motion.Appearance: OrientationChoose fixed rotation, alignment with the initial direction, alignment with current movement, or integrated angular velocity. The rectangular artwork makes the orientation visible.Appearance: Stretch With VelocityScale Y stretch by particle speed, using a fixed 60 FPS shutter factor. It needs nonzero stretchY; it does not stretch particles by itself.Emission: RateBirths requested per second and their random rate spread. Capacity limits how many particles can stay alive. Changing spread restarts playback; numeric rate changes apply live.Emission: ShapeSpawn from a point, a filled circle, a box, or a 2D cone. Each shape has its own valid fields. Change the JSON type and dimensions together.Emission: Shape typeSelect the shape. Point has no dimensions; circle uses diameter; box and cone2d use width and height. The preview supplies dimensions for the selected shape.Emission: Shape diameterCircle diameter and its random variation. Births sample the filled circle; each dimension accepts a constant or an emitter-lifetime curve.Initial properties: DirectionPoint-emitter direction and the full angular spread around it, in radians. Zero spread produces a straight stream; 2π distributes directions all around.Rendering: RenderingBlend mode controls how particles combine with the scene: normal, add, multiply, or screen. Tint applies emitter-wide red, green, blue, and alpha multipliers. One leaves a channel unchanged; zero removes it. Changes affect existing particles immediately.Effect: VersionConfiguration format version. The current schema accepts only 1. This is a compatibility marker, not a visual setting.Effect: EmittersNonempty list of emitters. Each must have a unique ID, capacity, seed, emission settings, and required initial values. Add another emitter to combine effects.Emission: Shape dimensionsWidth and height of a box or cone emitter, with independent spread for each dimension. Constants and emitter-lifetime curves are supported. This experiment uses a box.Initial properties: LifetimeSeconds each particle remains alive. Longer lifetimes require more capacity at the same emission rate. Accepts a number or a curve sampled at birth using normalized emitter lifetime. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Initial properties: SpeedInitial velocity magnitude. Changing it affects new particles; modifiers change velocity afterward. Accepts a number or a curve sampled at birth using normalized emitter lifetime. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Initial properties: SizeParticle size in manual texture sizing mode. Initial size is multiplied by overLifetime.scale. Accepts a number or a curve sampled at birth using normalized emitter lifetime. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Initial properties: RotationInitial particle rotation. Positive angles turn counterclockwise. It is added to orientation and lifetime rotation. Accepts a number or a curve sampled at birth using normalized emitter lifetime. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Initial properties: Angular VelocitySpin speed used by angular-velocity orientation. Integrated over simulation time. Accepts a number or a curve sampled at birth using normalized emitter lifetime. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Initial properties: StretchAdditional horizontal and vertical stretch at birth. Zero keeps the original dimension; one doubles it. Each axis accepts a number or an emitter-lifetime curve. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Initial properties: ColorBirth color as red, green, and blue channels from 0 to 1. Each channel accepts a number or an emitter-lifetime curve. Lifetime color and rendering tint multiply this color afterward. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Initial properties: AlphaInitial opacity, multiplied by lifetime alpha, emitter tint, and display-object alpha. Accepts a number or a curve sampled at birth using normalized emitter lifetime. Spread adds independent random variation around each birth value. Zero keeps that value unchanged.Over lifetime: ScaleMultiplies the particle’s initial size. A number stays constant; a curve follows each particle from birth at time 0 to expiration at time 1.Over lifetime: StretchHorizontal and vertical stretch added to birth stretch as particles age. Constants and particle-lifetime curves are supported.Over lifetime: RotationAdded to the particle’s initial rotation. A number stays constant; a curve follows each particle from birth at time 0 to expiration at time 1.Over lifetime: Angular VelocityMultiplies the particle’s initial angularVelocity. A number stays constant; a curve follows each particle from birth at time 0 to expiration at time 1.Over lifetime: ColorRed, green, and blue multipliers over each particle’s lifetime. Use curves to change color from birth at time 0 to expiration at time 1.Over lifetime: AlphaMultiplies the particle’s initial alpha. A number stays constant; a curve follows each particle from birth at time 0 to expiration at time 1.Modifiers: AccelerationConstant force along the rotated local up direction. Changes velocity every simulation step.Modifiers: DragVelocity damping. Positive strength slows particles; directional mode damps only the selected axis.Modifiers: RadialForce away from a center, with distance falloff. Negative magnitude attracts particles.Modifiers: VortexTangential force around a center, with distance falloff. Change the sign to reverse circulation.Curves: CurvesShape particle opacity over its lifetime. Edit point times, values, and tangents, then apply the curve to the preview. Time runs from birth (0) to expiration (1). A tangent controls the slope through a point.Artwork: Size ModeManual uses initial particle size. Auto uses texture-frame dimensions and treats initial size as a multiplier. The same numeric size therefore has a very different effect.Artwork: FlipMirror artwork horizontally, vertically, or both, without changing particle motion.Artwork: PivotHorizontal and vertical particle pivot offsets. Adjust both axes together to change the anchor used for particle geometry.Artwork: AnimationAnimation playback mode and FPS. Loop modes use FPS; once modes span particle lifetime. None freezes the first frame.Artwork: Animation SizeReference width and height for animation geometry. The first frame’s original size is used when omitted. This sets a consistent aspect across the sequence.
Working with effects

Textures & animation

Load images or sprite sheets with PixiJS, then choose which texture each emitter uses.

Load a texture

Load your image with Assets.load() before creating the effect. Pass the texture under the emitter’s ID: sparks below matches id: 'sparks' in the effect definition.

import { Assets, type Texture } from 'pixi.js';
import { ParticleEffect } from '@reparticle/pixi';

const spark = await Assets.load<Texture>('/textures/spark.png');

const effect = new ParticleEffect({
  version: 1,
  emitters: [{
    id: 'sparks', // Emitter ID.
    capacity: 2048,
    seed: 42,
    emission: { rate: 120, shape: { type: 'point' } },
    initial: { lifetime: 2, speed: 90, direction: 0, spread: Math.PI * 2, size: 12 },
  }],
}, {
  ticker: app.ticker,
  emitters: {
    sparks: { textures: [spark] }, // Must match the emitter ID above.
  },
});

effect.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(effect);

The artwork key sparks must match the emitter’s id exactly. The texture variable spark and filename spark.png can have any name.

This uses your existing PixiJS app. For multiple emitters, add an entry for each ID under emitters. An emitter without a supplied texture draws soft procedural particles.

Missing or invalid textures use a placeholder and log a warning. Load assets before assigning them.

Load a sprite sheet

A sprite sheet packs several images into one PNG. Its JSON file tells PixiJS where each image is.

For example, put these exported files in your textures folder:

textures/
  particles.png
  particles.json

Load particles.json. PixiJS also loads particles.png, as long as that is the image referenced in the JSON. Then choose a frame and give it to your emitter:

import { Assets } from 'pixi.js';

await Assets.load('/textures/particles.json');

effect.setEmitterTexture('sparks', {
  textures: ['star.png'],
});

star.png is the name of an image inside the sheet, not a separate file to load. PixiJS caches these names when the sheet loads. A frame named star can be passed as textures: ['star']. Replace it with one of the names listed under frames in your JSON.

sparks selects the emitter from the previous example. This gives all its particles the star texture; it does not animate them.

Animate particles

After loading the sprite sheet, list its frame names in playback order. Use at least two frames from the same sheet image:

effect.setEmitterTexture('sparks', {
  textures: [
    'fire-01.png',
    'fire-02.png',
    'fire-03.png',
  ],
  playback: 'loop-forward',
  fps: 12,
});

You can also pass these same options under emitters.sparks when creating ParticleEffect. Use loop-forward to repeat at the chosen FPS, or once-forward to play once over each particle’s lifetime.

Artwork options

SettingDescriptionDefaultRequiredValue
texturesLoaded textures or cache names. Use one for a static image, or at least two from the same sheet image for animation.Procedural particlesNoTexture objects Cached names
sizeModemanual uses particle size. For animation, auto keeps the frame’s aspect ratio and applies particle size as a multiplier.manualNomanual auto
pivotOffset from the center. Positive X moves right; positive Y moves up.{ x: 0, y: 0 }No{ x, y }
flipXMirror the artwork horizontally.falseNotrue false
flipYMirror the artwork vertically.falseNotrue false
playbackChoose how animation frames play. Once modes span each particle’s lifetime; loop modes repeat at the chosen FPS.loop-forwardNonone once-forward once-backward once-pingpong loop-forward loop-backward loop-pingpong
fpsFrames per second for looping animations.30No0 or more
animationSizeReference dimensions for animation frames.First frame sizeNo{ width, height } Both greater than 0

Clean up

Destroy the effect when removing it from your scene. Loaded textures remain available for other effects. Unload an asset only when nothing else uses it:

effect.destroy();

// Only when these assets are no longer used by your scene:
await Assets.unload('/textures/spark.png');
await Assets.unload('/textures/particles.json');