@newkrok/three-particles 2.12.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,6 +21,8 @@ Particle system for ThreeJS.
21
21
  * Serialization support for saving and loading particle system configs.
22
22
  * GPU instancing renderer (`RendererType.INSTANCED`) — removes `gl_PointSize` hardware limit, ideal for large particles or high particle counts.
23
23
  * Trail / Ribbon renderer (`RendererType.TRAIL`) — continuous ribbon trails behind particles with configurable width, opacity, and color tapering.
24
+ * 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.
25
+ * Soft particles — depth-based alpha fade near opaque geometry, eliminating hard intersection lines.
24
26
  * TypeDoc API documentation available.
25
27
 
26
28
  # Live Demo & Examples
package/dist/index.d.ts CHANGED
@@ -180,7 +180,23 @@ declare const enum RendererType {
180
180
  *
181
181
  * Configure trail-specific properties via {@link TrailConfig} on the renderer.
182
182
  */
183
- TRAIL = "TRAIL"
183
+ TRAIL = "TRAIL",
184
+ /**
185
+ * Render each particle as a 3D mesh using GPU instancing (`InstancedBufferGeometry`).
186
+ * Instead of flat billboard sprites, particles are rendered as real 3D geometry
187
+ * (e.g., cubes, spheres, tori, or any custom `THREE.BufferGeometry`).
188
+ *
189
+ * Key differences from billboard renderers:
190
+ * - **3D rotation**: Particles rotate in all three axes (quaternion-based).
191
+ * - **Normals**: Mesh geometry retains normals, enabling basic lighting.
192
+ * - **Arbitrary geometry**: Any `THREE.BufferGeometry` can be used per particle.
193
+ *
194
+ * All existing modifiers (sizeOverLifetime, colorOverLifetime, noise, force fields,
195
+ * sub-emitters) work with mesh particles.
196
+ *
197
+ * Configure mesh-specific properties via {@link MeshConfig} on the renderer.
198
+ */
199
+ MESH = "MESH"
184
200
  }
185
201
  /**
186
202
  * Defines how force diminishes with distance from a POINT force field center.
@@ -681,6 +697,84 @@ type TrailConfig = {
681
697
  g: LifetimeCurve;
682
698
  b: LifetimeCurve;
683
699
  };
700
+ /**
701
+ * Minimum distance (in world units) a particle must travel before a new
702
+ * trail sample is recorded. When set, the trail becomes frame-rate
703
+ * independent — at high FPS the samples are spread further apart in time,
704
+ * at low FPS they cluster around sharp turns.
705
+ *
706
+ * When `0` or `undefined`, a sample is recorded every frame (legacy behavior).
707
+ * @default 0
708
+ */
709
+ minVertexDistance?: number;
710
+ /**
711
+ * Maximum trail duration in seconds. Trail segments older than this value
712
+ * are faded out and expired, regardless of the ring-buffer `length`.
713
+ * This enables time-based trail length (e.g. "2-second trails") in addition
714
+ * to the segment-count cap.
715
+ *
716
+ * When `0` or `undefined`, trail length is governed only by `length`.
717
+ * @default 0
718
+ */
719
+ maxTime?: number;
720
+ /**
721
+ * Enable Catmull-Rom spline interpolation between history samples.
722
+ * Inserts additional subdivided points between raw samples, eliminating
723
+ * sharp kinks at trail bends. The `smoothingSubdivisions` property controls
724
+ * how many extra points are inserted per segment.
725
+ *
726
+ * @default false
727
+ */
728
+ smoothing?: boolean;
729
+ /**
730
+ * Number of Catmull-Rom subdivisions inserted between each pair of raw
731
+ * history samples when `smoothing` is enabled. Higher values produce
732
+ * smoother curves at the cost of more vertices.
733
+ *
734
+ * @default 3
735
+ */
736
+ smoothingSubdivisions?: number;
737
+ /**
738
+ * Enable twist prevention for the ribbon. Uses frame tracking to maintain
739
+ * consistent ribbon orientation during rapid direction changes, preventing
740
+ * self-intersecting or flipped ribbon quads.
741
+ *
742
+ * @default false
743
+ */
744
+ twistPrevention?: boolean;
745
+ /**
746
+ * Connect multiple particles into a single continuous ribbon.
747
+ * All particles that share the same `ribbonId` are sorted by age and
748
+ * their positions are chained into one continuous strip.
749
+ *
750
+ * When `undefined`, each particle has its own independent trail (default behavior).
751
+ */
752
+ ribbonId?: number;
753
+ };
754
+ /**
755
+ * Configuration for the mesh particle renderer.
756
+ * Controls which 3D geometry is used when `rendererType` is `RendererType.MESH`.
757
+ *
758
+ * @property geometry - A `THREE.BufferGeometry` to render for each particle.
759
+ * Built-in Three.js primitives like `BoxGeometry`, `SphereGeometry`, `TorusGeometry`
760
+ * all work. The geometry's own normals and UVs are preserved.
761
+ *
762
+ * @example
763
+ * ```typescript
764
+ * // Cube mesh particles
765
+ * mesh: {
766
+ * geometry: new THREE.BoxGeometry(1, 1, 1),
767
+ * }
768
+ *
769
+ * // Icosahedron mesh particles
770
+ * mesh: {
771
+ * geometry: new THREE.IcosahedronGeometry(0.5, 0),
772
+ * }
773
+ * ```
774
+ */
775
+ type MeshConfig = {
776
+ /** The geometry to render for each particle. */
777
+ geometry: THREE.BufferGeometry;
684
778
  };
685
779
  /**
686
780
  * Configuration for the particle system renderer, controlling blending, transparency, depth, and background color behavior.
@@ -742,6 +836,60 @@ type Renderer = {
742
836
  * @see TrailConfig
743
837
  */
744
838
  trail?: TrailConfig;
839
+ /**
840
+ * Mesh particle renderer configuration.
841
+ * Only used when `rendererType` is `RendererType.MESH`.
842
+ *
843
+ * @see MeshConfig
844
+ */
845
+ mesh?: MeshConfig;
846
+ /**
847
+ * Soft particles configuration.
848
+ * When enabled, particles fade smoothly near opaque geometry instead of
849
+ * producing a hard intersection line. Requires a depth texture from a
850
+ * `WebGLRenderTarget`.
851
+ *
852
+ * @see SoftParticlesConfig
853
+ */
854
+ softParticles?: SoftParticlesConfig;
855
+ };
856
+ /**
857
+ * Configuration for soft (depth-faded) particles.
858
+ * When enabled, particles fade out smoothly near opaque geometry instead
859
+ * of producing a hard intersection line.
860
+ *
861
+ * Requires a depth texture from a `WebGLRenderTarget` with `DepthTexture`.
862
+ * If `depthTexture` is not provided, soft particles are automatically disabled
863
+ * regardless of the `enabled` flag.
864
+ *
865
+ * @property enabled - Whether soft particle fading is active. @default false
866
+ * @property intensity - Controls the fade distance in world units. Higher values
867
+ * produce a wider fade zone. Typical range: 0.1 to 5.0. @default 1.0
868
+ * @property depthTexture - A `THREE.DepthTexture` attached to the render target
869
+ * that contains the scene's depth pass. Must be updated every frame before
870
+ * the particle system renders.
871
+ *
872
+ * @example
873
+ * // Create a render target with a depth texture
874
+ * const rt = new THREE.WebGLRenderTarget(width, height, {
875
+ * depthTexture: new THREE.DepthTexture(width, height),
876
+ * });
877
+ *
878
+ * // Pass it to the particle system config
879
+ * const config = {
880
+ * renderer: {
881
+ * softParticles: {
882
+ * enabled: true,
883
+ * intensity: 1.5,
884
+ * depthTexture: rt.depthTexture,
885
+ * },
886
+ * },
887
+ * };
888
+ */
889
+ type SoftParticlesConfig = {
890
+ enabled?: boolean;
891
+ intensity?: number;
892
+ depthTexture?: THREE.DepthTexture;
745
893
  };
746
894
  /**
747
895
  * Configuration for noise effects applied to particles in a particle system.
@@ -1565,6 +1713,22 @@ type GeneralData = {
1565
1713
  trailLength?: number;
1566
1714
  /** Cached camera world position, updated each frame via onBeforeRender for billboard trails. */
1567
1715
  trailCameraPosition?: THREE.Vector3;
1716
+ /**
1717
+ * Timestamp (in ms) when each trail history sample was recorded.
1718
+ * Used by `maxTime` to expire old segments.
1719
+ * Layout: `maxParticles * trailLength` entries.
1720
+ */
1721
+ trailSampleTimes?: Float64Array;
1722
+ /**
1723
+ * Last recorded position per particle for adaptive sampling (`minVertexDistance`).
1724
+ * Layout: `maxParticles * 3` (x, y, z).
1725
+ */
1726
+ trailLastSampledPosition?: Float32Array;
1727
+ /**
1728
+ * Per-particle previous ribbon normal vector for twist prevention.
1729
+ * Layout: `maxParticles * 3` (nx, ny, nz).
1730
+ */
1731
+ trailPrevNormal?: Float32Array;
1568
1732
  };
1569
1733
  /** Union of all buffer attribute types Three.js uses in geometry. */
1570
1734
  type AnyBufferAttribute = THREE.BufferAttribute | THREE.InstancedBufferAttribute | THREE.InterleavedBufferAttribute;
@@ -1585,6 +1749,8 @@ type MappedAttributes = {
1585
1749
  colorG: AnyBufferAttribute;
1586
1750
  colorB: AnyBufferAttribute;
1587
1751
  colorA: AnyBufferAttribute;
1752
+ /** Packed quaternion vec4 for 3D mesh rotation (only present for RendererType.MESH). */
1753
+ quat?: AnyBufferAttribute;
1588
1754
  };
1589
1755
  type ParticleSystemInstance = {
1590
1756
  particleSystem: THREE.Points | THREE.Mesh;
@@ -1645,10 +1811,16 @@ type ParticleSystemInstance = {
1645
1811
  g: CurveFunction;
1646
1812
  b: CurveFunction;
1647
1813
  };
1648
- /** Trail config (length, width) */
1814
+ /** Trail config (length, width, and advanced features) */
1649
1815
  trailConfig?: {
1650
1816
  length: number;
1651
1817
  width: number;
1818
+ minVertexDistance: number;
1819
+ maxTime: number;
1820
+ smoothing: boolean;
1821
+ smoothingSubdivisions: number;
1822
+ twistPrevention: boolean;
1823
+ ribbonId?: number;
1652
1824
  };
1653
1825
  };
1654
1826
  /**
@@ -2028,6 +2200,13 @@ declare const calculateRandomPositionAndVelocityOnRectangle: (position: THREE.Ve
2028
2200
  rotation: Point3D;
2029
2201
  scale: Point3D;
2030
2202
  }) => void;
2203
+ /**
2204
+ * Creates a solid white 1x1 texture for mesh particles.
2205
+ * Unlike the circle texture used by point/billboard renderers, mesh particles
2206
+ * need a neutral texture so the geometry shape is visible.
2207
+ * @returns {THREE.CanvasTexture | null} The generated texture or null if context fails.
2208
+ */
2209
+ declare const createDefaultMeshTexture: () => THREE.CanvasTexture | null;
2031
2210
  /**
2032
2211
  * Creates a default white circle texture using CanvasTexture.
2033
2212
  * @returns {THREE.CanvasTexture | null} The generated texture or null if context fails.
@@ -2142,4 +2321,4 @@ declare const getDefaultParticleSystemConfig: () => any;
2142
2321
  declare const createParticleSystem: (config?: ParticleSystemConfig, externalNow?: number) => ParticleSystem;
2143
2322
  declare const updateParticleSystems: (cycleData: CycleData) => void;
2144
2323
 
2145
- export { type BezierCurve, type BezierPoint, type Box, type Burst, type BurstState, type Circle, type Cone, type Constant, type CurveBase, type CurveFunction, CurveFunctionId, type CycleData, type EasingCurve, type Emission, EmitFrom, type ForceFieldConfig, ForceFieldFalloff, ForceFieldType, type GeneralData, LifeTimeCurve, type LifetimeCurve, type MappedAttributes, type MinMaxColor, type Noise, type NoiseConfig, type NormalizedForceFieldConfig, type NormalizedParticleSystemConfig, type ParticleSystem, type ParticleSystemConfig, type ParticleSystemInstance, type Point3D, type RandomBetweenTwoConstants, type Rectangle, type Renderer, RendererType, type Rgb, Shape, type ShapeConfig, SimulationSpace, type Sphere, type SubEmitterConfig, SubEmitterTrigger, type TextureSheetAnimation, TimeMode, type TrailConfig, type Transform, type VelocityOverLifetime, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultParticleTexture, createParticleSystem, curveFunctionIdMap, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isLifeTimeCurve, removeBezierCurveFunction, updateParticleSystems };
2324
+ export { type BezierCurve, type BezierPoint, type Box, type Burst, type BurstState, type Circle, type Cone, type Constant, type CurveBase, type CurveFunction, CurveFunctionId, type CycleData, type EasingCurve, type Emission, EmitFrom, type ForceFieldConfig, ForceFieldFalloff, ForceFieldType, type GeneralData, LifeTimeCurve, type LifetimeCurve, type MappedAttributes, type MeshConfig, type MinMaxColor, type Noise, type NoiseConfig, type NormalizedForceFieldConfig, type NormalizedParticleSystemConfig, type ParticleSystem, type ParticleSystemConfig, type ParticleSystemInstance, type Point3D, type RandomBetweenTwoConstants, type Rectangle, type Renderer, RendererType, type Rgb, Shape, type ShapeConfig, SimulationSpace, type SoftParticlesConfig, type Sphere, type SubEmitterConfig, SubEmitterTrigger, type TextureSheetAnimation, TimeMode, type TrailConfig, type Transform, type VelocityOverLifetime, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultMeshTexture, createDefaultParticleTexture, createParticleSystem, curveFunctionIdMap, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isLifeTimeCurve, removeBezierCurveFunction, updateParticleSystems };