Skip to content

NewKrok/three-particles

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

299 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

THREE Particles Logo

THREE Particles

npm downloads CI gzip license docs

Particle system for ThreeJS.

Features

  • Easy integration with Three.js.
  • Visual editor for creating and fine-tuning effects: THREE Particles Editor
  • Highly customizable particle properties (position, velocity, size, color, alpha, rotation, etc.).
  • Support for various emitter shapes and parameters.
  • Force fields and attractors for dynamic particle behavior (point attraction/repulsion, directional wind).
  • Sub-emitters triggered on particle birth or death events.
  • Serialization support for saving and loading particle system configs.
  • GPU instancing renderer (RendererType.INSTANCED) — removes gl_PointSize hardware limit, ideal for large particles or high particle counts.
  • Trail / Ribbon renderer (RendererType.TRAIL) — continuous ribbon trails behind particles with configurable width, opacity, and color tapering.
  • Mesh particle renderer (RendererType.MESH) — render each particle as a 3D mesh (debris, gems, coins) using GPU instancing with full 3D rotation and simple directional lighting.
  • Soft particles — depth-based alpha fade near opaque geometry, eliminating hard intersection lines.
  • TypeDoc API documentation available.

Live Demo & Examples

Installation

NPM

npm install @newkrok/three-particles

CDN (Browser)

Include the script directly in your HTML:

<script src="https://cdn.jsdelivr.net/npm/@newkrok/three-particles@latest/dist/three-particles.min.js"></script>
<!-- or -->
<script src="https://unpkg.com/@newkrok/three-particles@latest/dist/three-particles.min.js"></script>

Usage

Here's a basic example of how to load and use a particle system:

// Create a particle system
const effect = {
  // Your effect configuration here
  // It can be empty to use default settings
};
const system = createParticleSystem(effect);
scene.add(system.instance);

// Update the particle system in your animation loop
// Pass the current time, delta time, and elapsed time
updateParticleSystems({now, delta, elapsed});

// Update configuration at runtime without recreating the system
system.updateConfig({
  gravity: -9.8,
  forceFields: [{ type: 'DIRECTIONAL', direction: { x: 1, y: 0, z: 0 }, strength: 5 }],
});

Usage with React Three Fiber

The library works seamlessly with React Three Fiber. No additional wrapper package is needed — use createParticleSystem directly with React hooks:

import { useRef, useEffect } from "react";
import { useFrame } from "@react-three/fiber";
import {
  createParticleSystem,
  Shape,
  type ParticleSystem,
} from "@newkrok/three-particles";
import * as THREE from "three";

function FireEffect({ config }: { config?: Record<string, unknown> }) {
  const groupRef = useRef<THREE.Group>(null);
  const systemRef = useRef<ParticleSystem | null>(null);

  useEffect(() => {
    const system = createParticleSystem({
      duration: 5,
      looping: true,
      maxParticles: 200,
      startLifetime: { min: 0.5, max: 1.5 },
      startSpeed: { min: 1, max: 3 },
      startSize: { min: 0.3, max: 0.8 },
      startColor: {
        min: { r: 1, g: 0.2, b: 0 },
        max: { r: 1, g: 0.8, b: 0 },
      },
      gravity: -1,
      emission: { rateOverTime: 50 },
      shape: { shape: Shape.CONE, cone: { angle: 0.2, radius: 0.3 } },
      renderer: {
        blending: THREE.AdditiveBlending,
        transparent: true,
        depthWrite: false,
      },
      ...config,
    });

    systemRef.current = system;
    groupRef.current?.add(system.instance);

    return () => {
      system.dispose();
    };
  }, [config]);

  useFrame((_, delta) => {
    systemRef.current?.update({
      now: performance.now(),
      delta,
      elapsed: 0,
    });
  });

  return <group ref={groupRef} />;
}

// In your R3F Canvas:
// <Canvas>
//   <FireEffect />
// </Canvas>

Key points:

  • Use useEffect to create and dispose the particle system
  • Use useFrame to drive updates each frame (call system.update() instead of updateParticleSystems() for per-system control)
  • Add the system.instance to a <group> ref so R3F manages the scene graph
  • Return a cleanup function from useEffect that calls system.dispose()

Documentation

Automatically generated TypeDoc: https://newkrok.github.io/three-particles/api/

Important Notes

Color Over Lifetime

The colorOverLifetime feature uses a multiplier-based approach (similar to Unity's particle system), where each RGB channel curve acts as a multiplier applied to the particle's startColor.

Formula: finalColor = startColor * colorOverLifetime

⚠️ Important: To achieve full color transitions, set startColor to white { r: 1, g: 1, b: 1 }. If any channel in startColor is set to 0, that channel cannot be modified by colorOverLifetime.

Example - Rainbow effect:

{
  startColor: {
    min: { r: 1, g: 1, b: 1 },  // White - allows full color range
    max: { r: 1, g: 1, b: 1 }
  },
  colorOverLifetime: {
    isActive: true,
    r: {  // Red: full → half → off
      type: 'BEZIER',
      scale: 1,
      bezierPoints: [
        { x: 0, y: 1, percentage: 0 },
        { x: 0.5, y: 0.5, percentage: 0.5 },
        { x: 1, y: 0, percentage: 1 }
      ]
    },
    g: {  // Green: off → full → off
      type: 'BEZIER',
      scale: 1,
      bezierPoints: [
        { x: 0, y: 0, percentage: 0 },
        { x: 0.5, y: 1, percentage: 0.5 },
        { x: 1, y: 0, percentage: 1 }
      ]
    },
    b: {  // Blue: off → half → full
      type: 'BEZIER',
      scale: 1,
      bezierPoints: [
        { x: 0, y: 0, percentage: 0 },
        { x: 0.5, y: 0.5, percentage: 0.5 },
        { x: 1, y: 1, percentage: 1 }
      ]
    }
  }
}

About

Just one more particle system for ThreeJS

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors