Skip to Content
Quarks
DocumentationCore ComponentsParticle System

Particle System

The ParticleSystem class is the central component in three.quarks that manages the creation, behavior, and lifecycle of particles. Each particle system defines how particles are emitted, their initial properties, and how they evolve over time.

Overview

A particle system in three.quarks is composed of several key components:

  • Emitter: Defines where and how particles are spawned (point, sphere, cone, etc.)
  • Initial Properties: Starting values for particles (life, speed, size, color, etc.)
  • Behaviors: Components that control how particles evolve over time
  • Renderer Settings: How particles are rendered in the scene

Creating a Particle System

Here’s a basic example of creating a particle system:

import * as THREE from "three"; import * as QUARKS from "three.quarks"; const particleSystem = new ParticleSystem({ duration: 5, looping: true, shape: new SphereEmitter({ radius: 1, thickness: 1, }), startLife: new IntervalValue(1, 3), startSpeed: new ConstantValue(5), startSize: new ConstantValue(0.5), startColor: new ConstantColor(new Vector4(1, 0.5, 0.1, 1)), worldSpace: true, material: new MeshBasicMaterial({ transparent: true, blending: AdditiveBlending, }), behaviors: [ new SizeOverLife(new PiecewiseBezier()), new ColorOverLife(new Gradient()), ], });

ParticleSystem Parameters

The ParticleSystem constructor accepts a configuration object with the following properties:

Core Properties

PropertyTypeDefaultDescription
durationnumber1Duration of the particle system in seconds
loopingbooleantrueWhether the particle system should loop after duration
prewarmbooleanfalseWhether to pre-simulate one loop when first becoming visible
autoDestroybooleanfalseWhether the system should be automatically disposed when it finishes emitting particles
worldSpacebooleanfalseWhether particles are simulated in world space or local space

Emission Configuration

PropertyTypeDefaultDescription
shapeEmitterShapeSphereEmitterShape that determines where particles are emitted from
emissionOverTimeValueGenerator | FunctionValueGeneratorConstantValue(10)Particles to emit per second
emissionOverDistanceValueGenerator | FunctionValueGeneratorConstantValue(0)Particles to emit per unit of distance traveled
emissionBurstsArray<BurstParameters>[]Bursts of particles at specific times
onlyUsedByOtherbooleanfalseWhether this particle system is only used as a sub-system

Initial Particle Properties

PropertyTypeDefaultDescription
startLifeValueGenerator | FunctionValueGeneratorConstantValue(5)Initial lifetime of particles in seconds
startSpeedValueGenerator | FunctionValueGeneratorConstantValue(0)Initial speed of particles
startRotationValueGenerator | FunctionValueGenerator | RotationGeneratorConstantValue(0)Initial rotation of particles
startSizeValueGenerator | FunctionValueGenerator | Vector3GeneratorConstantValue(1)Initial size of particles
startColorColorGenerator | FunctionColorGeneratorConstantColorInitial color of particles
startTileIndexValueGeneratorConstantValue(0)Initial tile index for sprite sheet animation

Rendering Properties

PropertyTypeDefaultDescription
materialMaterialRequiredMaterial used to render particles
instancingGeometryBufferGeometryPlaneGeometryGeometry used for instancing particles
renderModeRenderModeRenderMode.BillBoardMode of rendering (Billboard, Trail, Mesh, etc.)
renderOrdernumber0Rendering order for sorting
uTileCountnumber1Number of horizontal tiles in texture
vTileCountnumber1Number of vertical tiles in texture
blendTilesbooleanfalseWhether to blend between tiles
softParticlesbooleanfalseWhether to use soft particles (fade when close to objects)
softNearFadenumber0Near fade distance for soft particles
softFarFadenumber0Far fade distance for soft particles
layersLayersnew Layers()Three.js layers for visibility control

Behaviors

PropertyTypeDefaultDescription
behaviorsArray<Behavior>[]Behaviors that control how particles evolve over time

Lifecycle Methods

The ParticleSystem class provides several methods to control its lifecycle:

play()

Starts or resumes the particle system simulation.

particleSystem.play();

pause()

Pauses the particle system simulation.

particleSystem.pause();

stop()

Stops the particle system simulation and removes all existing particles.

particleSystem.stop();

restart()

Resets the particle system simulation and starts it again.

particleSystem.restart();

endEmit()

Stops emitting new particles but continues simulating existing ones.

particleSystem.endEmit();

dispose()

Removes the particle system’s emitter from the scene. This should be called when the particle system is no longer needed.

particleSystem.dispose();

Adding to the Scene

To use a particle system, you need to add its emitter to the scene and register it with a BatchedRenderer:

// Create a batched renderer const batchedRenderer = new BatchedRenderer(); scene.add(batchedRenderer); // Add the particle system to the scene scene.add(particleSystem.emitter); // Register the particle system with the batched renderer batchedRenderer.addSystem(particleSystem); // In your animation loop, update the batched renderer function animate() { requestAnimationFrame(animate); // Update with delta time in seconds batchedRenderer.update(deltaTime); renderer.render(scene, camera); }

Utility Methods

The QuarksUtil class provides utility methods for working with multiple particle systems:

// Add all particle systems in an object to a batched renderer QuarksUtil.addToBatchRenderer(object, batchedRenderer); // Play all particle systems in an object QuarksUtil.play(object); // Stop all particle systems in an object QuarksUtil.stop(object); // Pause all particle systems in an object QuarksUtil.pause(object); // Restart all particle systems in an object QuarksUtil.restart(object); // End emission for all particle systems in an object QuarksUtil.endEmit(object);

RenderMode Types

The renderMode parameter determines how particles are rendered:

ModeDescription
RenderMode.BillBoardParticles always face the camera
RenderMode.StretchedBillBoardParticles face the camera but are stretched based on velocity
RenderMode.MeshParticles are rendered as instanced meshes
RenderMode.TrailParticles leave trails behind them
RenderMode.HorizontalBillBoardParticles face upward but rotate to face the camera horizontally
RenderMode.VerticalBillBoardParticles maintain vertical orientation but face the camera horizontally

When using RenderMode.Trail, you need to provide additional settings:

const trailSystem = new ParticleSystem({ // ... other settings renderMode: RenderMode.Trail, rendererEmitterSettings: { startLength: new ConstantValue(30), followLocalOrigin: false, }, behaviors: [ new WidthOverLength(new PiecewiseBezier([[new Bezier(1, 0.8, 0.2, 0), 0]])), ], });

Burst Emission

You can configure burst emissions to emit particles at specific times:

const burstSystem = new ParticleSystem({ // ... other settings emissionBursts: [ { time: 0, // Time in seconds when the burst occurs count: new ConstantValue(20), // Number of particles to emit cycle: 1, // Number of times to repeat the burst interval: 0.1, // Interval between cycles probability: 1, // Probability of the burst occurring }, { time: 1, count: new ConstantValue(10), cycle: 1, interval: 0.1, probability: 0.5, }, ], });

Serialization

Particle systems can be serialized to and from JSON:

// Convert a particle system to JSON const json = particleSystem.toJSON(metadata, { useUrlForImage: true, }); // Create a particle system from JSON const loader = new QuarksLoader(); const loadedSystem = loader.parse(json);

Events

The ParticleSystem class provides events to track its lifecycle:

// Listen for when the particle system stops emitting particleSystem.addEventListener("emitEnd", (event) => { console.log("Emission ended"); }); // Listen for when a particle dies particleSystem.addEventListener("particleDied", (event) => { console.log("Particle died", event.particle); }); // Listen for when the particle system is destroyed particleSystem.addEventListener("destroy", (event) => { console.log("Particle system destroyed"); });

Example: Complete Fire Effect

Here’s a complete example of a fire effect using many features of the ParticleSystem:

const fireSystem = new ParticleSystem({ duration: 5, looping: true, prewarm: true, // Emit from a cone shape pointing upward shape: new ConeEmitter({ radius: 0.5, angle: Math.PI / 8, thickness: 0.8, }), // Emission settings emissionOverTime: new ConstantValue(50), emissionBursts: [ { time: 1, count: new ConstantValue(10), probability: 0.8, }, ], // Initial particle properties startLife: new IntervalValue(1, 2), startSpeed: new IntervalValue(2, 5), startSize: new IntervalValue(0.5, 1.0), startColor: new ConstantColor(new Vector4(1, 0.5, 0.1, 1)), // Rendering settings worldSpace: true, material: new MeshBasicMaterial({ map: fireTexture, transparent: true, blending: AdditiveBlending, }), renderMode: RenderMode.BillBoard, // Behaviors controlling how particles evolve behaviors: [ // Size increases then decreases new SizeOverLife(new PiecewiseBezier([[new Bezier(0.5, 1, 1, 0), 0]])), // Color changes from yellow to red to black new ColorOverLife( new Gradient( [ [new Vector3(1, 0.8, 0.2), 0], [new Vector3(1, 0.2, 0.1), 0.5], [new Vector3(0.1, 0.1, 0.1), 1], ], [ [1, 0], [0.8, 0.5], [0, 1], ], ), ), // Upward force new ApplyForce(new Vector3(0, 5, 0), new ConstantValue(1)), // Rotation new RotationOverLife(new IntervalValue(-Math.PI, Math.PI)), // Turbulence new TurbulenceField( new Vector3(2, 2, 2), 2, new Vector3(1, 2, 1), new Vector3(0.1, 0.1, 0.1), ), ], });

Best Practices

  1. Use Batched Rendering: Always add particle systems to a BatchedRenderer for optimal performance.

  2. Memory Management: Call dispose() on particle systems when they’re no longer needed.

  3. Particle Count: Be mindful of the number of particles and their complexity, especially for mobile devices.

  4. World vs. Local Space: Use worldSpace: true when particles need to persist independent of the emitter’s movement.

  5. Soft Particles: Enable softParticles when particles need to blend smoothly with scene geometry (requires a depth texture).

  6. Value Generators: Use appropriate value generators to create variation between particles.

  7. Behaviors: Use behaviors to create dynamic, realistic particle motion and appearance.

Next Steps

  • Learn about different Emitter Shapes for controlling where particles spawn
  • Explore various Behaviors for controlling particle evolution
  • Understand Value Generators for creating dynamic particle properties
  • Learn about BatchedRenderer for optimizing particle system performance
Last updated on