@newkrok/three-particles 2.16.1 → 3.0.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/js/effects/three-particles/three-particles-bezier.ts","../src/js/effects/three-particles/three-particles-curves.ts","../src/js/effects/three-particles/three-particles-enums.ts","../src/js/effects/three-particles/three-particles-constants.ts","../src/js/effects/three-particles/three-particles-utils.ts","../src/js/effects/three-particles/three-particles-modifiers.ts","../src/js/effects/three-particles/three-particles-renderer-detect.ts","../src/js/effects/three-particles/shaders/instanced-particle-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/instanced-particle-vertex-shader.glsl.ts","../src/js/effects/three-particles/shaders/mesh-particle-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/mesh-particle-vertex-shader.glsl.ts","../src/js/effects/three-particles/shaders/particle-system-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/particle-system-vertex-shader.glsl.ts","../src/js/effects/three-particles/shaders/trail-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/trail-vertex-shader.glsl.ts","../src/js/effects/three-particles/three-particles-collision.ts","../src/js/effects/three-particles/three-particles-forces.ts","../src/js/effects/three-particles/three-particles.ts","../src/js/effects/three-particles/three-particles-serialization.ts"],"names":["CurveFunctionId","SimulationSpace","Shape","EmitFrom","TimeMode","LifeTimeCurve","SubEmitterTrigger","ForceFieldType","RendererType","ForceFieldFalloff","CollisionPlaneMode","SimulationBackend","THREE","THREE2","THREE3","THREE4","posIdx","px","py","pz","THREE6"],"mappings":"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","file":"index.js","sourcesContent":["import { BezierPoint, CurveFunction } from './types.js';\n\nconst cache: Array<{\n bezierPoints: Array<BezierPoint>;\n curveFunction: CurveFunction;\n referencedBy: Array<number>;\n}> = [];\n\nconst nCr = (n: number, k: number) => {\n let z = 1;\n for (let i = 1; i <= k; i++) z *= (n + 1 - i) / i;\n return z;\n};\n\nexport const createBezierCurveFunction = (\n particleSystemId: number,\n bezierPoints: Array<BezierPoint>\n) => {\n const cacheEntry = cache.find((item) => item.bezierPoints === bezierPoints);\n\n if (cacheEntry) {\n if (!cacheEntry.referencedBy.includes(particleSystemId))\n cacheEntry.referencedBy.push(particleSystemId);\n return cacheEntry.curveFunction;\n }\n\n const entry = {\n referencedBy: [particleSystemId],\n bezierPoints,\n curveFunction: (percentage: number): number => {\n if (percentage < 0) return bezierPoints[0].y;\n if (percentage > 1) return bezierPoints[bezierPoints.length - 1].y;\n\n let start = 0;\n let stop = bezierPoints.length - 1;\n\n bezierPoints.find((point, index) => {\n const result = percentage < (point.percentage ?? 0);\n if (result) stop = index;\n else if (point.percentage !== undefined) start = index;\n return result;\n });\n\n const n = stop - start;\n const calculatedPercentage =\n (percentage - (bezierPoints[start].percentage ?? 0)) /\n ((bezierPoints[stop].percentage ?? 1) -\n (bezierPoints[start].percentage ?? 0));\n\n let value = 0;\n for (let i = 0; i <= n; i++) {\n const p = bezierPoints[start + i];\n const c =\n nCr(n, i) *\n Math.pow(1 - calculatedPercentage, n - i) *\n Math.pow(calculatedPercentage, i);\n value += c * p.y;\n }\n return value;\n },\n };\n\n cache.push(entry);\n return entry.curveFunction;\n};\n\nexport const removeBezierCurveFunction = (particleSystemId: number) => {\n while (true) {\n const index = cache.findIndex((item) =>\n item.referencedBy.includes(particleSystemId)\n );\n if (index === -1) break;\n const entry = cache[index];\n entry.referencedBy = entry.referencedBy.filter(\n (id) => id !== particleSystemId\n );\n if (entry.referencedBy.length === 0) cache.splice(index, 1);\n }\n};\n\nexport const getBezierCacheSize = () => cache.length;\n","import Easing from 'easing-functions';\nimport { CurveFunction } from './types.js';\n\n/**\n * Predefined easing function identifiers for animating particle properties\n * over their lifetime.\n *\n * These functions control the rate of change and create different animation\n * feels. Each type has three variants:\n * - **IN**: Starts slow, accelerates toward the end\n * - **OUT**: Starts fast, decelerates toward the end\n * - **IN_OUT**: Combines both, slow at start and end, fast in middle\n *\n * @enum {string}\n *\n * @see {@link https://easings.net/} - Visual reference for easing functions\n */\nexport const enum CurveFunctionId {\n /** Use custom Bezier curve (not an easing function) */\n BEZIER = 'BEZIER',\n\n /** Linear interpolation with constant rate of change */\n LINEAR = 'LINEAR',\n\n /** Quadratic (t²) easing - gentle acceleration */\n QUADRATIC_IN = 'QUADRATIC_IN',\n /** Quadratic (t²) easing - gentle deceleration */\n QUADRATIC_OUT = 'QUADRATIC_OUT',\n /** Quadratic (t²) easing - gentle acceleration then deceleration */\n QUADRATIC_IN_OUT = 'QUADRATIC_IN_OUT',\n\n /** Cubic (t³) easing - moderate acceleration */\n CUBIC_IN = 'CUBIC_IN',\n /** Cubic (t³) easing - moderate deceleration */\n CUBIC_OUT = 'CUBIC_OUT',\n /** Cubic (t³) easing - moderate acceleration then deceleration */\n CUBIC_IN_OUT = 'CUBIC_IN_OUT',\n\n /** Quartic (t⁴) easing - strong acceleration */\n QUARTIC_IN = 'QUARTIC_IN',\n /** Quartic (t⁴) easing - strong deceleration */\n QUARTIC_OUT = 'QUARTIC_OUT',\n /** Quartic (t⁴) easing - strong acceleration then deceleration */\n QUARTIC_IN_OUT = 'QUARTIC_IN_OUT',\n\n /** Quintic (t⁵) easing - very strong acceleration */\n QUINTIC_IN = 'QUINTIC_IN',\n /** Quintic (t⁵) easing - very strong deceleration */\n QUINTIC_OUT = 'QUINTIC_OUT',\n /** Quintic (t⁵) easing - very strong acceleration then deceleration */\n QUINTIC_IN_OUT = 'QUINTIC_IN_OUT',\n\n /** Sinusoidal easing - smooth, natural acceleration */\n SINUSOIDAL_IN = 'SINUSOIDAL_IN',\n /** Sinusoidal easing - smooth, natural deceleration */\n SINUSOIDAL_OUT = 'SINUSOIDAL_OUT',\n /** Sinusoidal easing - smooth acceleration then deceleration */\n SINUSOIDAL_IN_OUT = 'SINUSOIDAL_IN_OUT',\n\n /** Exponential easing - dramatic, explosive acceleration */\n EXPONENTIAL_IN = 'EXPONENTIAL_IN',\n /** Exponential easing - dramatic, explosive deceleration */\n EXPONENTIAL_OUT = 'EXPONENTIAL_OUT',\n /** Exponential easing - dramatic acceleration then deceleration */\n EXPONENTIAL_IN_OUT = 'EXPONENTIAL_IN_OUT',\n\n /** Circular easing - sharp acceleration with curved trajectory */\n CIRCULAR_IN = 'CIRCULAR_IN',\n /** Circular easing - sharp deceleration with curved trajectory */\n CIRCULAR_OUT = 'CIRCULAR_OUT',\n /** Circular easing - sharp acceleration then deceleration */\n CIRCULAR_IN_OUT = 'CIRCULAR_IN_OUT',\n\n /** Elastic easing - oscillates back before accelerating (spring-like) */\n ELASTIC_IN = 'ELASTIC_IN',\n /** Elastic easing - overshoots then oscillates back (spring-like) */\n ELASTIC_OUT = 'ELASTIC_OUT',\n /** Elastic easing - oscillates at both ends (spring-like) */\n ELASTIC_IN_OUT = 'ELASTIC_IN_OUT',\n\n /** Back easing - pulls back before accelerating forward */\n BACK_IN = 'BACK_IN',\n /** Back easing - overshoots forward then pulls back */\n BACK_OUT = 'BACK_OUT',\n /** Back easing - pulls back, overshoots, then settles */\n BACK_IN_OUT = 'BACK_IN_OUT',\n\n /** Bounce easing - bounces at the start */\n BOUNCE_IN = 'BOUNCE_IN',\n /** Bounce easing - bounces at the end (like a ball landing) */\n BOUNCE_OUT = 'BOUNCE_OUT',\n /** Bounce easing - bounces at both start and end */\n BOUNCE_IN_OUT = 'BOUNCE_IN_OUT',\n}\n\nexport const curveFunctionIdMap: Partial<\n Record<CurveFunctionId, CurveFunction>\n> = {\n [CurveFunctionId.LINEAR]: Easing.Linear.None,\n [CurveFunctionId.QUADRATIC_IN]: Easing.Quadratic.In,\n [CurveFunctionId.QUADRATIC_OUT]: Easing.Quadratic.Out,\n [CurveFunctionId.QUADRATIC_IN_OUT]: Easing.Quadratic.InOut,\n [CurveFunctionId.CUBIC_IN]: Easing.Cubic.In,\n [CurveFunctionId.CUBIC_OUT]: Easing.Cubic.Out,\n [CurveFunctionId.CUBIC_IN_OUT]: Easing.Cubic.InOut,\n [CurveFunctionId.QUARTIC_IN]: Easing.Quartic.In,\n [CurveFunctionId.QUARTIC_OUT]: Easing.Quartic.Out,\n [CurveFunctionId.QUARTIC_IN_OUT]: Easing.Quartic.InOut,\n [CurveFunctionId.QUINTIC_IN]: Easing.Quintic.In,\n [CurveFunctionId.QUINTIC_OUT]: Easing.Quintic.Out,\n [CurveFunctionId.QUINTIC_IN_OUT]: Easing.Quintic.InOut,\n [CurveFunctionId.SINUSOIDAL_IN]: Easing.Sinusoidal.In,\n [CurveFunctionId.SINUSOIDAL_OUT]: Easing.Sinusoidal.Out,\n [CurveFunctionId.SINUSOIDAL_IN_OUT]: Easing.Sinusoidal.InOut,\n [CurveFunctionId.EXPONENTIAL_IN]: Easing.Exponential.In,\n [CurveFunctionId.EXPONENTIAL_OUT]: Easing.Exponential.Out,\n [CurveFunctionId.EXPONENTIAL_IN_OUT]: Easing.Exponential.InOut,\n [CurveFunctionId.CIRCULAR_IN]: Easing.Circular.In,\n [CurveFunctionId.CIRCULAR_OUT]: Easing.Circular.Out,\n [CurveFunctionId.CIRCULAR_IN_OUT]: Easing.Circular.InOut,\n [CurveFunctionId.ELASTIC_IN]: Easing.Elastic.In,\n [CurveFunctionId.ELASTIC_OUT]: Easing.Elastic.Out,\n [CurveFunctionId.ELASTIC_IN_OUT]: Easing.Elastic.InOut,\n [CurveFunctionId.BACK_IN]: Easing.Back.In,\n [CurveFunctionId.BACK_OUT]: Easing.Back.Out,\n [CurveFunctionId.BACK_IN_OUT]: Easing.Back.InOut,\n [CurveFunctionId.BOUNCE_IN]: Easing.Bounce.In,\n [CurveFunctionId.BOUNCE_OUT]: Easing.Bounce.Out,\n [CurveFunctionId.BOUNCE_IN_OUT]: Easing.Bounce.InOut,\n};\n\n/**\n * Resolves a curve function from an identifier or returns the function itself.\n *\n * This utility function allows you to use either a {@link CurveFunctionId} string\n * identifier or a custom function directly.\n *\n * @param curveFunctionId - Either a {@link CurveFunctionId} enum value or a\n * custom {@link CurveFunction} implementation\n * @returns The actual easing function that takes a normalized time value (0-1)\n * and returns the eased value\n *\n * @example\n * ```typescript\n * import { getCurveFunction, CurveFunctionId } from '@newkrok/three-particles';\n *\n * // Using a predefined easing function\n * const easingFunc = getCurveFunction(CurveFunctionId.CUBIC_OUT);\n * console.log(easingFunc(0.5)); // Returns eased value at 50% progress\n *\n * // Using a custom function\n * const customEasing = (t: number) => t * t; // Quadratic\n * const customFunc = getCurveFunction(customEasing);\n * console.log(customFunc(0.5)); // Returns 0.25\n * ```\n */\nexport const getCurveFunction = (\n curveFunctionId: CurveFunctionId | CurveFunction\n): CurveFunction =>\n typeof curveFunctionId === 'function'\n ? curveFunctionId\n : curveFunctionIdMap[curveFunctionId]!;\n","/**\n * Defines the coordinate space in which particles are simulated.\n *\n * @enum {string}\n */\nexport const enum SimulationSpace {\n /**\n * Particles move relative to the emitter's local coordinate system.\n * When the emitter moves or rotates, particles move with it.\n * Ideal for effects attached to moving objects (e.g., engine trails, character auras).\n */\n LOCAL = 'LOCAL',\n\n /**\n * Particles move in world space and are independent of the emitter's transform.\n * Once emitted, particles remain stationary or move according to their velocity in world coordinates.\n * Ideal for environmental effects (e.g., smoke, explosions, ambient particles).\n */\n WORLD = 'WORLD',\n}\n\n/**\n * Defines the geometric shape from which particles are emitted.\n *\n * @enum {string}\n */\nexport const enum Shape {\n /**\n * Emit particles from a spherical volume or shell.\n * Configure with {@link Sphere} properties (radius, arc, radiusThickness).\n */\n SPHERE = 'SPHERE',\n\n /**\n * Emit particles from a conical volume or shell.\n * Configure with {@link Cone} properties (angle, radius, arc, radiusThickness).\n * Useful for directional effects like fire, smoke plumes, or spray effects.\n */\n CONE = 'CONE',\n\n /**\n * Emit particles from a box volume, shell, or edges.\n * Configure with {@link Box} properties (scale, emitFrom).\n * Useful for area-based effects like dust clouds or rain.\n */\n BOX = 'BOX',\n\n /**\n * Emit particles from a circular area or edge.\n * Configure with {@link Circle} properties (radius, arc, radiusThickness).\n * Useful for ground impacts, rings, or radial effects.\n */\n CIRCLE = 'CIRCLE',\n\n /**\n * Emit particles from a rectangular area.\n * Configure with {@link Rectangle} properties (scale, rotation).\n * Useful for planar effects like rain on a surface or screen effects.\n */\n RECTANGLE = 'RECTANGLE',\n}\n\n/**\n * Defines where on a shape particles are emitted from.\n * Not all shapes support all emit modes.\n *\n * @enum {string}\n */\nexport const enum EmitFrom {\n /**\n * Emit particles from random positions within the entire volume of the shape.\n * Supported by: SPHERE, CONE, BOX.\n */\n VOLUME = 'VOLUME',\n\n /**\n * Emit particles from the surface/shell of the shape.\n * Supported by: SPHERE, CONE, BOX.\n */\n SHELL = 'SHELL',\n\n /**\n * Emit particles from the edges of the shape.\n * Supported by: BOX.\n */\n EDGE = 'EDGE',\n}\n\n/**\n * Defines how texture sheet animation is timed.\n *\n * @enum {string}\n */\nexport const enum TimeMode {\n /**\n * Animation frames are based on the particle's lifetime percentage.\n * The animation completes once over the particle's lifetime.\n */\n LIFETIME = 'LIFETIME',\n\n /**\n * Animation frames are based on frames per second (FPS).\n * The animation runs at a fixed speed regardless of particle lifetime.\n */\n FPS = 'FPS',\n}\n\n/**\n * Defines the type of curve function used for animating values over a particle's lifetime.\n *\n * @enum {string}\n */\nexport const enum LifeTimeCurve {\n /**\n * Use custom Bezier curves with control points.\n * Provides maximum control over the animation curve shape.\n * See {@link BezierCurve} for configuration.\n */\n BEZIER = 'BEZIER',\n\n /**\n * Use predefined easing functions (e.g., easeInQuad, easeOutCubic).\n * Convenient for common animation patterns.\n * See {@link EasingCurve} and {@link CurveFunctionId} for available functions.\n */\n EASING = 'EASING',\n}\n\n/**\n * Defines when a sub-emitter is triggered relative to a particle's lifecycle.\n *\n * @enum {string}\n */\nexport const enum SubEmitterTrigger {\n /**\n * Trigger the sub-emitter when a particle is born (activated).\n * Useful for trail effects that start immediately with each particle.\n */\n BIRTH = 'BIRTH',\n\n /**\n * Trigger the sub-emitter when a particle dies (reaches end of lifetime).\n * Useful for cascading effects like explosions spawning smoke.\n */\n DEATH = 'DEATH',\n}\n\n/**\n * Defines the type of force field that affects particles.\n *\n * @enum {string}\n */\nexport const enum ForceFieldType {\n /**\n * Attract or repel particles toward/from a point in space.\n * Positive strength attracts, negative strength repels.\n * Configure with position, strength, range, and falloff.\n */\n POINT = 'POINT',\n\n /**\n * Apply a constant directional force to all particles (like wind).\n * Configure with direction and strength.\n */\n DIRECTIONAL = 'DIRECTIONAL',\n}\n\n/**\n * Defines the rendering technique used for particles.\n *\n * @enum {string}\n */\nexport const enum RendererType {\n /**\n * Render particles as point sprites using `THREE.Points`.\n * This is the default renderer, efficient for small to medium particle counts.\n * Note: point size is limited by `gl_PointSize` hardware caps (typically 64–256 px).\n */\n POINTS = 'POINTS',\n\n /**\n * Render particles as camera-facing quads using `THREE.InstancedBufferGeometry`.\n * Removes the `gl_PointSize` hardware limit, supports stretched billboards,\n * and enables batching multiple emitters into fewer draw calls.\n * Recommended for 10 000+ particles or when large on-screen particle sizes are needed.\n */\n INSTANCED = 'INSTANCED',\n\n /**\n * Render each particle as a ribbon trail connecting its current and previous positions.\n * Each particle stores a configurable number of position history samples, and the\n * renderer builds a camera-facing triangle-strip ribbon through those samples.\n *\n * Trail width and opacity can taper along the ribbon length for effects like\n * sword slashes, magic missiles, comet tails, and speed lines.\n *\n * Configure trail-specific properties via {@link TrailConfig} on the renderer.\n */\n TRAIL = 'TRAIL',\n\n /**\n * Render each particle as a 3D mesh using GPU instancing (`InstancedBufferGeometry`).\n * Instead of flat billboard sprites, particles are rendered as real 3D geometry\n * (e.g., cubes, spheres, tori, or any custom `THREE.BufferGeometry`).\n *\n * Key differences from billboard renderers:\n * - **3D rotation**: Particles rotate in all three axes (quaternion-based).\n * - **Normals**: Mesh geometry retains normals, enabling basic lighting.\n * - **Arbitrary geometry**: Any `THREE.BufferGeometry` can be used per particle.\n *\n * All existing modifiers (sizeOverLifetime, colorOverLifetime, noise, force fields,\n * sub-emitters) work with mesh particles.\n *\n * Configure mesh-specific properties via {@link MeshConfig} on the renderer.\n */\n MESH = 'MESH',\n}\n\n/**\n * Defines how force diminishes with distance from a POINT force field center.\n * Only applicable to {@link ForceFieldType.POINT} force fields.\n *\n * @enum {string}\n */\nexport const enum ForceFieldFalloff {\n /**\n * No falloff — force is constant within range.\n */\n NONE = 'NONE',\n\n /**\n * Force decreases linearly with distance: `1 - d/range`.\n */\n LINEAR = 'LINEAR',\n\n /**\n * Force decreases with the square of distance: `1 - (d/range)²`.\n * More physically realistic than linear fallback.\n */\n QUADRATIC = 'QUADRATIC',\n}\n\n/**\n * Defines the behavior when a particle crosses a collision plane.\n *\n * @enum {string}\n */\nexport const enum CollisionPlaneMode {\n /**\n * Kill the particle immediately when it crosses the plane.\n * The particle is deactivated and returned to the free list.\n * Ideal for boundaries like water surfaces where bubbles pop.\n */\n KILL = 'KILL',\n\n /**\n * Clamp the particle's position to the plane surface.\n * The velocity component along the plane normal is zeroed.\n * The particle stays alive and slides along the plane.\n */\n CLAMP = 'CLAMP',\n\n /**\n * Bounce the particle off the plane.\n * The velocity is reflected across the plane normal and dampened.\n * Use `dampen` to control energy loss on bounce.\n */\n BOUNCE = 'BOUNCE',\n}\n\n/**\n * Defines the simulation backend used for particle updates.\n *\n * @enum {string}\n */\nexport const enum SimulationBackend {\n /**\n * Automatically select the best backend based on the renderer type.\n * Uses GPU compute when a WebGPU-capable renderer is detected, otherwise falls back to CPU.\n */\n AUTO = 'AUTO',\n\n /**\n * Force CPU-based simulation (JavaScript update loop).\n * Always available regardless of renderer type.\n */\n CPU = 'CPU',\n\n /**\n * Force GPU compute shader simulation.\n * Requires a WebGPU-capable renderer (e.g. `THREE.WebGPURenderer`).\n * Falls back to CPU if the renderer does not support compute.\n */\n GPU = 'GPU',\n}\n","/**\n * Interleaved scalar buffer layout constants.\n *\n * All per-particle float attributes (except position and quat) are packed\n * into a single InterleavedBuffer to stay within the WebGPU vertex buffer\n * limit of 8.\n *\n * Buffer layout per particle (stride = 10 floats):\n * ```\n * [isActive, lifetime, startLifetime, startFrame, size, rotation, colorR, colorG, colorB, colorA]\n * ```\n */\n\n/** Number of float32 elements per particle in the interleaved scalar buffer. */\nexport const SCALAR_STRIDE = 10;\n\n/** Offset for the isActive flag (0 = inactive, 1 = active). */\nexport const S_IS_ACTIVE = 0;\n\n/** Offset for the current lifetime of the particle in milliseconds. */\nexport const S_LIFETIME = 1;\n\n/** Offset for the total lifetime of the particle in milliseconds. */\nexport const S_START_LIFETIME = 2;\n\n/** Offset for the texture sheet animation start frame index. */\nexport const S_START_FRAME = 3;\n\n/** Offset for the particle size. */\nexport const S_SIZE = 4;\n\n/** Offset for the particle rotation (radians). */\nexport const S_ROTATION = 5;\n\n/** Offset for the red color channel (0..1). */\nexport const S_COLOR_R = 6;\n\n/** Offset for the green color channel (0..1). */\nexport const S_COLOR_G = 7;\n\n/** Offset for the blue color channel (0..1). */\nexport const S_COLOR_B = 8;\n\n/** Offset for the alpha (opacity) channel (0..1). */\nexport const S_COLOR_A = 9;\n\n// ─── Shared rendering constants ─────────────────────────────────────────────\n\n/** Scale factor converting particle size to pixel-equivalent point size. */\nexport const POINT_SIZE_SCALE = 100.0;\n\n/** Minimum alpha below which fragments are discarded. */\nexport const ALPHA_DISCARD_THRESHOLD = 0.001;\n","import * as THREE from 'three';\n\nimport { createBezierCurveFunction } from './three-particles-bezier.js';\nimport { EmitFrom, LifeTimeCurve } from './three-particles-enums.js';\nimport {\n Constant,\n LifetimeCurve,\n Point3D,\n RandomBetweenTwoConstants,\n} from './types.js';\n\n/**\n * Calculates random position and velocity for particles emitted from a sphere.\n *\n * Supports emission from the entire volume or just the shell of the sphere.\n * Uses spherical coordinates for uniform distribution across the surface.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Sphere configuration\n * @param params.radius - Radius of the sphere\n * @param params.radiusThickness - Controls emission from volume (1.0) vs shell (0.0)\n * @param params.arc - Arc angle in degrees (360 = full sphere, 180 = hemisphere)\n *\n * @remarks\n * - `radiusThickness = 1.0`: Emit from entire volume\n * - `radiusThickness = 0.0`: Emit only from surface shell\n * - Particles are emitted radially outward from the center\n *\n * @see {@link Sphere} - Configuration type for sphere shape\n */\nexport const calculateRandomPositionAndVelocityOnSphere = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n {\n radius,\n radiusThickness,\n arc,\n }: { radius: number; radiusThickness: number; arc: number }\n) => {\n const u = Math.random() * (arc / 360);\n const v = Math.random();\n const randomizedDistanceRatio = Math.random();\n const theta = 2 * Math.PI * u;\n const phi = Math.acos(2 * v - 1);\n const sinPhi = Math.sin(phi);\n\n const xDirection = sinPhi * Math.cos(theta);\n const yDirection = sinPhi * Math.sin(theta);\n const zDirection = Math.cos(phi);\n const normalizedThickness = 1 - radiusThickness;\n\n position.x =\n radius * normalizedThickness * xDirection +\n radius * radiusThickness * randomizedDistanceRatio * xDirection;\n position.y =\n radius * normalizedThickness * yDirection +\n radius * radiusThickness * randomizedDistanceRatio * yDirection;\n position.z =\n radius * normalizedThickness * zDirection +\n radius * radiusThickness * randomizedDistanceRatio * zDirection;\n\n position.applyQuaternion(quaternion);\n\n const speedMultiplierByPosition = 1 / position.length();\n velocity.set(\n position.x * speedMultiplierByPosition * speed,\n position.y * speedMultiplierByPosition * speed,\n position.z * speedMultiplierByPosition * speed\n );\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a cone.\n *\n * Useful for directional particle effects like fire, smoke plumes, fountains,\n * or spray effects. The cone emits particles in a spreading pattern.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Cone configuration\n * @param params.radius - Base radius of the cone\n * @param params.radiusThickness - Controls emission from volume (1.0) vs shell (0.0)\n * @param params.arc - Arc angle in degrees (360 = full cone, 180 = half cone)\n * @param params.angle - Cone opening angle in degrees (default: 90)\n * Smaller values create tighter cones\n *\n * @remarks\n * - The cone emits from its base (circular area) outward\n * - Particles travel in a conical spread pattern\n * - `angle = 0`: Straight line (no spread)\n * - `angle = 90`: Wide cone\n * - Common for fire (10-30°), smoke (30-60°), explosions (60-90°)\n *\n * @see {@link Cone} - Configuration type for cone shape\n */\nexport const calculateRandomPositionAndVelocityOnCone = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n {\n radius,\n radiusThickness,\n arc,\n angle = 90,\n }: {\n radius: number;\n radiusThickness: number;\n arc: number;\n angle?: number;\n }\n) => {\n const theta = 2 * Math.PI * Math.random() * (arc / 360);\n const randomizedDistanceRatio = Math.random();\n\n const xDirection = Math.cos(theta);\n const yDirection = Math.sin(theta);\n const normalizedThickness = 1 - radiusThickness;\n\n position.x =\n radius * normalizedThickness * xDirection +\n radius * radiusThickness * randomizedDistanceRatio * xDirection;\n position.y =\n radius * normalizedThickness * yDirection +\n radius * radiusThickness * randomizedDistanceRatio * yDirection;\n position.z = 0;\n\n position.applyQuaternion(quaternion);\n\n const positionLength = position.length();\n const normalizedAngle = Math.abs(\n (positionLength / radius) * THREE.MathUtils.degToRad(angle)\n );\n const sinNormalizedAngle = Math.sin(normalizedAngle);\n\n const speedMultiplierByPosition = 1 / positionLength;\n velocity.set(\n position.x * sinNormalizedAngle * speedMultiplierByPosition * speed,\n position.y * sinNormalizedAngle * speedMultiplierByPosition * speed,\n Math.cos(normalizedAngle) * speed\n );\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a box.\n *\n * Supports three emission modes: volume, shell (surface), and edges.\n * Useful for area-based effects like dust clouds, rain, or geometric patterns.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Box configuration\n * @param params.scale - Size of the box on each axis (width, height, depth)\n * @param params.emitFrom - Emission mode:\n * - `VOLUME`: Random positions throughout the entire box volume\n * - `SHELL`: Random positions on the 6 faces (surface)\n * - `EDGE`: Random positions along the 12 edges\n *\n * @remarks\n * - All particles emit with velocity along the +Z axis (forward)\n * - Box is centered at the origin before rotation\n * - VOLUME mode: Best for rain, snow, or volumetric clouds\n * - SHELL mode: Best for hollow effects or surface particles\n * - EDGE mode: Best for wireframe effects or particle outlines\n *\n * @see {@link Box} - Configuration type for box shape\n * @see {@link EmitFrom} - Emission mode enum\n */\nexport const calculateRandomPositionAndVelocityOnBox = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n { scale, emitFrom }: { scale: Point3D; emitFrom: EmitFrom }\n) => {\n const _scale = scale as Required<Point3D>;\n switch (emitFrom) {\n case EmitFrom.VOLUME:\n position.x = Math.random() * _scale.x - _scale.x / 2;\n position.y = Math.random() * _scale.y - _scale.y / 2;\n position.z = Math.random() * _scale.z - _scale.z / 2;\n break;\n\n case EmitFrom.SHELL:\n const side = Math.floor(Math.random() * 6);\n const perpendicularAxis = side % 3;\n const shellResult = [];\n shellResult[perpendicularAxis] = side > 2 ? 1 : 0;\n shellResult[(perpendicularAxis + 1) % 3] = Math.random();\n shellResult[(perpendicularAxis + 2) % 3] = Math.random();\n position.x = shellResult[0] * _scale.x - _scale.x / 2;\n position.y = shellResult[1] * _scale.y - _scale.y / 2;\n position.z = shellResult[2] * _scale.z - _scale.z / 2;\n break;\n\n case EmitFrom.EDGE:\n const side2 = Math.floor(Math.random() * 6);\n const perpendicularAxis2 = side2 % 3;\n const edge = Math.floor(Math.random() * 4);\n const edgeResult = [];\n edgeResult[perpendicularAxis2] = side2 > 2 ? 1 : 0;\n edgeResult[(perpendicularAxis2 + 1) % 3] =\n edge < 2 ? Math.random() : edge - 2;\n edgeResult[(perpendicularAxis2 + 2) % 3] =\n edge < 2 ? edge : Math.random();\n position.x = edgeResult[0] * _scale.x - _scale.x / 2;\n position.y = edgeResult[1] * _scale.y - _scale.y / 2;\n position.z = edgeResult[2] * _scale.z - _scale.z / 2;\n break;\n }\n\n position.applyQuaternion(quaternion);\n\n velocity.set(0, 0, speed);\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a circle.\n *\n * Emits particles from a circular area or ring. Useful for ground impacts,\n * radial effects, magic circles, or any circular planar emission.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Circle configuration\n * @param params.radius - Radius of the circle\n * @param params.radiusThickness - Controls emission from area (1.0) vs edge (0.0)\n * @param params.arc - Arc angle in degrees (360 = full circle, 180 = semicircle)\n *\n * @remarks\n * - Circle lies in the XY plane by default (Z = 0)\n * - Particles emit along the +Z axis (perpendicular to circle)\n * - `radiusThickness = 1.0`: Filled circle (disc)\n * - `radiusThickness = 0.0`: Ring (circle edge only)\n * - Good for ground impact effects, teleport circles, or radial bursts\n *\n * @see {@link Circle} - Configuration type for circle shape\n */\nexport const calculateRandomPositionAndVelocityOnCircle = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n {\n radius,\n radiusThickness,\n arc,\n }: { radius: number; radiusThickness: number; arc: number }\n) => {\n const theta = 2 * Math.PI * Math.random() * (arc / 360);\n const randomizedDistanceRatio = Math.random();\n\n const xDirection = Math.cos(theta);\n const yDirection = Math.sin(theta);\n const normalizedThickness = 1 - radiusThickness;\n\n position.x =\n radius * normalizedThickness * xDirection +\n radius * radiusThickness * randomizedDistanceRatio * xDirection;\n position.y =\n radius * normalizedThickness * yDirection +\n radius * radiusThickness * randomizedDistanceRatio * yDirection;\n position.z = 0;\n\n position.applyQuaternion(quaternion);\n\n const positionLength = position.length();\n const speedMultiplierByPosition = 1 / positionLength;\n velocity.set(\n position.x * speedMultiplierByPosition * speed,\n position.y * speedMultiplierByPosition * speed,\n 0\n );\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a rectangle.\n *\n * Emits particles from a rectangular planar area. Useful for rain on a surface,\n * screen-space effects, or any planar emission pattern.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Rectangle configuration\n * @param params.rotation - Local rotation of the rectangle (degrees) before\n * applying quaternion\n * @param params.scale - Size of the rectangle (width and height)\n *\n * @remarks\n * - Rectangle lies in the XY plane by default\n * - Particles emit along the +Z axis (perpendicular to rectangle)\n * - The rotation parameter allows tilting the rectangle before the main\n * quaternion rotation is applied\n * - Good for rain effects, screen particles, or planar area emissions\n *\n * @see {@link Rectangle} - Configuration type for rectangle shape\n */\nexport const calculateRandomPositionAndVelocityOnRectangle = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n { rotation, scale }: { rotation: Point3D; scale: Point3D }\n) => {\n const _scale = scale as Required<Point3D>;\n const _rotation = rotation as Required<Point3D>;\n\n const xOffset = Math.random() * _scale.x - _scale.x / 2;\n const yOffset = Math.random() * _scale.y - _scale.y / 2;\n const rotationX = THREE.MathUtils.degToRad(_rotation.x);\n const rotationY = THREE.MathUtils.degToRad(_rotation.y);\n position.x = xOffset * Math.cos(rotationY);\n position.y = yOffset * Math.cos(rotationX);\n position.z = xOffset * Math.sin(rotationY) - yOffset * Math.sin(rotationX);\n\n position.applyQuaternion(quaternion);\n\n velocity.set(0, 0, speed);\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Creates a solid white 1x1 texture for mesh particles.\n * Unlike the circle texture used by point/billboard renderers, mesh particles\n * need a neutral texture so the geometry shape is visible.\n * @returns {THREE.CanvasTexture | null} The generated texture or null if context fails.\n */\nexport const createDefaultMeshTexture = (): THREE.CanvasTexture | null => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const context = canvas.getContext('2d');\n if (context) {\n context.fillStyle = 'white';\n context.fillRect(0, 0, 1, 1);\n const texture = new THREE.CanvasTexture(canvas);\n texture.needsUpdate = true;\n return texture;\n }\n return null;\n } catch {\n return null;\n }\n};\n\n/**\n * Creates a default white circle texture using CanvasTexture.\n * @returns {THREE.CanvasTexture | null} The generated texture or null if context fails.\n */\nexport const createDefaultParticleTexture = (): THREE.CanvasTexture | null => {\n try {\n const canvas = document.createElement('canvas');\n const size = 64;\n canvas.width = size;\n canvas.height = size;\n const context = canvas.getContext('2d');\n if (context) {\n const centerX = size / 2;\n const centerY = size / 2;\n const radius = size / 2 - 2; // Small padding\n\n context.beginPath();\n context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);\n context.fillStyle = 'white';\n context.fill();\n const texture = new THREE.CanvasTexture(canvas);\n texture.needsUpdate = true;\n return texture;\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n 'Could not get 2D context to generate default particle texture.'\n );\n return null;\n }\n } catch (error) {\n // Handle potential errors (e.g., document not available in non-browser env)\n // eslint-disable-next-line no-console\n console.warn('Error creating default particle texture:', error);\n return null;\n }\n};\n\nexport const isLifeTimeCurve = (\n value: Constant | RandomBetweenTwoConstants | LifetimeCurve\n): value is LifetimeCurve => {\n return typeof value !== 'number' && 'type' in value;\n};\n\nexport const getCurveFunctionFromConfig = (\n particleSystemId: number,\n lifetimeCurve: LifetimeCurve\n) => {\n if (lifetimeCurve.type === LifeTimeCurve.BEZIER) {\n return createBezierCurveFunction(\n particleSystemId,\n lifetimeCurve.bezierPoints\n ); // Bézier curve\n }\n\n if (lifetimeCurve.type === LifeTimeCurve.EASING) {\n return lifetimeCurve.curveFunction; // Easing curve\n }\n\n throw new Error(`Unsupported value type: ${lifetimeCurve}`);\n};\n\nexport const calculateValue = (\n particleSystemId: number,\n value: Constant | RandomBetweenTwoConstants | LifetimeCurve,\n time: number = 0\n): number => {\n if (typeof value === 'number') {\n return value; // Constant value\n }\n\n if ('min' in value && 'max' in value) {\n if (value.min === value.max) {\n return value.min ?? 0; // Constant value\n }\n return THREE.MathUtils.randFloat(value.min ?? 0, value.max ?? 1); // Random range\n }\n\n const lifetimeCurve = value as LifetimeCurve;\n return (\n getCurveFunctionFromConfig(particleSystemId, lifetimeCurve)(time) *\n (lifetimeCurve.scale ?? 1)\n );\n};\n","import * as THREE from 'three';\n\nimport {\n SCALAR_STRIDE,\n S_SIZE,\n S_ROTATION,\n S_COLOR_R,\n S_COLOR_G,\n S_COLOR_B,\n S_COLOR_A,\n} from './three-particles-constants.js';\nimport { calculateValue } from './three-particles-utils.js';\nimport {\n GeneralData,\n MappedAttributes,\n NormalizedParticleSystemConfig,\n} from './types.js';\n\nconst noiseInput = new THREE.Vector3(0, 0, 0);\nconst orbitalEuler = new THREE.Euler();\n\n/**\n * Applies all active modifiers to a single particle during the update cycle.\n *\n * This function handles the animation and modification of particle properties over its lifetime,\n * including velocity (linear and orbital), size, opacity, color, rotation, and noise-based effects.\n * It is called once per particle per frame by the {@link updateParticleSystems} function.\n *\n * @param params - Configuration object containing:\n * @param params.delta - Time elapsed since the last frame in seconds. Used for velocity and rotation calculations.\n * @param params.generalData - Internal particle system state and cached values.\n * @param params.normalizedConfig - The normalized particle system configuration with all modifiers.\n * @param params.attributes - Three.js buffer attributes for position, size, rotation, and color.\n * @param params.particleLifetimePercentage - Normalized lifetime of the particle (0.0 to 1.0).\n * - 0.0 = particle just born\n * - 1.0 = particle at end of life\n * @param params.particleIndex - Index of the particle in the buffer arrays.\n *\n * @remarks\n * The function modifies the following particle properties based on configuration:\n *\n * - **Linear Velocity**: Moves particles in a straight line (velocityOverLifetime.linear)\n * - **Orbital Velocity**: Rotates particles around their emission point (velocityOverLifetime.orbital)\n * - **Size Over Lifetime**: Scales particle size based on lifetime curve (sizeOverLifetime)\n * - **Opacity Over Lifetime**: Fades particles in/out based on lifetime curve (opacityOverLifetime)\n * - **Color Over Lifetime**: Animates RGB channels independently based on lifetime curves (colorOverLifetime)\n * - **Rotation Over Lifetime**: Rotates particles around their center (rotationOverLifetime)\n * - **Noise**: Adds organic, turbulent motion to position, rotation, and size (noise)\n *\n * Each modifier only runs if it's active in the configuration, optimizing performance for simple effects.\n *\n * @example\n * ```typescript\n * // This function is called internally by updateParticleSystems\n * // You typically don't need to call it directly\n *\n * // However, understanding its behavior helps configure particle systems:\n * const config = {\n * sizeOverLifetime: {\n * isActive: true,\n * lifetimeCurve: {\n * type: 'BEZIER',\n * bezierPoints: [\n * { x: 0, y: 0, percentage: 0 }, // Start at 0% size\n * { x: 0.5, y: 1, percentage: 0.5 }, // Grow to 100% at midlife\n * { x: 1, y: 0, percentage: 1 } // Shrink to 0% at end\n * ]\n * }\n * },\n * opacityOverLifetime: {\n * isActive: true,\n * lifetimeCurve: {\n * type: 'EASING',\n * curveFunction: 'easeOutQuad'\n * }\n * }\n * };\n * ```\n *\n * @see {@link updateParticleSystems} - Calls this function for each active particle\n * @see {@link VelocityOverLifetime} - Configuration for velocity modifiers\n * @see {@link NoiseConfig} - Configuration for noise-based effects\n */\nexport const applyModifiers = ({\n delta,\n generalData,\n normalizedConfig,\n attributes,\n scalarArray,\n particleLifetimePercentage,\n particleIndex,\n}: {\n delta: number;\n generalData: GeneralData;\n normalizedConfig: NormalizedParticleSystemConfig;\n attributes: MappedAttributes;\n scalarArray: Float32Array;\n particleLifetimePercentage: number;\n particleIndex: number;\n}) => {\n const {\n particleSystemId,\n startValues,\n lifetimeValues,\n linearVelocityData,\n orbitalVelocityData,\n noise,\n } = generalData;\n\n const positionIndex = particleIndex * 3;\n const positionArr = attributes.position.array;\n const base = particleIndex * SCALAR_STRIDE;\n\n if (linearVelocityData) {\n const { speed, valueModifiers } = linearVelocityData[particleIndex];\n\n const normalizedXSpeed = valueModifiers.x\n ? valueModifiers.x(particleLifetimePercentage)\n : speed.x;\n\n const normalizedYSpeed = valueModifiers.y\n ? valueModifiers.y(particleLifetimePercentage)\n : speed.y;\n\n const normalizedZSpeed = valueModifiers.z\n ? valueModifiers.z(particleLifetimePercentage)\n : speed.z;\n\n positionArr[positionIndex] += normalizedXSpeed * delta;\n positionArr[positionIndex + 1] += normalizedYSpeed * delta;\n positionArr[positionIndex + 2] += normalizedZSpeed * delta;\n\n attributes.position.needsUpdate = true;\n }\n\n if (orbitalVelocityData) {\n const { speed, positionOffset, valueModifiers } =\n orbitalVelocityData[particleIndex];\n\n positionArr[positionIndex] -= positionOffset.x;\n positionArr[positionIndex + 1] -= positionOffset.y;\n positionArr[positionIndex + 2] -= positionOffset.z;\n\n const normalizedXSpeed = valueModifiers.x\n ? valueModifiers.x(particleLifetimePercentage)\n : speed.x;\n\n const normalizedYSpeed = valueModifiers.y\n ? valueModifiers.y(particleLifetimePercentage)\n : speed.y;\n\n const normalizedZSpeed = valueModifiers.z\n ? valueModifiers.z(particleLifetimePercentage)\n : speed.z;\n\n orbitalEuler.set(\n normalizedXSpeed * delta,\n normalizedZSpeed * delta,\n normalizedYSpeed * delta\n );\n positionOffset.applyEuler(orbitalEuler);\n\n positionArr[positionIndex] += positionOffset.x;\n positionArr[positionIndex + 1] += positionOffset.y;\n positionArr[positionIndex + 2] += positionOffset.z;\n\n attributes.position.needsUpdate = true;\n }\n\n if (normalizedConfig.sizeOverLifetime.isActive) {\n const multiplier = calculateValue(\n particleSystemId,\n normalizedConfig.sizeOverLifetime.lifetimeCurve,\n particleLifetimePercentage\n );\n scalarArray[base + S_SIZE] =\n startValues.startSize[particleIndex] * multiplier;\n }\n\n if (normalizedConfig.opacityOverLifetime.isActive) {\n const multiplier = calculateValue(\n particleSystemId,\n normalizedConfig.opacityOverLifetime.lifetimeCurve,\n particleLifetimePercentage\n );\n scalarArray[base + S_COLOR_A] =\n startValues.startOpacity[particleIndex] * multiplier;\n }\n\n if (normalizedConfig.colorOverLifetime.isActive) {\n const rMultiplier = calculateValue(\n particleSystemId,\n normalizedConfig.colorOverLifetime.r,\n particleLifetimePercentage\n );\n const gMultiplier = calculateValue(\n particleSystemId,\n normalizedConfig.colorOverLifetime.g,\n particleLifetimePercentage\n );\n const bMultiplier = calculateValue(\n particleSystemId,\n normalizedConfig.colorOverLifetime.b,\n particleLifetimePercentage\n );\n\n scalarArray[base + S_COLOR_R] =\n startValues.startColorR[particleIndex] * rMultiplier;\n scalarArray[base + S_COLOR_G] =\n startValues.startColorG[particleIndex] * gMultiplier;\n scalarArray[base + S_COLOR_B] =\n startValues.startColorB[particleIndex] * bMultiplier;\n }\n\n if (lifetimeValues.rotationOverLifetime) {\n scalarArray[base + S_ROTATION] +=\n lifetimeValues.rotationOverLifetime[particleIndex] * delta * 0.02;\n }\n\n if (noise.isActive) {\n const {\n sampler,\n strength,\n noisePower,\n offsets,\n positionAmount,\n rotationAmount,\n sizeAmount,\n } = noise;\n let noiseOnPosition;\n\n const noisePosition =\n (particleLifetimePercentage + (offsets ? offsets[particleIndex] : 0)) *\n 10 *\n strength;\n\n noiseInput.set(noisePosition, 0, 0);\n noiseOnPosition = sampler!.get3(noiseInput);\n positionArr[positionIndex] += noiseOnPosition * noisePower * positionAmount;\n\n if (rotationAmount !== 0) {\n scalarArray[base + S_ROTATION] +=\n noiseOnPosition * noisePower * rotationAmount;\n }\n\n if (sizeAmount !== 0) {\n scalarArray[base + S_SIZE] += noiseOnPosition * noisePower * sizeAmount;\n }\n\n noiseInput.set(noisePosition, noisePosition, 0);\n noiseOnPosition = sampler!.get3(noiseInput);\n positionArr[positionIndex + 1] +=\n noiseOnPosition * noisePower * positionAmount;\n\n noiseInput.set(noisePosition, noisePosition, noisePosition);\n noiseOnPosition = sampler!.get3(noiseInput);\n positionArr[positionIndex + 2] +=\n noiseOnPosition * noisePower * positionAmount;\n\n attributes.position.needsUpdate = true;\n }\n\n // Sync packed quaternion vec4 from scalar rotation for mesh particles.\n // This runs after noise so the quaternion reflects the final rotation value.\n if (attributes.quat) {\n const rotZ = scalarArray[base + S_ROTATION];\n const halfZ = rotZ * 0.5;\n const qi = particleIndex * 4;\n attributes.quat.array[qi] = 0;\n attributes.quat.array[qi + 1] = 0;\n attributes.quat.array[qi + 2] = Math.sin(halfZ);\n attributes.quat.array[qi + 3] = Math.cos(halfZ);\n attributes.quat.needsUpdate = true;\n }\n};\n","import { SimulationBackend } from './three-particles-enums.js';\n\n/**\n * Checks whether the given renderer supports GPU compute dispatches.\n *\n * Uses duck-typing: a renderer is considered WebGPU-capable when it exposes\n * a `.compute()` method and a `.hasFeature()` method (both present on\n * `THREE.WebGPURenderer` but absent from `THREE.WebGLRenderer`).\n *\n * @param renderer - Any Three.js renderer instance.\n * @returns `true` when the renderer supports compute shaders.\n */\nexport function isComputeCapableRenderer(renderer: unknown): boolean {\n return (\n renderer !== null &&\n renderer !== undefined &&\n typeof renderer === 'object' &&\n 'compute' in renderer &&\n typeof (renderer as Record<string, unknown>).compute === 'function' &&\n 'hasFeature' in renderer &&\n typeof (renderer as Record<string, unknown>).hasFeature === 'function'\n );\n}\n\n/**\n * Resolves the effective simulation backend based on the user's preference\n * and the capabilities of the provided renderer.\n *\n * | Preference | WebGPURenderer | WebGLRenderer |\n * |------------|---------------|---------------|\n * | `AUTO` | `GPU` | `CPU` |\n * | `CPU` | `CPU` | `CPU` |\n * | `GPU` | `GPU` | `CPU` (fallback) |\n *\n * @param renderer - The Three.js renderer instance used for rendering.\n * @param preference - The user-specified simulation backend preference.\n * @returns The resolved {@link SimulationBackend} (`CPU` or `GPU`).\n */\nexport function resolveSimulationBackend(\n renderer: unknown,\n preference: SimulationBackend = SimulationBackend.AUTO\n): SimulationBackend.CPU | SimulationBackend.GPU {\n const gpuCapable = isComputeCapableRenderer(renderer);\n\n if (preference === SimulationBackend.CPU) {\n return SimulationBackend.CPU;\n }\n\n if (preference === SimulationBackend.GPU) {\n return gpuCapable ? SimulationBackend.GPU : SimulationBackend.CPU;\n }\n\n // AUTO: use GPU when available\n return gpuCapable ? SimulationBackend.GPU : SimulationBackend.CPU;\n}\n","const InstancedParticleFragmentShader = `\n uniform sampler2D map;\n uniform float elapsed;\n uniform float fps;\n uniform bool useFPSForFrameIndex;\n uniform vec2 tiles;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying vec2 vUv;\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n gl_FragColor = vColor;\n\n // Rotate UV around centre (matches Points renderer behaviour)\n vec2 center = vec2(0.5);\n vec2 centeredPoint = vUv - center;\n\n mat2 rotation = mat2(\n cos(vRotation), sin(vRotation),\n -sin(vRotation), cos(vRotation)\n );\n\n centeredPoint = rotation * centeredPoint;\n vec2 centeredMiddlePoint = centeredPoint + center;\n\n // Discard pixels outside the inscribed circle\n float dist = distance(centeredMiddlePoint, center);\n if (dist > 0.5) discard;\n\n float frameIndex = round(vStartFrame) + (\n useFPSForFrameIndex == true\n ? fps == 0.0\n ? 0.0\n : max((vLifetime / 1000.0) * fps, 0.0)\n : max(min(floor(min(vLifetime / vStartLifetime, 1.0) * (tiles.x * tiles.y)), tiles.x * tiles.y - 1.0), 0.0)\n );\n\n float spriteXIndex = floor(mod(frameIndex, tiles.x));\n float spriteYIndex = floor(mod(frameIndex / tiles.x, tiles.y));\n\n vec2 uvPoint = vec2(\n centeredMiddlePoint.x / tiles.x + spriteXIndex / tiles.x,\n centeredMiddlePoint.y / tiles.y + spriteYIndex / tiles.y\n );\n\n vec4 rotatedTexture = texture2D(map, uvPoint);\n\n gl_FragColor = gl_FragColor * rotatedTexture;\n\n if (discardBackgroundColor && abs(length(rotatedTexture.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n #include <logdepthbuf_fragment>\n }\n`;\n\nexport default InstancedParticleFragmentShader;\n","const InstancedParticleVertexShader = `\n attribute float instanceSize;\n attribute vec4 instanceColor;\n attribute float instanceLifetime;\n attribute float instanceStartLifetime;\n attribute float instanceRotation;\n attribute float instanceStartFrame;\n attribute vec3 instanceOffset;\n\n uniform float viewportHeight;\n\n varying vec2 vUv;\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n void main()\n {\n // Early-out for dead particles: skip all transforms and emit a degenerate\n // position that produces zero-area triangles.\n if (instanceColor.a <= 0.0) {\n gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n return;\n }\n\n vColor = instanceColor;\n vLifetime = instanceLifetime;\n vStartLifetime = instanceStartLifetime;\n vStartFrame = instanceStartFrame;\n vRotation = instanceRotation;\n\n vec4 mvPosition = modelViewMatrix * vec4(instanceOffset, 1.0);\n\n // Match the Points renderer pixel size: gl_PointSize = size * 100.0 / distance.\n // A view-space offset of d produces d * projectionMatrix[1][1] / w * (viewportHeight/2) pixels,\n // where w = -mvPosition.z for perspective. Solving for d so the result equals\n // the gl_PointSize pixel count:\n // d = size * 100.0 / distance\n // * (-mvPosition.z)\n // / (projectionMatrix[1][1] * viewportHeight * 0.5)\n // Since distance ≈ -mvPosition.z for view-aligned particles the two cancel out,\n // leaving a distance-independent expression. We keep them explicit so particles\n // off the viewing axis still scale correctly.\n float dist = length(mvPosition.xyz);\n float pointSizePx = instanceSize * 100.0 / dist;\n float perspectiveSize = pointSizePx * (-mvPosition.z)\n / (projectionMatrix[1][1] * viewportHeight * 0.5);\n\n // Billboard: offset quad vertices in view space (no rotation here;\n // rotation is applied to UVs in the fragment shader to keep behaviour\n // identical to the Points renderer).\n mvPosition.xy += position.xy * perspectiveSize;\n\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n // Pass UV for texture sampling (quad ranges from -0.5..0.5, map to 0..1).\n // Flip Y to match gl_PointCoord convention (Y runs top-to-bottom).\n vUv = vec2(position.x + 0.5, 0.5 - position.y);\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default InstancedParticleVertexShader;\n","const MeshParticleFragmentShader = `\n uniform sampler2D map;\n uniform float elapsed;\n uniform float fps;\n uniform bool useFPSForFrameIndex;\n uniform vec2 tiles;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying vec3 vNormal;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n gl_FragColor = vColor;\n\n // Use mesh UVs directly for texture sampling\n vec2 uvPoint = vUv;\n\n // Apply texture sheet animation if tiles > 1x1\n if (tiles.x > 1.0 || tiles.y > 1.0) {\n float frameIndex = round(vStartFrame) + (\n useFPSForFrameIndex == true\n ? fps == 0.0\n ? 0.0\n : max((vLifetime / 1000.0) * fps, 0.0)\n : max(min(floor(min(vLifetime / vStartLifetime, 1.0) * (tiles.x * tiles.y)), tiles.x * tiles.y - 1.0), 0.0)\n );\n\n float spriteXIndex = floor(mod(frameIndex, tiles.x));\n float spriteYIndex = floor(mod(frameIndex / tiles.x, tiles.y));\n\n uvPoint = vec2(\n vUv.x / tiles.x + spriteXIndex / tiles.x,\n vUv.y / tiles.y + spriteYIndex / tiles.y\n );\n }\n\n vec4 texColor = texture2D(map, uvPoint);\n gl_FragColor = gl_FragColor * texColor;\n\n if (discardBackgroundColor && abs(length(texColor.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n // Simple directional lighting from camera direction\n float lightIntensity = 0.5 + 0.5 * max(dot(vNormal, vec3(0.0, 0.0, 1.0)), 0.0);\n gl_FragColor.rgb *= lightIntensity;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n #include <logdepthbuf_fragment>\n }\n`;\n\nexport default MeshParticleFragmentShader;\n","const MeshParticleVertexShader = `\n attribute float instanceSize;\n attribute vec4 instanceColor;\n attribute float instanceLifetime;\n attribute float instanceStartLifetime;\n attribute float instanceRotation;\n attribute float instanceStartFrame;\n attribute vec3 instanceOffset;\n attribute vec4 instanceQuat;\n\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying vec3 vNormal;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n vec3 applyQuaternion(vec3 v, vec4 q) {\n vec3 t = 2.0 * cross(q.xyz, v);\n return v + q.w * t + cross(q.xyz, t);\n }\n\n void main()\n {\n // Early-out for dead particles: skip all expensive transforms and emit\n // a degenerate position that produces zero-area triangles.\n if (instanceColor.a <= 0.0) {\n gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n return;\n }\n\n vColor = instanceColor;\n vLifetime = instanceLifetime;\n vStartLifetime = instanceStartLifetime;\n vStartFrame = instanceStartFrame;\n vRotation = instanceRotation;\n\n // Apply quaternion rotation to the mesh vertex position\n vec3 rotatedPosition = applyQuaternion(position, instanceQuat);\n\n // Scale mesh by particle size\n vec3 scaledPosition = rotatedPosition * instanceSize;\n\n // Apply instance offset (particle world position)\n vec3 worldPos = scaledPosition + instanceOffset;\n\n vec4 mvPosition = modelViewMatrix * vec4(worldPos, 1.0);\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n // Transform normal by quaternion for lighting\n vNormal = normalize((modelViewMatrix * vec4(applyQuaternion(normal, instanceQuat), 0.0)).xyz);\n\n // Pass through UVs from the mesh geometry\n vUv = uv;\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default MeshParticleVertexShader;\n","const ParticleSystemFragmentShader = `\n uniform sampler2D map;\n uniform float elapsed;\n uniform float fps;\n uniform bool useFPSForFrameIndex;\n uniform vec2 tiles;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vRotation;\n varying float vStartFrame;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n gl_FragColor = vColor;\n float mid = 0.5;\n\n float frameIndex = round(vStartFrame) + (\n useFPSForFrameIndex == true\n ? fps == 0.0\n ? 0.0\n : max((vLifetime / 1000.0) * fps, 0.0)\n : max(min(floor(min(vLifetime / vStartLifetime, 1.0) * (tiles.x * tiles.y)), tiles.x * tiles.y - 1.0), 0.0)\n );\n \n float spriteXIndex = floor(mod(frameIndex, tiles.x));\n float spriteYIndex = floor(mod(frameIndex / tiles.x, tiles.y));\n\n vec2 frameUV = vec2(\n gl_PointCoord.x / tiles.x + spriteXIndex / tiles.x,\n gl_PointCoord.y / tiles.y + spriteYIndex / tiles.y);\n\n vec2 center = vec2(0.5, 0.5);\n vec2 centeredPoint = gl_PointCoord - center;\n\n mat2 rotation = mat2(\n cos(vRotation), sin(vRotation),\n -sin(vRotation), cos(vRotation)\n );\n\n centeredPoint = rotation * centeredPoint;\n vec2 centeredMiddlePoint = vec2(\n centeredPoint.x + center.x,\n centeredPoint.y + center.y\n );\n\n float dist = distance(centeredMiddlePoint, center);\n if (dist > 0.5) discard;\n\n vec2 uvPoint = vec2(\n centeredMiddlePoint.x / tiles.x + spriteXIndex / tiles.x,\n centeredMiddlePoint.y / tiles.y + spriteYIndex / tiles.y\n );\n\n vec4 rotatedTexture = texture2D(map, uvPoint);\n\n gl_FragColor = gl_FragColor * rotatedTexture;\n\n if (discardBackgroundColor && abs(length(rotatedTexture.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n #include <logdepthbuf_fragment>\n }\n`;\n\nexport default ParticleSystemFragmentShader;\n","const ParticleSystemVertexShader = `\n attribute float size;\n attribute vec4 color;\n attribute float lifetime;\n attribute float startLifetime;\n attribute float rotation;\n attribute float startFrame;\n\n varying mat4 vPosition;\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vRotation;\n varying float vStartFrame;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n void main()\n {\n vColor = color;\n vLifetime = lifetime;\n vStartLifetime = startLifetime;\n vRotation = rotation;\n vStartFrame = startFrame;\n\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n gl_PointSize = size * (100.0 / length(mvPosition.xyz));\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default ParticleSystemVertexShader;\n","const TrailFragmentShader = `\n uniform sampler2D map;\n uniform bool useMap;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying float vAlpha;\n varying vec4 vColor;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n // Soft edge: always fade near ribbon edges\n float edgeDist = 1.0 - abs(vUv.x * 2.0 - 1.0);\n float softEdge = smoothstep(0.0, 0.4, edgeDist);\n\n gl_FragColor = vColor;\n\n if (useMap) {\n // Use texture luminance as brightness modulation on top of soft edge\n vec4 texColor = texture2D(map, vUv);\n float texBrightness = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));\n gl_FragColor.rgb *= (0.5 + texBrightness * 0.5);\n gl_FragColor.a *= texColor.a;\n }\n\n gl_FragColor.a *= vAlpha * softEdge;\n\n if (gl_FragColor.a < 0.001) discard;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n if (discardBackgroundColor && abs(length(gl_FragColor.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n #include <logdepthbuf_fragment>\n }\n`;\n\nexport default TrailFragmentShader;\n","const TrailVertexShader = `\n attribute float trailAlpha;\n attribute vec4 trailColor;\n attribute float trailOffset;\n attribute float trailHalfWidth;\n attribute vec3 trailNext;\n attribute vec2 trailUV;\n\n varying float vAlpha;\n varying vec4 vColor;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n void main()\n {\n vAlpha = trailAlpha;\n vColor = trailColor;\n vUv = trailUV;\n\n // Compute tangent from current position to next sample\n vec3 tangent = trailNext - position;\n float tangentLen = length(tangent);\n if (tangentLen < 0.0001) {\n tangent = vec3(0.0, 1.0, 0.0);\n } else {\n tangent = tangent / tangentLen;\n }\n\n // Billboard: perpendicular = cross(tangent, viewDirection)\n vec3 worldPos = (modelMatrix * vec4(position, 1.0)).xyz;\n vec3 viewDir = normalize(cameraPosition - worldPos);\n vec3 perp = cross(tangent, viewDir);\n float perpLen = length(perp);\n\n // When tangent is nearly parallel to view direction, the cross product\n // collapses and the ribbon becomes edge-on (invisible). Build a stable\n // fallback perpendicular from the camera's right axis — this keeps the\n // ribbon in screen-space and prevents it from flipping into an arbitrary\n // plane when viewed edge-on.\n vec3 camRight = vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);\n vec3 fallbackPerp = normalize(camRight - tangent * dot(camRight, tangent));\n\n if (perpLen < 0.0001) {\n perp = fallbackPerp;\n } else {\n perp = perp / perpLen;\n // Smoothly blend toward the fallback when the billboard perp weakens.\n // The wide range (0..0.7) ensures a gradual transition so the ribbon\n // does not snap abruptly when rotating toward edge-on.\n float blendFactor = smoothstep(0.0, 0.7, perpLen);\n perp = normalize(mix(fallbackPerp, perp, blendFactor));\n }\n\n vec3 offsetPos = position + perp * trailOffset * trailHalfWidth;\n vec4 mvPosition = modelViewMatrix * vec4(offsetPos, 1.0);\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default TrailVertexShader;\n","import * as THREE from 'three';\n\nimport { S_LIFETIME, S_START_LIFETIME } from './three-particles-constants.js';\nimport { CollisionPlaneMode } from './three-particles-enums.js';\nimport { NormalizedCollisionPlaneConfig } from './types.js';\n\n// Pre-allocated vectors to avoid GC pressure in the hot loop\nconst _planeToParticle = new THREE.Vector3();\nconst _normalComponent = new THREE.Vector3();\n\n/**\n * Applies all active collision planes to a single particle.\n *\n * Collision planes define infinite surfaces in 3D space. When a particle's\n * signed distance to the plane becomes negative (i.e., it crosses from the\n * front side to the back side), the configured response mode is triggered:\n *\n * - **KILL**: Deactivate the particle immediately.\n * - **CLAMP**: Project the particle back onto the plane surface and zero the\n * velocity component along the plane normal.\n * - **BOUNCE**: Reflect the velocity across the plane normal, apply damping,\n * project the position back onto the plane, and optionally reduce lifetime.\n *\n * Called once per active particle per frame in the update loop,\n * after position update and before modifiers.\n *\n * @returns `true` if the particle was killed (caller should skip remaining processing).\n */\nexport const applyCollisionPlanes = ({\n collisionPlanes,\n velocity,\n positionArr,\n positionIndex,\n scalarArr,\n scalarBase,\n deactivateParticle,\n particleIndex,\n}: {\n collisionPlanes: ReadonlyArray<NormalizedCollisionPlaneConfig>;\n velocity: THREE.Vector3;\n positionArr: THREE.TypedArray;\n positionIndex: number;\n scalarArr: Float32Array;\n scalarBase: number;\n deactivateParticle: (particleIndex: number) => void;\n particleIndex: number;\n}): boolean => {\n for (let i = 0; i < collisionPlanes.length; i++) {\n const plane = collisionPlanes[i];\n if (!plane.isActive) continue;\n\n const normal = plane.normal;\n const planePos = plane.position;\n\n // Vector from plane position to particle position\n _planeToParticle.set(\n (positionArr[positionIndex] as number) - planePos.x,\n (positionArr[positionIndex + 1] as number) - planePos.y,\n (positionArr[positionIndex + 2] as number) - planePos.z\n );\n\n // Signed distance: positive = front side, negative = crossed the plane\n const signedDistance = _planeToParticle.dot(normal);\n\n if (signedDistance >= 0) continue;\n\n // Particle has crossed the plane — apply response\n switch (plane.mode) {\n case CollisionPlaneMode.KILL:\n deactivateParticle(particleIndex);\n return true;\n\n case CollisionPlaneMode.CLAMP:\n // Project position back onto the plane surface\n positionArr[positionIndex] =\n (positionArr[positionIndex] as number) - signedDistance * normal.x;\n positionArr[positionIndex + 1] =\n (positionArr[positionIndex + 1] as number) -\n signedDistance * normal.y;\n positionArr[positionIndex + 2] =\n (positionArr[positionIndex + 2] as number) -\n signedDistance * normal.z;\n\n // Remove velocity component along the plane normal\n const velDotNormal =\n velocity.x * normal.x + velocity.y * normal.y + velocity.z * normal.z;\n if (velDotNormal < 0) {\n velocity.x -= velDotNormal * normal.x;\n velocity.y -= velDotNormal * normal.y;\n velocity.z -= velDotNormal * normal.z;\n }\n break;\n\n case CollisionPlaneMode.BOUNCE: {\n // Project position back onto the plane surface\n positionArr[positionIndex] =\n (positionArr[positionIndex] as number) - signedDistance * normal.x;\n positionArr[positionIndex + 1] =\n (positionArr[positionIndex + 1] as number) -\n signedDistance * normal.y;\n positionArr[positionIndex + 2] =\n (positionArr[positionIndex + 2] as number) -\n signedDistance * normal.z;\n\n // Reflect velocity: v' = v - 2 * dot(v, n) * n\n const vDotN =\n velocity.x * normal.x + velocity.y * normal.y + velocity.z * normal.z;\n _normalComponent.set(\n 2 * vDotN * normal.x,\n 2 * vDotN * normal.y,\n 2 * vDotN * normal.z\n );\n velocity.x = (velocity.x - _normalComponent.x) * plane.dampen;\n velocity.y = (velocity.y - _normalComponent.y) * plane.dampen;\n velocity.z = (velocity.z - _normalComponent.z) * plane.dampen;\n\n // Apply lifetime loss\n if (plane.lifetimeLoss > 0) {\n const startLifetime = scalarArr[scalarBase + S_START_LIFETIME];\n scalarArr[scalarBase + S_LIFETIME] +=\n plane.lifetimeLoss * startLifetime;\n }\n break;\n }\n }\n }\n\n return false;\n};\n","import * as THREE from 'three';\n\nimport { ForceFieldFalloff, ForceFieldType } from './three-particles-enums.js';\nimport { calculateValue } from './three-particles-utils.js';\nimport { NormalizedForceFieldConfig } from './types.js';\n\n// Pre-allocated vector to avoid GC pressure in the hot loop\nconst _forceDirection = new THREE.Vector3();\n\nconst applyPointForce = (\n field: NormalizedForceFieldConfig,\n strength: number,\n velocity: THREE.Vector3,\n positionArr: THREE.TypedArray,\n positionIndex: number,\n delta: number\n): void => {\n _forceDirection.set(\n field.position.x - (positionArr[positionIndex] as number),\n field.position.y - (positionArr[positionIndex + 1] as number),\n field.position.z - (positionArr[positionIndex + 2] as number)\n );\n\n const distance = _forceDirection.length();\n\n if (distance < 0.0001) return;\n if (field.range !== Infinity && distance > field.range) return;\n\n _forceDirection.divideScalar(distance);\n\n let falloffMultiplier = 1.0;\n if (field.range !== Infinity) {\n const normalizedDistance = distance / field.range;\n switch (field.falloff) {\n case ForceFieldFalloff.LINEAR:\n falloffMultiplier = 1.0 - normalizedDistance;\n break;\n case ForceFieldFalloff.QUADRATIC:\n falloffMultiplier = 1.0 - normalizedDistance * normalizedDistance;\n break;\n case ForceFieldFalloff.NONE:\n falloffMultiplier = 1.0;\n break;\n }\n }\n\n const force = strength * falloffMultiplier * delta;\n velocity.x += _forceDirection.x * force;\n velocity.y += _forceDirection.y * force;\n velocity.z += _forceDirection.z * force;\n};\n\nconst applyDirectionalForce = (\n field: NormalizedForceFieldConfig,\n strength: number,\n velocity: THREE.Vector3,\n delta: number\n): void => {\n const force = strength * delta;\n velocity.x += field.direction.x * force;\n velocity.y += field.direction.y * force;\n velocity.z += field.direction.z * force;\n};\n\n/**\n * Applies all active force fields to a single particle's velocity.\n *\n * Force fields modify particle velocity (not position directly), matching\n * the gravity application pattern. This preserves momentum and integrates\n * naturally with the existing velocity system.\n *\n * Called once per active particle per frame in the update loop,\n * after gravity and before position update.\n *\n * @param params - Configuration object containing:\n * @param params.particleSystemId - Unique ID for the particle system (used by calculateValue).\n * @param params.forceFields - Array of normalized force field configurations.\n * @param params.velocity - The particle's current velocity vector (modified in place).\n * @param params.positionArr - The position buffer array for all particles.\n * @param params.positionIndex - The index into positionArr for this particle's X coordinate.\n * @param params.delta - Time elapsed since last frame in seconds.\n * @param params.systemLifetimePercentage - Normalized system lifetime (0.0 to 1.0) for curve evaluation.\n *\n * @example\n * ```typescript\n * // This function is called internally by updateParticleSystems\n * // You typically don't need to call it directly\n *\n * // Configure force fields in your particle system:\n * const config = {\n * forceFields: [\n * {\n * type: ForceFieldType.POINT,\n * position: new THREE.Vector3(0, 5, 0),\n * strength: 3.0,\n * range: 10,\n * falloff: ForceFieldFalloff.LINEAR,\n * },\n * ],\n * };\n * ```\n *\n * @see {@link ForceFieldConfig} - User-facing configuration type\n * @see {@link ForceFieldType} - Available force field types\n * @see {@link ForceFieldFalloff} - Available falloff modes\n */\nexport const applyForceFields = ({\n particleSystemId,\n forceFields,\n velocity,\n positionArr,\n positionIndex,\n delta,\n systemLifetimePercentage,\n}: {\n particleSystemId: number;\n forceFields: Array<NormalizedForceFieldConfig>;\n velocity: THREE.Vector3;\n positionArr: THREE.TypedArray;\n positionIndex: number;\n delta: number;\n systemLifetimePercentage: number;\n}): void => {\n for (let i = 0; i < forceFields.length; i++) {\n const field = forceFields[i];\n if (!field.isActive) continue;\n\n const strength = calculateValue(\n particleSystemId,\n field.strength,\n systemLifetimePercentage\n );\n\n if (strength === 0) continue;\n\n if (field.type === ForceFieldType.POINT) {\n applyPointForce(\n field,\n strength,\n velocity,\n positionArr,\n positionIndex,\n delta\n );\n } else if (field.type === ForceFieldType.DIRECTIONAL) {\n applyDirectionalForce(field, strength, velocity, delta);\n }\n }\n};\n","import { ObjectUtils } from '@newkrok/three-utils';\nimport * as THREE from 'three';\nimport { Gyroscope } from 'three/examples/jsm/misc/Gyroscope.js';\nimport { FBM } from 'three-noise/build/three-noise.module.js';\nimport InstancedParticleFragmentShader from './shaders/instanced-particle-fragment-shader.glsl.js';\nimport InstancedParticleVertexShader from './shaders/instanced-particle-vertex-shader.glsl.js';\nimport MeshParticleFragmentShader from './shaders/mesh-particle-fragment-shader.glsl.js';\nimport MeshParticleVertexShader from './shaders/mesh-particle-vertex-shader.glsl.js';\nimport ParticleSystemFragmentShader from './shaders/particle-system-fragment-shader.glsl.js';\nimport ParticleSystemVertexShader from './shaders/particle-system-vertex-shader.glsl.js';\nimport TrailFragmentShader from './shaders/trail-fragment-shader.glsl.js';\nimport TrailVertexShader from './shaders/trail-vertex-shader.glsl.js';\nimport { removeBezierCurveFunction } from './three-particles-bezier.js';\nimport { applyCollisionPlanes } from './three-particles-collision.js';\nimport {\n SCALAR_STRIDE,\n S_IS_ACTIVE,\n S_LIFETIME,\n S_START_LIFETIME,\n S_START_FRAME,\n S_SIZE,\n S_ROTATION,\n S_COLOR_R,\n S_COLOR_G,\n S_COLOR_B,\n S_COLOR_A,\n} from './three-particles-constants.js';\nimport {\n CollisionPlaneMode,\n EmitFrom,\n ForceFieldFalloff,\n ForceFieldType,\n LifeTimeCurve,\n RendererType,\n Shape,\n SimulationBackend,\n SimulationSpace,\n SubEmitterTrigger,\n TimeMode,\n} from './three-particles-enums';\nimport { applyForceFields } from './three-particles-forces.js';\nimport { applyModifiers } from './three-particles-modifiers.js';\nimport { isComputeCapableRenderer } from './three-particles-renderer-detect.js';\nimport {\n calculateRandomPositionAndVelocityOnBox,\n calculateRandomPositionAndVelocityOnCircle,\n calculateRandomPositionAndVelocityOnCone,\n calculateRandomPositionAndVelocityOnRectangle,\n calculateRandomPositionAndVelocityOnSphere,\n calculateValue,\n getCurveFunctionFromConfig,\n isLifeTimeCurve,\n createDefaultMeshTexture,\n createDefaultParticleTexture,\n} from './three-particles-utils.js';\n\nimport {\n CollisionPlaneConfig,\n Constant,\n CurveFunction,\n CycleData,\n ForceFieldConfig,\n GeneralData,\n LifetimeCurve,\n MappedAttributes,\n NormalizedCollisionPlaneConfig,\n NormalizedForceFieldConfig,\n NormalizedParticleSystemConfig,\n ParticleSystem,\n ParticleSystemConfig,\n ParticleSystemInstance,\n Point3D,\n RandomBetweenTwoConstants,\n ShapeConfig,\n SubEmitterConfig,\n MeshConfig,\n TrailConfig,\n} from './types.js';\n\nexport * from './types.js';\n\nconst normalizeTrailCurve = (\n curve: LifetimeCurve | undefined,\n defaultCurve: LifetimeCurve\n): LifetimeCurve => {\n if (!curve) return defaultCurve;\n const raw = curve as Record<string, unknown>;\n if (!raw.type && Array.isArray(raw.bezierPoints)) {\n return { type: LifeTimeCurve.BEZIER, ...raw } as LifetimeCurve;\n }\n return curve;\n};\n\n// Re-export so downstream consumers can access stride constants from the main module.\nexport {\n SCALAR_STRIDE,\n S_IS_ACTIVE,\n S_LIFETIME,\n S_START_LIFETIME,\n S_START_FRAME,\n S_SIZE,\n S_ROTATION,\n S_COLOR_R,\n S_COLOR_G,\n S_COLOR_B,\n S_COLOR_A,\n} from './three-particles-constants.js';\n\nlet _particleSystemId = 0;\nlet createdParticleSystems: Array<ParticleSystemInstance> = [];\n\n// ─── GPU Compute Uniform Helpers ────────────────────────────────────────────\n// Centralise the `as unknown as` casts for setting TSL uniform values.\n// The TSL uniform nodes expose `.value` at runtime but their TypeScript\n// type (`ShaderNodeObject<Node>`) does not declare it.\n\n/** Sets a TSL float uniform's value. */\nconst setUniformFloat = (u: unknown, v: number): void => {\n (u as { value: number }).value = v;\n};\n\n/** Sets a TSL vec3 uniform's value. */\nconst setUniformVec3 = (u: unknown, x: number, y: number, z: number): void => {\n (\n u as { value: { set: (x: number, y: number, z: number) => void } }\n ).value.set(x, y, z);\n};\n\n// ─── WebGPU TSL Material Support (opt-in via registerTSLMaterialFactory) ─────\n\ntype TSLMaterialFactory = {\n createTSLParticleMaterial: (\n rendererType: RendererType,\n sharedUniforms: Record<string, { value: unknown }>,\n rendererConfig: {\n transparent: boolean;\n blending: THREE.Blending;\n depthTest: boolean;\n depthWrite: boolean;\n },\n gpuCompute?: boolean\n ) => THREE.Material;\n createTSLTrailMaterial: (\n trailUniforms: Record<string, { value: unknown }>,\n rendererConfig: {\n transparent: boolean;\n blending: THREE.Blending;\n depthTest: boolean;\n depthWrite: boolean;\n }\n ) => THREE.Material;\n // GPU compute functions — use opaque types to avoid pulling WebGPU/TSL\n // types into the DTS output.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createComputePipeline?: (...args: any[]) => any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n writeParticleToModifierBuffers?: (...args: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deactivateParticleInModifierBuffers?: (...args: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n flushEmitQueue?: (...args: any[]) => number;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n registerCurveDataLength?: (...args: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n encodeForceFieldsForGPU?: (...args: any[]) => Float32Array;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n encodeCollisionPlanesForGPU?: (...args: any[]) => Float32Array;\n};\n\nlet _tslMaterialFactory: TSLMaterialFactory | null = null;\n\n/**\n * Registers the TSL (Three Shading Language) material factory for WebGPU support.\n *\n * Call this **once** before creating any particle systems that use WebGPU rendering.\n * The factory functions are imported from the `@newkrok/three-particles/webgpu` sub-module.\n *\n * When registered, all particle systems will use TSL-based `NodeMaterial` (compiles to WGSL)\n * instead of GLSL `ShaderMaterial`. If the factory also includes the GPU compute functions\n * (`createComputePipeline`, `writeParticleToModifierBuffers`, etc.), particle systems with\n * `simulationBackend: 'AUTO'` or `'GPU'` will run physics and modifiers on the GPU.\n *\n * @param factory - Object containing TSL material creators and optional GPU compute helpers.\n *\n * @example\n * ```typescript\n * import { registerTSLMaterialFactory } from '@newkrok/three-particles';\n * import {\n * createTSLParticleMaterial,\n * createTSLTrailMaterial,\n * createComputePipeline,\n * writeParticleToModifierBuffers,\n * deactivateParticleInModifierBuffers,\n * flushEmitQueue,\n * registerCurveDataLength,\n * encodeForceFieldsForGPU,\n * } from '@newkrok/three-particles/webgpu';\n *\n * registerTSLMaterialFactory({\n * createTSLParticleMaterial,\n * createTSLTrailMaterial,\n * createComputePipeline,\n * writeParticleToModifierBuffers,\n * deactivateParticleInModifierBuffers,\n * flushEmitQueue,\n * registerCurveDataLength,\n * encodeForceFieldsForGPU,\n * });\n * ```\n */\nexport const registerTSLMaterialFactory = (\n factory: TSLMaterialFactory\n): void => {\n _tslMaterialFactory = factory;\n};\n\n// Pre-allocated objects for updateParticleSystemInstance to avoid GC pressure\nconst _subEmitterPosition = new THREE.Vector3();\nconst _shadowOrbitalEuler = new THREE.Euler(0, 0, 0, 'XYZ');\nconst _lastWorldPositionSnapshot = new THREE.Vector3();\n// Force field local-space conversion helpers (reused across frames)\nconst _localForceFieldPos = new THREE.Vector3();\nconst _localForceFieldDir = new THREE.Vector3();\nconst _inverseQuat = new THREE.Quaternion();\nlet _localForceFields: Array<NormalizedForceFieldConfig> = [];\n// Collision plane local-space conversion helpers (reused across frames)\nconst _localCollisionPlanePos = new THREE.Vector3();\nconst _localCollisionPlaneNormal = new THREE.Vector3();\nlet _localCollisionPlanes: Array<NormalizedCollisionPlaneConfig> = [];\n// Trail ribbon helpers (reused across frames to avoid allocations)\nconst _trailDir = new THREE.Vector3();\nconst _trailPerp = new THREE.Vector3();\nconst _trailToCam = new THREE.Vector3();\nconst _distanceStep = { x: 0, y: 0, z: 0 };\nconst _tempPosition = { x: 0, y: 0, z: 0 };\nconst _modifierParams = {\n delta: 0,\n generalData: null as unknown as GeneralData,\n normalizedConfig: null as unknown as NormalizedParticleSystemConfig,\n attributes: null as unknown as MappedAttributes,\n scalarArray: null as unknown as Float32Array,\n particleLifetimePercentage: 0,\n particleIndex: 0,\n};\n\n/**\n * Converts a plain {x, y, z} object to a THREE.Vector3, using the fallback if undefined.\n */\nconst toVector3 = (\n v: { x?: number; y?: number; z?: number } | undefined,\n fallback: THREE.Vector3\n): THREE.Vector3 =>\n v ? new THREE.Vector3(v.x ?? 0, v.y ?? 0, v.z ?? 0) : fallback.clone();\n\n/**\n * Normalizes raw force field configs into the internal representation with THREE.Vector3 fields.\n */\nconst normalizeForceFields = (\n rawForceFields: Array<ForceFieldConfig> | undefined\n): Array<NormalizedForceFieldConfig> =>\n (rawForceFields ?? []).map((ff: ForceFieldConfig) => ({\n isActive: ff.isActive ?? true,\n type: ff.type ?? ForceFieldType.POINT,\n position: toVector3(ff.position, new THREE.Vector3(0, 0, 0)),\n direction: toVector3(ff.direction, new THREE.Vector3(0, 1, 0)).normalize(),\n strength: ff.strength ?? 1,\n range: Math.max(0, ff.range ?? Infinity),\n falloff: ff.falloff ?? ForceFieldFalloff.LINEAR,\n }));\n\n/**\n * Normalizes raw collision plane configs into the internal representation with THREE.Vector3 fields.\n */\nconst normalizeCollisionPlanes = (\n rawPlanes: Array<CollisionPlaneConfig> | undefined\n): Array<NormalizedCollisionPlaneConfig> =>\n (rawPlanes ?? []).map((cp: CollisionPlaneConfig) => ({\n isActive: cp.isActive ?? true,\n position: toVector3(cp.position, new THREE.Vector3(0, 0, 0)),\n normal: toVector3(cp.normal, new THREE.Vector3(0, 1, 0)).normalize(),\n mode: cp.mode ?? CollisionPlaneMode.KILL,\n dampen: Math.max(0, Math.min(1, cp.dampen ?? 0.5)),\n lifetimeLoss: Math.max(0, Math.min(1, cp.lifetimeLoss ?? 0)),\n }));\n\n/**\n * Mapping of blending mode string identifiers to Three.js blending constants.\n *\n * Used for converting serialized particle system configurations (e.g., from JSON)\n * to actual Three.js blending mode constants.\n *\n * @example\n * ```typescript\n * import { blendingMap } from '@newkrok/three-particles';\n *\n * // Convert string to Three.js constant\n * const blending = blendingMap['THREE.AdditiveBlending'];\n * // blending === THREE.AdditiveBlending\n * ```\n */\nexport const blendingMap = {\n 'THREE.NoBlending': THREE.NoBlending,\n 'THREE.NormalBlending': THREE.NormalBlending,\n 'THREE.AdditiveBlending': THREE.AdditiveBlending,\n 'THREE.SubtractiveBlending': THREE.SubtractiveBlending,\n 'THREE.MultiplyBlending': THREE.MultiplyBlending,\n};\n\n/**\n * Returns a deep copy of the default particle system configuration.\n *\n * This is useful when you want to start with default settings and modify specific properties\n * without affecting the internal default configuration object.\n *\n * @returns A new object containing all default particle system settings\n *\n * @example\n * ```typescript\n * import { getDefaultParticleSystemConfig, createParticleSystem } from '@newkrok/three-particles';\n *\n * // Get default config and modify it\n * const config = getDefaultParticleSystemConfig();\n * config.emission.rateOverTime = 100;\n * config.startColor.min = { r: 1, g: 0, b: 0 };\n *\n * const { instance } = createParticleSystem(config);\n * scene.add(instance);\n * ```\n */\nexport const getDefaultParticleSystemConfig = () =>\n JSON.parse(JSON.stringify(DEFAULT_PARTICLE_SYSTEM_CONFIG));\n\nconst DEFAULT_PARTICLE_SYSTEM_CONFIG: ParticleSystemConfig = {\n transform: {\n position: new THREE.Vector3(),\n rotation: new THREE.Vector3(),\n scale: new THREE.Vector3(1, 1, 1),\n },\n duration: 5.0,\n looping: true,\n startDelay: 0,\n startLifetime: 5.0,\n startSpeed: 1.0,\n startSize: 1.0,\n startOpacity: 1.0,\n startRotation: 0.0,\n startColor: {\n min: { r: 1.0, g: 1.0, b: 1.0 },\n max: { r: 1.0, g: 1.0, b: 1.0 },\n },\n gravity: 0.0,\n simulationSpace: SimulationSpace.LOCAL,\n simulationBackend: SimulationBackend.AUTO,\n maxParticles: 100.0,\n emission: {\n rateOverTime: 10.0,\n rateOverDistance: 0.0,\n bursts: [],\n },\n shape: {\n shape: Shape.SPHERE,\n sphere: {\n radius: 1.0,\n radiusThickness: 1.0,\n arc: 360.0,\n },\n cone: {\n angle: 25.0,\n radius: 1.0,\n radiusThickness: 1.0,\n arc: 360.0,\n },\n circle: {\n radius: 1.0,\n radiusThickness: 1.0,\n arc: 360.0,\n },\n rectangle: {\n rotation: { x: 0.0, y: 0.0 }, // TODO: add z rotation\n scale: { x: 1.0, y: 1.0 },\n },\n box: {\n scale: { x: 1.0, y: 1.0, z: 1.0 },\n emitFrom: EmitFrom.VOLUME,\n },\n },\n map: undefined,\n renderer: {\n blending: THREE.NormalBlending,\n discardBackgroundColor: false,\n backgroundColorTolerance: 1.0,\n backgroundColor: { r: 1.0, g: 1.0, b: 1.0 },\n transparent: true,\n depthTest: true,\n depthWrite: false,\n softParticles: {\n enabled: false,\n intensity: 1.0,\n },\n },\n velocityOverLifetime: {\n isActive: false,\n linear: {\n x: 0,\n y: 0,\n z: 0,\n },\n orbital: {\n x: 0,\n y: 0,\n z: 0,\n },\n },\n sizeOverLifetime: {\n isActive: false,\n lifetimeCurve: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 0, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n },\n colorOverLifetime: {\n isActive: false,\n r: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n g: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n b: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n },\n opacityOverLifetime: {\n isActive: false,\n lifetimeCurve: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 0, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n },\n rotationOverLifetime: {\n isActive: false,\n min: 0.0,\n max: 0.0,\n },\n noise: {\n isActive: false,\n useRandomOffset: false,\n strength: 1.0,\n frequency: 0.5,\n octaves: 1,\n positionAmount: 1.0,\n rotationAmount: 0.0,\n sizeAmount: 0.0,\n },\n textureSheetAnimation: {\n tiles: new THREE.Vector2(1.0, 1.0),\n timeMode: TimeMode.LIFETIME,\n fps: 30.0,\n startFrame: 0,\n },\n forceFields: [],\n collisionPlanes: [],\n};\n\nconst calculatePositionAndVelocity = (\n generalData: GeneralData,\n { shape, sphere, cone, circle, rectangle, box }: ShapeConfig,\n startSpeed: Constant | RandomBetweenTwoConstants | LifetimeCurve,\n position: THREE.Vector3,\n velocity: THREE.Vector3\n) => {\n const calculatedStartSpeed = calculateValue(\n generalData.particleSystemId,\n startSpeed,\n generalData.normalizedLifetimePercentage\n );\n\n switch (shape) {\n case Shape.SPHERE:\n calculateRandomPositionAndVelocityOnSphere(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n sphere as Required<NonNullable<ShapeConfig['sphere']>>\n );\n break;\n\n case Shape.CONE:\n calculateRandomPositionAndVelocityOnCone(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n cone as Required<NonNullable<ShapeConfig['cone']>>\n );\n break;\n\n case Shape.CIRCLE:\n calculateRandomPositionAndVelocityOnCircle(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n circle as Required<NonNullable<ShapeConfig['circle']>>\n );\n break;\n\n case Shape.RECTANGLE:\n calculateRandomPositionAndVelocityOnRectangle(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n rectangle as Required<NonNullable<ShapeConfig['rectangle']>>\n );\n break;\n\n case Shape.BOX:\n calculateRandomPositionAndVelocityOnBox(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n box as Required<NonNullable<ShapeConfig['box']>>\n );\n break;\n }\n};\n\nconst destroyParticleSystem = (particleSystem: THREE.Points | THREE.Mesh) => {\n createdParticleSystems = createdParticleSystems.filter(\n ({\n particleSystem: savedParticleSystem,\n wrapper,\n trailMesh,\n generalData: { particleSystemId },\n }) => {\n if (\n savedParticleSystem !== particleSystem &&\n wrapper !== particleSystem\n ) {\n return true;\n }\n\n removeBezierCurveFunction(particleSystemId);\n\n // Dispose trail mesh if present\n if (trailMesh) {\n trailMesh.geometry.dispose();\n if (Array.isArray(trailMesh.material))\n trailMesh.material.forEach((m) => m.dispose());\n else trailMesh.material.dispose();\n if (trailMesh.parent) trailMesh.parent.remove(trailMesh);\n }\n\n savedParticleSystem.geometry.dispose();\n if (Array.isArray(savedParticleSystem.material))\n savedParticleSystem.material.forEach((material) => material.dispose());\n else savedParticleSystem.material.dispose();\n\n if (savedParticleSystem.parent)\n savedParticleSystem.parent.remove(savedParticleSystem);\n if (wrapper?.parent) wrapper.parent.remove(wrapper);\n return false;\n }\n );\n};\n\n/**\n * Creates a new particle system with the specified configuration.\n *\n * This is the primary function for instantiating particle effects. It handles the complete\n * setup of a particle system including geometry creation, material configuration, shader setup,\n * and initialization of all particle properties.\n *\n * @param config - Configuration object for the particle system. If not provided, uses default settings.\n * See {@link ParticleSystemConfig} for all available options.\n * @param externalNow - Optional custom timestamp in milliseconds. If not provided, uses `Date.now()`.\n * Useful for synchronized particle systems or testing.\n *\n * @returns A {@link ParticleSystem} object containing:\n * - `instance`: The THREE.Object3D that should be added to your scene\n * - `resumeEmitter()`: Function to resume particle emission\n * - `pauseEmitter()`: Function to pause particle emission\n * - `dispose()`: Function to clean up resources and remove the particle system\n *\n * @example\n * ```typescript\n * import { createParticleSystem, updateParticleSystems } from '@newkrok/three-particles';\n *\n * // Create a basic particle system with default settings\n * const { instance, dispose } = createParticleSystem();\n * scene.add(instance);\n *\n * // Create a custom fire effect\n * const fireEffect = createParticleSystem({\n * duration: 2.0,\n * looping: true,\n * startLifetime: { min: 0.5, max: 1.5 },\n * startSpeed: { min: 2, max: 4 },\n * startSize: { min: 0.5, max: 1.5 },\n * startColor: {\n * min: { r: 1.0, g: 0.3, b: 0.0 },\n * max: { r: 1.0, g: 0.8, b: 0.0 }\n * },\n * emission: { rateOverTime: 50 },\n * shape: {\n * shape: Shape.CONE,\n * cone: { angle: 10, radius: 0.2 }\n * }\n * });\n * scene.add(fireEffect.instance);\n *\n * // In your animation loop\n * function animate(time) {\n * updateParticleSystems({ now: time, delta: deltaTime, elapsed: elapsedTime });\n * renderer.render(scene, camera);\n * }\n *\n * // Clean up when done\n * fireEffect.dispose();\n * ```\n *\n * @see {@link updateParticleSystems} - Required function to call in your animation loop\n * @see {@link ParticleSystemConfig} - Complete configuration options\n */\nexport const createParticleSystem = (\n config: ParticleSystemConfig = DEFAULT_PARTICLE_SYSTEM_CONFIG,\n externalNow?: number\n): ParticleSystem => {\n const now = externalNow || Date.now();\n const generalData: GeneralData = {\n particleSystemId: _particleSystemId++,\n normalizedLifetimePercentage: 0,\n distanceFromLastEmitByDistance: 0,\n lastWorldPosition: new THREE.Vector3(-99999),\n currentWorldPosition: new THREE.Vector3(-99999),\n worldPositionChange: new THREE.Vector3(),\n worldQuaternion: new THREE.Quaternion(),\n wrapperQuaternion: new THREE.Quaternion(),\n lastWorldQuaternion: new THREE.Quaternion(-99999),\n worldEuler: new THREE.Euler(),\n gravityVelocity: new THREE.Vector3(0, 0, 0),\n startValues: {},\n linearVelocityData: undefined,\n orbitalVelocityData: undefined,\n lifetimeValues: {},\n creationTimes: [],\n noise: {\n isActive: false,\n strength: 0,\n noisePower: 0,\n frequency: 0.5,\n positionAmount: 0,\n rotationAmount: 0,\n sizeAmount: 0,\n fbmMax: 1,\n },\n isEnabled: true,\n };\n const normalizedConfig = ObjectUtils.deepMerge(\n DEFAULT_PARTICLE_SYSTEM_CONFIG as NormalizedParticleSystemConfig,\n config,\n { applyToFirstObject: false, skippedProperties: [] }\n ) as NormalizedParticleSystemConfig;\n let particleMap: THREE.Texture | null =\n normalizedConfig.map ||\n (normalizedConfig.renderer.rendererType === RendererType.MESH\n ? createDefaultMeshTexture()\n : createDefaultParticleTexture());\n\n // Ensure ClampToEdgeWrapping for particle textures to prevent bleeding\n // at sprite-sheet tile boundaries (especially visible with WebGPU).\n if (particleMap) {\n particleMap.wrapS = THREE.ClampToEdgeWrapping;\n particleMap.wrapT = THREE.ClampToEdgeWrapping;\n }\n\n const {\n transform,\n duration,\n looping,\n startDelay,\n startLifetime,\n startSpeed,\n startSize,\n startRotation,\n startColor,\n startOpacity,\n gravity,\n simulationSpace,\n maxParticles,\n emission,\n shape,\n renderer,\n noise,\n velocityOverLifetime,\n onUpdate,\n onComplete,\n textureSheetAnimation,\n subEmitters,\n forceFields: rawForceFields,\n } = normalizedConfig;\n\n const normalizedForceFields: Array<NormalizedForceFieldConfig> =\n normalizeForceFields(rawForceFields);\n\n const normalizedCollisionPlanes: Array<NormalizedCollisionPlaneConfig> =\n normalizeCollisionPlanes(normalizedConfig.collisionPlanes);\n\n if (typeof renderer?.blending === 'string')\n renderer.blending = blendingMap[renderer.blending];\n\n const startPositions = Array.from(\n { length: maxParticles },\n () => new THREE.Vector3()\n );\n const velocities = Array.from(\n { length: maxParticles },\n () => new THREE.Vector3()\n );\n\n generalData.creationTimes = Array.from({ length: maxParticles }, () => 0);\n\n // Free list for O(1) inactive particle lookup (stack, top = end of array)\n const freeList: Array<number> = Array.from(\n { length: maxParticles },\n (_, i) => maxParticles - 1 - i\n );\n\n if (velocityOverLifetime.isActive) {\n generalData.linearVelocityData = Array.from(\n { length: maxParticles },\n () => ({\n speed: new THREE.Vector3(\n velocityOverLifetime.linear.x\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.linear.x,\n 0\n )\n : 0,\n velocityOverLifetime.linear.y\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.linear.y,\n 0\n )\n : 0,\n velocityOverLifetime.linear.z\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.linear.z,\n 0\n )\n : 0\n ),\n valueModifiers: {\n x: isLifeTimeCurve(velocityOverLifetime.linear.x || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.linear.x as LifetimeCurve\n )\n : undefined,\n y: isLifeTimeCurve(velocityOverLifetime.linear.y || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.linear.y as LifetimeCurve\n )\n : undefined,\n z: isLifeTimeCurve(velocityOverLifetime.linear.z || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.linear.z as LifetimeCurve\n )\n : undefined,\n },\n })\n );\n\n generalData.orbitalVelocityData = Array.from(\n { length: maxParticles },\n () => ({\n speed: new THREE.Vector3(\n velocityOverLifetime.orbital.x\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.x,\n 0\n )\n : 0,\n velocityOverLifetime.orbital.y\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.y,\n 0\n )\n : 0,\n velocityOverLifetime.orbital.z\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.z,\n 0\n )\n : 0\n ),\n valueModifiers: {\n x: isLifeTimeCurve(velocityOverLifetime.orbital.x || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.x as LifetimeCurve\n )\n : undefined,\n y: isLifeTimeCurve(velocityOverLifetime.orbital.y || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.y as LifetimeCurve\n )\n : undefined,\n z: isLifeTimeCurve(velocityOverLifetime.orbital.z || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.z as LifetimeCurve\n )\n : undefined,\n },\n positionOffset: new THREE.Vector3(),\n })\n );\n }\n\n const startValueKeys: Array<keyof NormalizedParticleSystemConfig> = [\n 'startSize',\n 'startOpacity',\n ];\n startValueKeys.forEach((key) => {\n generalData.startValues[key] = Array.from({ length: maxParticles }, () =>\n calculateValue(\n generalData.particleSystemId,\n normalizedConfig[key] as\n | Constant\n | RandomBetweenTwoConstants\n | LifetimeCurve,\n 0\n )\n );\n });\n\n generalData.startValues.startColorR = Array.from(\n { length: maxParticles },\n () => 0\n );\n generalData.startValues.startColorG = Array.from(\n { length: maxParticles },\n () => 0\n );\n generalData.startValues.startColorB = Array.from(\n { length: maxParticles },\n () => 0\n );\n\n const lifetimeValueKeys: Array<keyof NormalizedParticleSystemConfig> = [\n 'rotationOverLifetime',\n ];\n lifetimeValueKeys.forEach((key) => {\n const value = normalizedConfig[key] as {\n isActive: boolean;\n } & RandomBetweenTwoConstants;\n if (value.isActive)\n generalData.lifetimeValues[key] = Array.from(\n { length: maxParticles },\n () => THREE.MathUtils.randFloat(value.min!, value.max!)\n );\n });\n\n // Pre-compute FBM normalisation divisor once (avoids recalculating every frame).\n // fbmMax = 1 + 0.5 + 0.25 + ... = 2 - 2^(-octaves)\n const fbmMax = 2 - Math.pow(2, -noise.octaves);\n\n generalData.noise = {\n isActive: noise.isActive,\n strength: noise.strength,\n noisePower: 0.15 * noise.strength,\n frequency: noise.frequency,\n positionAmount: noise.positionAmount,\n rotationAmount: noise.rotationAmount,\n sizeAmount: noise.sizeAmount,\n fbmMax,\n sampler: noise.isActive\n ? new FBM({\n seed: Math.random(),\n scale: noise.frequency,\n octaves: noise.octaves,\n })\n : undefined,\n offsets: noise.useRandomOffset\n ? Array.from({ length: maxParticles }, () => Math.random() * 100)\n : undefined,\n };\n\n // Initialize burst states if bursts are configured\n if (emission.bursts && emission.bursts.length > 0) {\n generalData.burstStates = emission.bursts.map(() => ({\n cyclesExecuted: 0,\n lastCycleTime: 0,\n probabilityPassed: false,\n }));\n }\n\n const useTrail = renderer.rendererType === RendererType.TRAIL;\n const useMesh = renderer.rendererType === RendererType.MESH;\n const useInstancing =\n !useTrail && !useMesh && renderer.rendererType === RendererType.INSTANCED;\n const useInstancedAttributes = useInstancing || useMesh;\n\n // Trail config defaults\n const defaultTrailCurve: LifetimeCurve = {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 0, percentage: 1 },\n ],\n };\n const trailConfig = useTrail\n ? {\n length: renderer.trail?.length ?? 20,\n width: renderer.trail?.width ?? 1.0,\n widthOverTrail: normalizeTrailCurve(\n renderer.trail?.widthOverTrail,\n defaultTrailCurve\n ),\n opacityOverTrail: normalizeTrailCurve(\n renderer.trail?.opacityOverTrail,\n defaultTrailCurve\n ),\n colorOverTrail: renderer.trail?.colorOverTrail,\n minVertexDistance: renderer.trail?.minVertexDistance ?? 0,\n maxTime: renderer.trail?.maxTime ?? 0,\n smoothing: renderer.trail?.smoothing ?? false,\n smoothingSubdivisions: renderer.trail?.smoothingSubdivisions ?? 3,\n twistPrevention: renderer.trail?.twistPrevention ?? false,\n ribbonId: renderer.trail?.ribbonId,\n }\n : undefined;\n\n // Initialize trail position history buffers\n if (useTrail && trailConfig) {\n const trailLength = trailConfig.length;\n generalData.trailLength = trailLength;\n generalData.positionHistory = new Float32Array(\n maxParticles * trailLength * 3\n );\n generalData.positionHistoryIndex = new Uint16Array(maxParticles);\n generalData.positionHistoryCount = new Uint16Array(maxParticles);\n\n // Adaptive sampling: track last sampled position per particle\n if (trailConfig.minVertexDistance > 0) {\n generalData.trailLastSampledPosition = new Float32Array(maxParticles * 3);\n }\n\n // Max time: track timestamp of each history sample\n if (trailConfig.maxTime > 0) {\n generalData.trailSampleTimes = new Float64Array(\n maxParticles * trailLength\n );\n }\n\n // Twist prevention: store previous ribbon normal per particle\n if (trailConfig.twistPrevention) {\n generalData.trailPrevNormal = new Float32Array(maxParticles * 3);\n }\n }\n\n // Attribute name prefix: instanced/mesh renderers use 'instance'-prefixed names\n // to avoid collision with the base geometry's own 'position' attribute.\n const attr = (name: string) =>\n useInstancedAttributes\n ? `instance${name.charAt(0).toUpperCase()}${name.slice(1)}`\n : name;\n\n // Position attribute is special: Points uses 'position', instanced/mesh uses 'instanceOffset'\n const posAttr = useInstancedAttributes ? 'instanceOffset' : 'position';\n\n const softParticlesEnabled = !!(\n renderer.softParticles?.enabled && renderer.softParticles?.depthTexture\n );\n\n const sharedUniforms: Record<string, { value: unknown }> = {\n elapsed: { value: 0.0 },\n map: { value: particleMap },\n tiles: {\n value: new THREE.Vector2(\n textureSheetAnimation.tiles?.x ?? 1,\n textureSheetAnimation.tiles?.y ?? 1\n ),\n },\n fps: { value: textureSheetAnimation.fps },\n useFPSForFrameIndex: {\n value: textureSheetAnimation.timeMode === TimeMode.FPS,\n },\n backgroundColor: { value: renderer.backgroundColor },\n discardBackgroundColor: { value: renderer.discardBackgroundColor },\n backgroundColorTolerance: { value: renderer.backgroundColorTolerance },\n ...(useInstancing ? { viewportHeight: { value: 1.0 } } : {}),\n softParticlesEnabled: { value: softParticlesEnabled },\n softParticlesIntensity: {\n value: Math.max(renderer.softParticles?.intensity ?? 1.0, 0.001),\n },\n sceneDepthTexture: {\n value: renderer.softParticles?.depthTexture ?? null,\n },\n cameraNearFar: { value: new THREE.Vector2(0.1, 1000.0) },\n };\n\n const getVertexShader = () => {\n if (useMesh) return MeshParticleVertexShader;\n if (useInstancing) return InstancedParticleVertexShader;\n return ParticleSystemVertexShader;\n };\n\n const getFragmentShader = () => {\n if (useMesh) return MeshParticleFragmentShader;\n if (useInstancing) return InstancedParticleFragmentShader;\n return ParticleSystemFragmentShader;\n };\n\n // Determine whether to use TSL materials (WebGPU path).\n // TSL is used whenever the factory is registered — regardless of simulationBackend.\n // This ensures WebGPURenderer always gets NodeMaterial (not GLSL ShaderMaterial).\n const useTSL = _tslMaterialFactory !== null;\n\n // Determine whether to use GPU compute for simulation.\n // GPU compute requires: TSL active + not trail + backend != CPU + compute factory registered.\n const useGPUCompute =\n useTSL &&\n !useTrail &&\n normalizedConfig.simulationBackend !== SimulationBackend.CPU &&\n !!_tslMaterialFactory?.createComputePipeline &&\n !!_tslMaterialFactory.writeParticleToModifierBuffers &&\n !!_tslMaterialFactory.deactivateParticleInModifierBuffers &&\n !!_tslMaterialFactory.flushEmitQueue;\n\n // Create GPU compute pipeline when active\n type GPUComputePipeline =\n import('./webgpu/compute-modifiers.js').ModifierComputePipeline;\n let gpuPipeline: GPUComputePipeline | null = null;\n\n if (useGPUCompute) {\n gpuPipeline = _tslMaterialFactory!.createComputePipeline!(\n maxParticles,\n useInstancedAttributes,\n normalizedConfig,\n generalData.particleSystemId,\n normalizedForceFields.length,\n normalizedCollisionPlanes.length\n );\n // Register the curveDataLength so the init data helpers know the offset.\n if (gpuPipeline && _tslMaterialFactory!.registerCurveDataLength) {\n _tslMaterialFactory!.registerCurveDataLength(\n gpuPipeline.buffers,\n gpuPipeline.curveDataLength\n );\n }\n }\n\n const rendererConfig = {\n transparent: renderer.transparent,\n blending: renderer.blending,\n depthTest: renderer.depthTest,\n depthWrite: renderer.depthWrite,\n };\n\n const material: THREE.Material = useTSL\n ? _tslMaterialFactory!.createTSLParticleMaterial(\n renderer.rendererType ?? RendererType.POINTS,\n sharedUniforms,\n rendererConfig,\n useGPUCompute\n )\n : new THREE.ShaderMaterial({\n uniforms: sharedUniforms,\n vertexShader: getVertexShader(),\n fragmentShader: getFragmentShader(),\n ...rendererConfig,\n });\n\n let geometry: THREE.BufferGeometry | THREE.InstancedBufferGeometry;\n\n if (useMesh) {\n const meshConfig = renderer.mesh;\n if (!meshConfig?.geometry) {\n throw new Error(\n 'RendererType.MESH requires a mesh configuration with a geometry. ' +\n 'Set renderer.mesh.geometry to a THREE.BufferGeometry instance.'\n );\n }\n const instancedGeometry = new THREE.InstancedBufferGeometry();\n // Copy base mesh geometry attributes (position, normal, uv, index)\n const sourceGeom = meshConfig.geometry;\n const srcPos = sourceGeom.getAttribute('position');\n if (srcPos) instancedGeometry.setAttribute('position', srcPos);\n const srcNormal = sourceGeom.getAttribute('normal');\n if (srcNormal) instancedGeometry.setAttribute('normal', srcNormal);\n const srcUv = sourceGeom.getAttribute('uv');\n if (srcUv) instancedGeometry.setAttribute('uv', srcUv);\n const srcIndex = sourceGeom.getIndex();\n if (srcIndex) instancedGeometry.setIndex(srcIndex);\n instancedGeometry.instanceCount = maxParticles;\n geometry = instancedGeometry;\n } else if (useInstancing) {\n const instancedGeometry = new THREE.InstancedBufferGeometry();\n // Base quad: 1x1 plane centred at origin (vertices from -0.5 to 0.5)\n const quadPositions = new Float32Array([\n -0.5, -0.5, 0, 0.5, -0.5, 0, 0.5, 0.5, 0, -0.5, 0.5, 0,\n ]);\n const quadIndices = new Uint16Array([0, 1, 2, 0, 2, 3]);\n instancedGeometry.setAttribute(\n 'position',\n new THREE.BufferAttribute(quadPositions, 3)\n );\n instancedGeometry.setIndex(new THREE.BufferAttribute(quadIndices, 1));\n instancedGeometry.instanceCount = maxParticles;\n geometry = instancedGeometry;\n } else {\n geometry = new THREE.BufferGeometry();\n }\n\n for (let i = 0; i < maxParticles; i++)\n calculatePositionAndVelocity(\n generalData,\n shape,\n startSpeed,\n startPositions[i],\n velocities[i]\n );\n\n // Create interleaved buffer for all scalar per-particle attributes.\n // In GPU compute mode this is kept for CPU death detection reads only\n // (not set as geometry attributes — storage buffers are used instead).\n const scalarArray = new Float32Array(maxParticles * SCALAR_STRIDE);\n\n // Pre-fill initial values\n for (let i = 0; i < maxParticles; i++) {\n const base = i * SCALAR_STRIDE;\n scalarArray[base + S_IS_ACTIVE] = 0;\n scalarArray[base + S_LIFETIME] = 0;\n scalarArray[base + S_START_LIFETIME] =\n calculateValue(generalData.particleSystemId, startLifetime, 0) * 1000;\n scalarArray[base + S_START_FRAME] = textureSheetAnimation.startFrame\n ? calculateValue(\n generalData.particleSystemId,\n textureSheetAnimation.startFrame,\n 0\n )\n : 0;\n scalarArray[base + S_SIZE] = generalData.startValues.startSize[i];\n scalarArray[base + S_ROTATION] = 0;\n const colorRandomRatio = Math.random();\n scalarArray[base + S_COLOR_R] =\n startColor.min!.r! +\n colorRandomRatio * (startColor.max!.r! - startColor.min!.r!);\n scalarArray[base + S_COLOR_G] =\n startColor.min!.g! +\n colorRandomRatio * (startColor.max!.g! - startColor.min!.g!);\n scalarArray[base + S_COLOR_B] =\n startColor.min!.b! +\n colorRandomRatio * (startColor.max!.b! - startColor.min!.b!);\n scalarArray[base + S_COLOR_A] = 0;\n }\n\n // Always create the interleaved buffer (needed for CPU death detection\n // and the CPU rendering path)\n const scalarInterleavedBuffer = useInstancedAttributes\n ? new THREE.InstancedInterleavedBuffer(scalarArray, SCALAR_STRIDE)\n : new THREE.InterleavedBuffer(scalarArray, SCALAR_STRIDE);\n\n if (useGPUCompute && gpuPipeline) {\n // ── GPU Compute Path: use storage buffers as geometry attributes ──\n // StorageBufferAttribute extends BufferAttribute, so these work as\n // geometry attributes read by the TSL material.\n // GPU path: 5 geometry attributes total (under 8 vertex buffer limit)\n // 1. base quad position (for instanced/mesh)\n // 2. particle position (vec3)\n // 3. color (vec4: R,G,B,A)\n // 4. particleState (vec4: lifetime, size, rotation, startFrame)\n // 5. startValues (vec4: startLifetime, startSize, startOpacity, startColorR)\n const gpuBuf = gpuPipeline.buffers;\n geometry.setAttribute(posAttr, gpuBuf.position);\n geometry.setAttribute(attr('color'), gpuBuf.color);\n geometry.setAttribute(attr('particleState'), gpuBuf.particleState);\n geometry.setAttribute(attr('startValues'), gpuBuf.startValues);\n } else {\n // ── CPU Path: position + interleaved scalar attributes ──\n const positionArray = new Float32Array(maxParticles * 3);\n for (let i = 0; i < maxParticles; i++) {\n positionArray[i * 3] = startPositions[i].x;\n positionArray[i * 3 + 1] = startPositions[i].y;\n positionArray[i * 3 + 2] = startPositions[i].z;\n }\n const positionAttribute = useInstancedAttributes\n ? new THREE.InstancedBufferAttribute(positionArray, 3)\n : new THREE.BufferAttribute(positionArray, 3);\n geometry.setAttribute(posAttr, positionAttribute);\n\n geometry.setAttribute(\n attr('isActive'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_IS_ACTIVE\n )\n );\n geometry.setAttribute(\n attr('lifetime'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_LIFETIME\n )\n );\n geometry.setAttribute(\n attr('startLifetime'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_START_LIFETIME\n )\n );\n geometry.setAttribute(\n attr('startFrame'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_START_FRAME\n )\n );\n geometry.setAttribute(\n attr('size'),\n new THREE.InterleavedBufferAttribute(scalarInterleavedBuffer, 1, S_SIZE)\n );\n geometry.setAttribute(\n attr('rotation'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_ROTATION\n )\n );\n // Packed RGBA color as single vec4 (R/G/B/A are contiguous in the\n // interleaved buffer at offsets 6,7,8,9 — read as a vec4 from offset 6)\n geometry.setAttribute(\n attr('color'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 4,\n S_COLOR_R\n )\n );\n }\n\n // Packed quaternion vec4 attribute for 3D mesh rotation (only for MESH renderer,\n // CPU path only — GPU compute derives quaternion from particleState.z in the shader)\n if (useMesh && !useGPUCompute) {\n const quatArray = new Float32Array(maxParticles * 4);\n // Initialize to identity quaternion (0, 0, 0, 1)\n for (let i = 0; i < maxParticles; i++) {\n quatArray[i * 4 + 3] = 1; // w = 1\n }\n geometry.setAttribute(\n attr('quat'),\n new THREE.InstancedBufferAttribute(quatArray, 4)\n );\n }\n\n // Resolve per-particle attribute accessors (instanced/mesh uses prefixed names)\n const a = geometry.attributes;\n const aIsActive = a[attr('isActive')];\n const aColor = a[attr('color')];\n const aStartFrame = a[attr('startFrame')];\n const aStartLifetime = a[attr('startLifetime')];\n const aSize = a[attr('size')];\n const aRotation = a[attr('rotation')];\n const aLifetime = a[attr('lifetime')];\n const aPosition = a[posAttr];\n const aQuat = useMesh && !useGPUCompute ? a[attr('quat')] : undefined;\n\n const deactivateParticle = (particleIndex: number) => {\n const base = particleIndex * SCALAR_STRIDE;\n scalarArray[base + S_IS_ACTIVE] = 0;\n scalarArray[base + S_COLOR_A] = 0;\n if (useGPUCompute && gpuPipeline) {\n _tslMaterialFactory!.deactivateParticleInModifierBuffers!(\n gpuPipeline.buffers,\n particleIndex\n );\n } else {\n scalarInterleavedBuffer.needsUpdate = true;\n }\n freeList.push(particleIndex);\n };\n\n const activateParticle = ({\n particleIndex,\n activationTime,\n position,\n }: {\n particleIndex: number;\n activationTime: number;\n position: Required<Point3D>;\n }) => {\n const base = particleIndex * SCALAR_STRIDE;\n scalarArray[base + S_IS_ACTIVE] = 1;\n generalData.creationTimes[particleIndex] = activationTime;\n\n // Reset trail history so a recycled particle doesn't inherit old trail\n if (generalData.positionHistoryCount) {\n generalData.positionHistoryCount[particleIndex] = 0;\n generalData.positionHistoryIndex![particleIndex] = 0;\n\n // Reset adaptive sampling last position\n if (generalData.trailLastSampledPosition) {\n const lsIdx = particleIndex * 3;\n generalData.trailLastSampledPosition[lsIdx] = 0;\n generalData.trailLastSampledPosition[lsIdx + 1] = 0;\n generalData.trailLastSampledPosition[lsIdx + 2] = 0;\n }\n\n // Reset twist prevention normal\n if (generalData.trailPrevNormal) {\n const nIdx = particleIndex * 3;\n generalData.trailPrevNormal[nIdx] = 0;\n generalData.trailPrevNormal[nIdx + 1] = 0;\n generalData.trailPrevNormal[nIdx + 2] = 0;\n }\n }\n\n if (generalData.noise.offsets)\n generalData.noise.offsets[particleIndex] = Math.random() * 100;\n\n const colorRandomRatio = Math.random();\n const cfgStartColor = normalizedConfig.startColor;\n\n scalarArray[base + S_COLOR_R] =\n cfgStartColor.min!.r! +\n colorRandomRatio * (cfgStartColor.max!.r! - cfgStartColor.min!.r!);\n\n scalarArray[base + S_COLOR_G] =\n cfgStartColor.min!.g! +\n colorRandomRatio * (cfgStartColor.max!.g! - cfgStartColor.min!.g!);\n\n scalarArray[base + S_COLOR_B] =\n cfgStartColor.min!.b! +\n colorRandomRatio * (cfgStartColor.max!.b! - cfgStartColor.min!.b!);\n\n generalData.startValues.startColorR[particleIndex] =\n scalarArray[base + S_COLOR_R];\n generalData.startValues.startColorG[particleIndex] =\n scalarArray[base + S_COLOR_G];\n generalData.startValues.startColorB[particleIndex] =\n scalarArray[base + S_COLOR_B];\n\n scalarArray[base + S_START_FRAME] = normalizedConfig.textureSheetAnimation\n .startFrame\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.textureSheetAnimation.startFrame,\n 0\n )\n : 0;\n\n scalarArray[base + S_START_LIFETIME] =\n calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startLifetime,\n generalData.normalizedLifetimePercentage\n ) * 1000;\n\n generalData.startValues.startSize[particleIndex] = calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startSize,\n generalData.normalizedLifetimePercentage\n );\n scalarArray[base + S_SIZE] =\n generalData.startValues.startSize[particleIndex];\n\n generalData.startValues.startOpacity[particleIndex] = calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startOpacity,\n generalData.normalizedLifetimePercentage\n );\n scalarArray[base + S_COLOR_A] =\n generalData.startValues.startOpacity[particleIndex];\n\n scalarArray[base + S_ROTATION] = calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startRotation,\n generalData.normalizedLifetimePercentage\n );\n\n // Initialize mesh particle quaternion from the Z-rotation startRotation\n if (aQuat) {\n const rotZ = scalarArray[base + S_ROTATION];\n const halfZ = rotZ * 0.5;\n const qi = particleIndex * 4;\n aQuat.array[qi] = 0;\n aQuat.array[qi + 1] = 0;\n aQuat.array[qi + 2] = Math.sin(halfZ);\n aQuat.array[qi + 3] = Math.cos(halfZ);\n aQuat.needsUpdate = true;\n }\n\n if (normalizedConfig.rotationOverLifetime.isActive)\n generalData.lifetimeValues.rotationOverLifetime[particleIndex] =\n THREE.MathUtils.randFloat(\n normalizedConfig.rotationOverLifetime.min!,\n normalizedConfig.rotationOverLifetime.max!\n );\n\n calculatePositionAndVelocity(\n generalData,\n normalizedConfig.shape,\n normalizedConfig.startSpeed,\n startPositions[particleIndex],\n velocities[particleIndex]\n );\n // GPU compute: position is set via the emit scatter in the compute shader\n // (writeParticleToModifierBuffers queues it). Do NOT set needsUpdate —\n // that triggers a full CPU→GPU upload that overwrites GPU-computed\n // positions for all particles.\n // However, we still write the CPU-side array so death sub-emitters can\n // read the particle's approximate position without GPU readback.\n {\n const positionIndex = particleIndex * 3;\n aPosition.array[positionIndex] =\n position.x + startPositions[particleIndex].x;\n aPosition.array[positionIndex + 1] =\n position.y + startPositions[particleIndex].y;\n aPosition.array[positionIndex + 2] =\n position.z + startPositions[particleIndex].z;\n if (!useGPUCompute) {\n aPosition.needsUpdate = true;\n }\n }\n\n if (generalData.linearVelocityData) {\n generalData.linearVelocityData[particleIndex].speed.set(\n normalizedConfig.velocityOverLifetime.linear.x\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.linear.x,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.linear.y\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.linear.y,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.linear.z\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.linear.z,\n 0\n )\n : 0\n );\n }\n\n if (generalData.orbitalVelocityData) {\n generalData.orbitalVelocityData[particleIndex].speed.set(\n normalizedConfig.velocityOverLifetime.orbital.x\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.orbital.x,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.orbital.y\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.orbital.y,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.orbital.z\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.orbital.z,\n 0\n )\n : 0\n );\n generalData.orbitalVelocityData[particleIndex].positionOffset.set(\n startPositions[particleIndex].x,\n startPositions[particleIndex].y,\n startPositions[particleIndex].z\n );\n }\n\n scalarArray[base + S_LIFETIME] = 0;\n\n if (useGPUCompute && gpuPipeline) {\n // Write all particle data to GPU storage buffers\n _tslMaterialFactory!.writeParticleToModifierBuffers!(\n gpuPipeline.buffers,\n particleIndex,\n {\n position: {\n x: position.x + startPositions[particleIndex].x,\n y: position.y + startPositions[particleIndex].y,\n z: position.z + startPositions[particleIndex].z,\n },\n velocity: {\n x: velocities[particleIndex].x,\n y: velocities[particleIndex].y,\n z: velocities[particleIndex].z,\n },\n startLifetime: scalarArray[base + S_START_LIFETIME],\n colorA: scalarArray[base + S_COLOR_A],\n size: scalarArray[base + S_SIZE],\n rotation: scalarArray[base + S_ROTATION],\n colorR: scalarArray[base + S_COLOR_R],\n colorG: scalarArray[base + S_COLOR_G],\n colorB: scalarArray[base + S_COLOR_B],\n startSize: generalData.startValues.startSize[particleIndex],\n startOpacity: generalData.startValues.startOpacity[particleIndex],\n startColorR: generalData.startValues.startColorR[particleIndex],\n startColorG: generalData.startValues.startColorG[particleIndex],\n startColorB: generalData.startValues.startColorB[particleIndex],\n rotationSpeed: generalData.lifetimeValues.rotationOverLifetime\n ? generalData.lifetimeValues.rotationOverLifetime[particleIndex]\n : 0,\n noiseOffset: generalData.noise.offsets\n ? generalData.noise.offsets[particleIndex]\n : 0,\n startFrame: scalarArray[base + S_START_FRAME],\n orbitalOffset: {\n x: startPositions[particleIndex].x,\n y: startPositions[particleIndex].y,\n z: startPositions[particleIndex].z,\n },\n }\n );\n // Modifiers run on GPU — no CPU applyModifiers needed\n } else {\n scalarInterleavedBuffer.needsUpdate = true;\n\n applyModifiers({\n delta: 0,\n generalData,\n normalizedConfig,\n attributes: mappedAttributes,\n scalarArray,\n particleLifetimePercentage: 0,\n particleIndex,\n });\n }\n };\n\n // Sub-emitter setup\n const subEmitterArr: Array<SubEmitterConfig> = subEmitters ?? [];\n const deathSubEmitters = subEmitterArr.filter(\n (s) => (s.trigger ?? SubEmitterTrigger.DEATH) === SubEmitterTrigger.DEATH\n );\n const birthSubEmitters = subEmitterArr.filter(\n (s) => s.trigger === SubEmitterTrigger.BIRTH\n );\n // Track sub-emitter instances per config for per-config maxInstances enforcement\n const subEmitterInstancesMap = new Map<\n SubEmitterConfig,\n Array<ParticleSystem>\n >();\n for (const cfg of subEmitterArr) {\n subEmitterInstancesMap.set(cfg, []);\n }\n\n const cleanupCompletedInstances = (instances: Array<ParticleSystem>) => {\n for (let i = instances.length - 1; i >= 0; i--) {\n const sub = instances[i];\n const obj3d =\n sub.instance instanceof THREE.Points ||\n sub.instance instanceof THREE.Mesh\n ? sub.instance\n : (sub.instance.children[0] as THREE.Points | THREE.Mesh | undefined);\n const geomAttrs = (obj3d as THREE.Points | THREE.Mesh | undefined)\n ?.geometry?.attributes;\n const isActiveAttr = geomAttrs\n ? (geomAttrs.isActive ?? geomAttrs.instanceIsActive)\n : undefined;\n if (!isActiveAttr) {\n sub.dispose();\n instances.splice(i, 1);\n continue;\n }\n let hasActive = false;\n for (let j = 0; j < isActiveAttr.count; j++) {\n if (isActiveAttr.getX(j)) {\n hasActive = true;\n break;\n }\n }\n if (!hasActive) {\n sub.dispose();\n instances.splice(i, 1);\n }\n }\n };\n\n const spawnSubEmitters = (\n configs: Array<SubEmitterConfig>,\n position: THREE.Vector3,\n velocity: THREE.Vector3,\n spawnNow: number\n ) => {\n for (const subConfig of configs) {\n const instances = subEmitterInstancesMap.get(subConfig)!;\n const maxInst = subConfig.maxInstances ?? 32;\n if (instances.length >= maxInst) {\n cleanupCompletedInstances(instances);\n if (instances.length >= maxInst) continue;\n }\n\n const inheritVelocity = subConfig.inheritVelocity ?? 0;\n const subSystem = createParticleSystem(\n {\n ...subConfig.config,\n looping: false,\n // Sub-emitters must always use CPU simulation because their compute\n // nodes cannot be dispatched independently by the parent system.\n simulationBackend: SimulationBackend.CPU,\n transform: {\n ...subConfig.config.transform,\n position: new THREE.Vector3(position.x, position.y, position.z),\n },\n renderer: {\n ...(subConfig.config.renderer ?? {}),\n ...(subConfig.config.renderer?.rendererType\n ? {}\n : renderer.rendererType === RendererType.MESH ||\n renderer.rendererType === RendererType.TRAIL\n ? {}\n : { rendererType: renderer.rendererType }),\n } as typeof subConfig.config.renderer,\n ...(inheritVelocity > 0\n ? {\n startSpeed:\n (typeof subConfig.config.startSpeed === 'number'\n ? subConfig.config.startSpeed\n : typeof subConfig.config.startSpeed === 'object' &&\n subConfig.config.startSpeed !== null &&\n 'min' in subConfig.config.startSpeed\n ? ((\n subConfig.config\n .startSpeed as RandomBetweenTwoConstants\n ).min ?? 0)\n : 0) +\n velocity.length() * inheritVelocity,\n }\n : {}),\n },\n spawnNow\n );\n\n const parentObj = (wrapper || particleSystem).parent;\n if (parentObj) parentObj.add(subSystem.instance);\n\n instances.push(subSystem);\n }\n };\n\n // Trail mesh setup: ribbon geometry + material (created only for TRAIL mode)\n let trailMesh: THREE.Mesh | undefined;\n let trailGeometry: THREE.BufferGeometry | undefined;\n let trailPositionAttr: THREE.BufferAttribute | undefined;\n let trailAlphaAttr: THREE.BufferAttribute | undefined;\n let trailColorAttr: THREE.BufferAttribute | undefined;\n let trailNextAttr: THREE.BufferAttribute | undefined;\n let trailHalfWidthAttr: THREE.BufferAttribute | undefined;\n let trailUVAttr: THREE.BufferAttribute | undefined;\n let trailIndexAttr: THREE.BufferAttribute | undefined;\n let trailWidthCurveFn: CurveFunction | undefined;\n let trailOpacityCurveFn: CurveFunction | undefined;\n let trailColorOverTrailFns:\n | { r: CurveFunction; g: CurveFunction; b: CurveFunction }\n | undefined;\n\n if (useTrail && trailConfig) {\n const trailLength = trailConfig.length;\n // Each particle contributes (trailLength) vertices (2 per segment joint: left+right)\n // Segments = trailLength - 1, so 2 * trailLength vertices per particle\n const verticesPerParticle = trailLength * 2;\n const totalVertices = maxParticles * verticesPerParticle;\n // Each segment (between 2 consecutive history points) = 2 triangles = 6 indices\n const indicesPerParticle = (trailLength - 1) * 6;\n const totalIndices = maxParticles * indicesPerParticle;\n\n trailGeometry = new THREE.BufferGeometry();\n const trailPositions = new Float32Array(totalVertices * 3);\n const trailNextPositions = new Float32Array(totalVertices * 3);\n const trailAlphas = new Float32Array(totalVertices);\n const trailColors = new Float32Array(totalVertices * 4);\n const trailOffsets = new Float32Array(totalVertices);\n const trailHalfWidths = new Float32Array(totalVertices);\n const trailUVs = new Float32Array(totalVertices * 2);\n const trailIndices = new Uint32Array(totalIndices);\n\n // Pre-build index buffer and static offset attribute (-1/+1 per side)\n for (let p = 0; p < maxParticles; p++) {\n const vertBase = p * verticesPerParticle;\n const idxBase = p * indicesPerParticle;\n for (let s = 0; s < trailLength; s++) {\n trailOffsets[vertBase + s * 2] = -1.0; // left\n trailOffsets[vertBase + s * 2 + 1] = 1.0; // right\n }\n for (let s = 0; s < trailLength - 1; s++) {\n const i = idxBase + s * 6;\n const v = vertBase + s * 2;\n trailIndices[i] = v;\n trailIndices[i + 1] = v + 1;\n trailIndices[i + 2] = v + 2;\n trailIndices[i + 3] = v + 1;\n trailIndices[i + 4] = v + 3;\n trailIndices[i + 5] = v + 2;\n }\n }\n\n trailPositionAttr = new THREE.BufferAttribute(trailPositions, 3);\n trailPositionAttr.setUsage(THREE.DynamicDrawUsage);\n trailNextAttr = new THREE.BufferAttribute(trailNextPositions, 3);\n trailNextAttr.setUsage(THREE.DynamicDrawUsage);\n trailAlphaAttr = new THREE.BufferAttribute(trailAlphas, 1);\n trailAlphaAttr.setUsage(THREE.DynamicDrawUsage);\n trailColorAttr = new THREE.BufferAttribute(trailColors, 4);\n trailColorAttr.setUsage(THREE.DynamicDrawUsage);\n trailHalfWidthAttr = new THREE.BufferAttribute(trailHalfWidths, 1);\n trailHalfWidthAttr.setUsage(THREE.DynamicDrawUsage);\n trailUVAttr = new THREE.BufferAttribute(trailUVs, 2);\n trailUVAttr.setUsage(THREE.DynamicDrawUsage);\n trailIndexAttr = new THREE.BufferAttribute(trailIndices, 1);\n\n trailGeometry.setAttribute('position', trailPositionAttr);\n trailGeometry.setAttribute('trailNext', trailNextAttr);\n trailGeometry.setAttribute('trailAlpha', trailAlphaAttr);\n trailGeometry.setAttribute('trailColor', trailColorAttr);\n trailGeometry.setAttribute(\n 'trailOffset',\n new THREE.BufferAttribute(trailOffsets, 1)\n );\n trailGeometry.setAttribute('trailHalfWidth', trailHalfWidthAttr);\n trailGeometry.setAttribute('trailUV', trailUVAttr);\n trailGeometry.setIndex(trailIndexAttr);\n\n const trailUniformValues = {\n map: { value: particleMap },\n useMap: { value: !!particleMap },\n discardBackgroundColor: { value: renderer.discardBackgroundColor },\n backgroundColor: { value: renderer.backgroundColor },\n backgroundColorTolerance: { value: renderer.backgroundColorTolerance },\n softParticlesEnabled: { value: softParticlesEnabled },\n softParticlesIntensity: {\n value: Math.max(renderer.softParticles?.intensity ?? 1.0, 0.001),\n },\n sceneDepthTexture: {\n value: renderer.softParticles?.depthTexture ?? null,\n },\n cameraNearFar: { value: new THREE.Vector2(0.1, 1000.0) },\n };\n\n const trailMaterial: THREE.Material = useTSL\n ? _tslMaterialFactory!.createTSLTrailMaterial(\n trailUniformValues,\n rendererConfig\n )\n : new THREE.ShaderMaterial({\n uniforms: trailUniformValues,\n vertexShader: TrailVertexShader,\n fragmentShader: TrailFragmentShader,\n ...rendererConfig,\n side: THREE.DoubleSide,\n });\n\n trailMesh = new THREE.Mesh(trailGeometry, trailMaterial);\n trailMesh.frustumCulled = false;\n\n // Capture camera world position each frame for billboard trail ribbons\n const trailCameraPos = new THREE.Vector3();\n trailMesh.onBeforeRender = (\n _renderer: THREE.WebGLRenderer,\n _scene: THREE.Scene,\n camera: THREE.Camera\n ) => {\n camera.getWorldPosition(trailCameraPos);\n if (\n softParticlesEnabled &&\n (camera as THREE.PerspectiveCamera).isPerspectiveCamera\n ) {\n const perspCam = camera as THREE.PerspectiveCamera;\n (trailUniformValues.cameraNearFar.value as THREE.Vector2).set(\n perspCam.near,\n perspCam.far\n );\n }\n };\n generalData.trailCameraPosition = trailCameraPos;\n\n // Pre-compute curve functions for trail width/opacity\n trailWidthCurveFn = getCurveFunctionFromConfig(\n generalData.particleSystemId,\n trailConfig.widthOverTrail\n );\n trailOpacityCurveFn = getCurveFunctionFromConfig(\n generalData.particleSystemId,\n trailConfig.opacityOverTrail\n );\n\n if (trailConfig.colorOverTrail?.isActive) {\n trailColorOverTrailFns = {\n r: getCurveFunctionFromConfig(\n generalData.particleSystemId,\n normalizeTrailCurve(trailConfig.colorOverTrail.r, defaultTrailCurve)\n ),\n g: getCurveFunctionFromConfig(\n generalData.particleSystemId,\n normalizeTrailCurve(trailConfig.colorOverTrail.g, defaultTrailCurve)\n ),\n b: getCurveFunctionFromConfig(\n generalData.particleSystemId,\n normalizeTrailCurve(trailConfig.colorOverTrail.b, defaultTrailCurve)\n ),\n };\n }\n }\n\n let particleSystem: THREE.Points | THREE.Mesh =\n useInstancing || useMesh\n ? new THREE.Mesh(geometry, material)\n : new THREE.Points(geometry, material);\n\n // Late-bound ref so onBeforeRender can access instanceData (assigned later).\n const _instanceRef: { current: ParticleSystemInstance | null } = {\n current: null,\n };\n\n if (useInstancing || softParticlesEnabled || useGPUCompute) {\n particleSystem.onBeforeRender = (\n glRenderer: THREE.WebGLRenderer,\n _scene: THREE.Scene,\n camera: THREE.Camera\n ) => {\n if (useInstancing) {\n const size = glRenderer.getSize(new THREE.Vector2());\n sharedUniforms.viewportHeight.value =\n size.y * glRenderer.getPixelRatio();\n }\n if (\n softParticlesEnabled &&\n (camera as THREE.PerspectiveCamera).isPerspectiveCamera\n ) {\n const perspCam = camera as THREE.PerspectiveCamera;\n (sharedUniforms.cameraNearFar.value as THREE.Vector2).set(\n perspCam.near,\n perspCam.far\n );\n }\n // Note: GPU compute dispatch is done by the caller via\n // renderer.compute(system.computeNode) before renderer.render().\n };\n }\n\n // In trail mode, hide the particle points (but keep the parent visible so\n // the trail mesh child can render) and attach the visible trail mesh\n if (useTrail && trailMesh) {\n material.visible = false;\n particleSystem.add(trailMesh);\n }\n\n particleSystem.position.copy(transform!.position!);\n particleSystem.rotation.x = THREE.MathUtils.degToRad(transform.rotation!.x);\n particleSystem.rotation.y = THREE.MathUtils.degToRad(transform.rotation!.y);\n particleSystem.rotation.z = THREE.MathUtils.degToRad(transform.rotation!.z);\n particleSystem.scale.copy(transform.scale!);\n\n // Create a mapped view of attributes so the update loop and modifiers can\n // use standard names regardless of the renderer type.\n const mappedAttributes = {\n position: aPosition,\n isActive: aIsActive,\n lifetime: aLifetime,\n startLifetime: aStartLifetime,\n startFrame: aStartFrame,\n size: aSize,\n rotation: aRotation,\n color: aColor,\n ...(useMesh ? { quat: aQuat } : {}),\n };\n\n const calculatedCreationTime =\n now + calculateValue(generalData.particleSystemId, startDelay) * 1000;\n\n let wrapper: Gyroscope | undefined;\n if (normalizedConfig.simulationSpace === SimulationSpace.WORLD) {\n wrapper = new Gyroscope();\n wrapper.add(particleSystem);\n }\n\n const hasDeathSubEmitters = deathSubEmitters.length > 0;\n const hasBirthSubEmitters = birthSubEmitters.length > 0;\n\n const onParticleDeath = hasDeathSubEmitters\n ? (\n particleIndex: number,\n positionArr: THREE.TypedArray,\n velocity: THREE.Vector3,\n deathNow: number\n ) => {\n const posIdx = particleIndex * 3;\n _subEmitterPosition.set(\n positionArr[posIdx],\n positionArr[posIdx + 1],\n positionArr[posIdx + 2]\n );\n // Convert local particle position to world space so the sub-emitter\n // spawns at the correct scene position regardless of transform offset.\n if (simulationSpace === SimulationSpace.LOCAL) {\n particleSystem.localToWorld(_subEmitterPosition);\n }\n spawnSubEmitters(\n deathSubEmitters,\n _subEmitterPosition,\n velocity,\n deathNow\n );\n }\n : undefined;\n\n const onParticleBirth = hasBirthSubEmitters\n ? (\n particleIndex: number,\n positionArr: THREE.TypedArray,\n velocity: THREE.Vector3,\n birthNow: number\n ) => {\n const posIdx = particleIndex * 3;\n _subEmitterPosition.set(\n positionArr[posIdx],\n positionArr[posIdx + 1],\n positionArr[posIdx + 2]\n );\n // Convert local particle position to world space so the sub-emitter\n // spawns at the correct scene position regardless of transform offset.\n if (simulationSpace === SimulationSpace.LOCAL) {\n particleSystem.localToWorld(_subEmitterPosition);\n }\n spawnSubEmitters(\n birthSubEmitters,\n _subEmitterPosition,\n velocity,\n birthNow\n );\n }\n : undefined;\n\n const instanceData: ParticleSystemInstance = {\n particleSystem,\n wrapper,\n mappedAttributes,\n scalarArray,\n scalarInterleavedBuffer,\n elapsedUniform: sharedUniforms.elapsed as { value: number },\n generalData,\n onUpdate,\n onComplete,\n creationTime: calculatedCreationTime,\n lastEmissionTime: calculatedCreationTime,\n duration,\n looping,\n simulationSpace,\n gravity,\n normalizedForceFields,\n normalizedCollisionPlanes,\n emission,\n normalizedConfig,\n iterationCount: 0,\n velocities,\n freeList,\n deactivateParticle,\n activateParticle,\n onParticleDeath,\n onParticleBirth,\n useGPUCompute: useGPUCompute && gpuPipeline !== null,\n computePipeline: gpuPipeline ?? undefined,\n computeDispatchReady: false,\n ...(useTrail\n ? {\n trailMesh,\n trailPositionAttr,\n trailAlphaAttr,\n trailColorAttr,\n trailNextAttr: trailNextAttr as THREE.BufferAttribute,\n trailHalfWidthAttr: trailHalfWidthAttr as THREE.BufferAttribute,\n trailUVAttr: trailUVAttr as THREE.BufferAttribute,\n trailWidthCurveFn,\n trailOpacityCurveFn,\n trailColorOverTrailFns,\n trailConfig: {\n length: trailConfig!.length,\n width: trailConfig!.width,\n minVertexDistance: trailConfig!.minVertexDistance,\n maxTime: trailConfig!.maxTime,\n smoothing: trailConfig!.smoothing,\n smoothingSubdivisions: trailConfig!.smoothingSubdivisions,\n twistPrevention: trailConfig!.twistPrevention,\n ribbonId: trailConfig!.ribbonId,\n },\n }\n : {}),\n };\n\n createdParticleSystems.push(instanceData);\n _instanceRef.current = instanceData;\n\n const resumeEmitter = () => (generalData.isEnabled = true);\n const pauseEmitter = () => (generalData.isEnabled = false);\n const dispose = () => {\n for (const instances of subEmitterInstancesMap.values()) {\n for (const sub of instances) sub.dispose();\n instances.length = 0;\n }\n destroyParticleSystem(particleSystem);\n };\n const update = (cycleData: CycleData) => {\n updateParticleSystemInstance(instanceData, cycleData);\n for (const instances of subEmitterInstancesMap.values()) {\n for (const sub of instances) sub.update(cycleData);\n }\n };\n\n const updateConfig = (partialConfig: Partial<ParticleSystemConfig>) => {\n // Deep-merge partial config into the live normalizedConfig\n ObjectUtils.deepMerge(instanceData.normalizedConfig, partialConfig, {\n applyToFirstObject: true,\n skippedProperties: [],\n });\n\n const cfg = instanceData.normalizedConfig;\n\n // Update instance-level cached scalars\n if (partialConfig.gravity !== undefined) {\n instanceData.gravity = cfg.gravity;\n // Force gravityVelocity recalculation on next frame\n generalData.lastWorldQuaternion.x = -99999;\n }\n if (partialConfig.duration !== undefined)\n instanceData.duration = cfg.duration;\n if (partialConfig.looping !== undefined) instanceData.looping = cfg.looping;\n if (partialConfig.simulationSpace !== undefined)\n instanceData.simulationSpace = cfg.simulationSpace;\n if (partialConfig.emission !== undefined)\n instanceData.emission = cfg.emission;\n\n // Re-normalize force fields when changed\n if (partialConfig.forceFields !== undefined) {\n instanceData.normalizedForceFields = normalizeForceFields(\n cfg.forceFields\n );\n }\n\n // Re-normalize collision planes when changed\n if (partialConfig.collisionPlanes !== undefined) {\n instanceData.normalizedCollisionPlanes = normalizeCollisionPlanes(\n cfg.collisionPlanes\n );\n }\n\n // Re-initialize noise when changed\n if (partialConfig.noise !== undefined) {\n const n = cfg.noise;\n generalData.noise = {\n isActive: n.isActive,\n strength: n.strength,\n noisePower: 0.15 * n.strength,\n frequency: n.frequency,\n positionAmount: n.positionAmount,\n rotationAmount: n.rotationAmount,\n sizeAmount: n.sizeAmount,\n fbmMax: 2 - Math.pow(2, -n.octaves),\n sampler: n.isActive\n ? new FBM({\n seed: Math.random(),\n scale: n.frequency,\n octaves: n.octaves,\n })\n : undefined,\n offsets: n.useRandomOffset\n ? (generalData.noise.offsets ??\n Array.from({ length: maxParticles }, () => Math.random() * 100))\n : undefined,\n };\n }\n };\n\n return {\n instance: wrapper || particleSystem,\n resumeEmitter,\n pauseEmitter,\n dispose,\n update,\n updateConfig,\n computeNode: gpuPipeline?.computeNode ?? null,\n };\n};\n\n/**\n * Updates all active particle systems created with {@link createParticleSystem}.\n *\n * This function must be called once per frame in your animation loop to animate all particles.\n * It handles particle emission, movement, lifetime tracking, modifier application, and cleanup\n * of expired particle systems.\n *\n * @param cycleData - Object containing timing information for the current frame:\n * - `now`: Current timestamp in milliseconds (typically from `performance.now()` or `Date.now()`)\n * - `delta`: Time elapsed since the last frame in seconds\n * - `elapsed`: Total time elapsed since the animation started in seconds\n *\n * @example\n * ```typescript\n * import { createParticleSystem, updateParticleSystems } from '@newkrok/three-particles';\n *\n * const { instance } = createParticleSystem({\n * // your config\n * });\n * scene.add(instance);\n *\n * // Animation loop\n * let lastTime = 0;\n * let elapsedTime = 0;\n *\n * function animate(currentTime) {\n * requestAnimationFrame(animate);\n *\n * const delta = (currentTime - lastTime) / 1000; // Convert to seconds\n * elapsedTime += delta;\n * lastTime = currentTime;\n *\n * // Update all particle systems\n * updateParticleSystems({\n * now: currentTime,\n * delta: delta,\n * elapsed: elapsedTime\n * });\n *\n * renderer.render(scene, camera);\n * }\n *\n * animate(0);\n * ```\n *\n * @example\n * ```typescript\n * // Using Three.js Clock for timing\n * import * as THREE from 'three';\n * import { updateParticleSystems } from '@newkrok/three-particles';\n *\n * const clock = new THREE.Clock();\n *\n * function animate() {\n * requestAnimationFrame(animate);\n *\n * const delta = clock.getDelta();\n * const elapsed = clock.getElapsedTime();\n *\n * updateParticleSystems({\n * now: performance.now(),\n * delta: delta,\n * elapsed: elapsed\n * });\n *\n * renderer.render(scene, camera);\n * }\n * ```\n *\n * @see {@link createParticleSystem} - Creates particle systems to be updated\n * @see {@link CycleData} - Timing data structure\n */\nconst updateParticleSystemInstance = (\n props: ParticleSystemInstance,\n { now, delta, elapsed }: CycleData\n) => {\n const {\n onUpdate,\n generalData,\n onComplete,\n particleSystem,\n wrapper,\n elapsedUniform,\n creationTime,\n lastEmissionTime,\n duration,\n looping,\n emission,\n normalizedConfig,\n iterationCount,\n velocities,\n freeList,\n deactivateParticle,\n activateParticle,\n simulationSpace,\n gravity,\n normalizedForceFields,\n normalizedCollisionPlanes,\n onParticleDeath,\n onParticleBirth,\n mappedAttributes: ma,\n useGPUCompute,\n computePipeline,\n } = props;\n\n const hasForceFields = normalizedForceFields.length > 0;\n const hasCollisionPlanes = normalizedCollisionPlanes.length > 0;\n\n const lifetime = now - creationTime;\n const normalizedLifetime = lifetime % (duration * 1000);\n\n generalData.normalizedLifetimePercentage = Math.max(\n Math.min(normalizedLifetime / (duration * 1000), 1),\n 0\n );\n\n const {\n lastWorldPosition,\n currentWorldPosition,\n worldPositionChange,\n lastWorldQuaternion,\n worldQuaternion,\n worldEuler,\n gravityVelocity,\n isEnabled,\n } = generalData;\n\n if (wrapper?.parent)\n generalData.wrapperQuaternion.copy(wrapper.parent.quaternion);\n\n _lastWorldPositionSnapshot.copy(lastWorldPosition);\n\n elapsedUniform.value = elapsed;\n\n particleSystem.getWorldPosition(currentWorldPosition);\n if (lastWorldPosition.x !== -99999) {\n worldPositionChange.set(\n currentWorldPosition.x - lastWorldPosition.x,\n currentWorldPosition.y - lastWorldPosition.y,\n currentWorldPosition.z - lastWorldPosition.z\n );\n }\n if (isEnabled) {\n generalData.distanceFromLastEmitByDistance += worldPositionChange.length();\n }\n particleSystem.getWorldPosition(lastWorldPosition);\n particleSystem.getWorldQuaternion(worldQuaternion);\n if (\n lastWorldQuaternion.x === -99999 ||\n lastWorldQuaternion.x !== worldQuaternion.x ||\n lastWorldQuaternion.y !== worldQuaternion.y ||\n lastWorldQuaternion.z !== worldQuaternion.z\n ) {\n worldEuler.setFromQuaternion(worldQuaternion);\n lastWorldQuaternion.copy(worldQuaternion);\n gravityVelocity.set(\n lastWorldPosition.x,\n lastWorldPosition.y + gravity,\n lastWorldPosition.z\n );\n particleSystem.worldToLocal(gravityVelocity);\n }\n\n // Transform force field positions/directions into local space once per frame\n // (particle positions in the buffer are in local space, so force fields must match)\n if (hasForceFields) {\n _inverseQuat.copy(worldQuaternion).invert();\n\n _localForceFields.length = normalizedForceFields.length;\n\n for (let i = 0; i < normalizedForceFields.length; i++) {\n const src = normalizedForceFields[i];\n let dst = _localForceFields[i];\n if (!dst) {\n dst = {\n isActive: true,\n type: ForceFieldType.POINT,\n position: new THREE.Vector3(),\n direction: new THREE.Vector3(),\n strength: 0,\n range: 0,\n falloff: ForceFieldFalloff.LINEAR,\n };\n _localForceFields[i] = dst;\n }\n dst.isActive = src.isActive;\n dst.type = src.type;\n dst.strength = src.strength;\n dst.range = src.range;\n dst.falloff = src.falloff;\n\n _localForceFieldPos.copy(src.position);\n particleSystem.worldToLocal(_localForceFieldPos);\n dst.position.copy(_localForceFieldPos);\n\n _localForceFieldDir.copy(src.direction);\n _localForceFieldDir.applyQuaternion(_inverseQuat);\n dst.direction.copy(_localForceFieldDir);\n }\n }\n\n // Transform collision plane positions/normals into local space once per frame\n if (hasCollisionPlanes) {\n if (!hasForceFields) _inverseQuat.copy(worldQuaternion).invert();\n\n _localCollisionPlanes.length = normalizedCollisionPlanes.length;\n\n for (let i = 0; i < normalizedCollisionPlanes.length; i++) {\n const src = normalizedCollisionPlanes[i];\n let dst = _localCollisionPlanes[i];\n if (!dst) {\n dst = {\n isActive: true,\n position: new THREE.Vector3(),\n normal: new THREE.Vector3(),\n mode: CollisionPlaneMode.KILL,\n dampen: 0.5,\n lifetimeLoss: 0,\n };\n _localCollisionPlanes[i] = dst;\n }\n dst.isActive = src.isActive;\n dst.mode = src.mode;\n dst.dampen = src.dampen;\n dst.lifetimeLoss = src.lifetimeLoss;\n\n _localCollisionPlanePos.copy(src.position);\n particleSystem.worldToLocal(_localCollisionPlanePos);\n dst.position.copy(_localCollisionPlanePos);\n\n _localCollisionPlaneNormal.copy(src.normal);\n _localCollisionPlaneNormal.applyQuaternion(_inverseQuat);\n dst.normal.copy(_localCollisionPlaneNormal);\n }\n }\n\n const creationTimes = generalData.creationTimes;\n const scalarArr = props.scalarArray;\n const positionArr = ma.position.array;\n const creationTimesLength = creationTimes.length;\n\n // ── GPU Compute Path ──────────────────────────────────────────────────\n // When GPU compute is active, all per-particle physics AND modifiers\n // (gravity, velocity, position, lifetime, size/opacity/color/rotation\n // over lifetime, noise, orbital velocity, force fields) run on the GPU\n // in a single compute dispatch. CPU still handles:\n // - Death detection for sub-emitter callbacks + freeList management\n // - Emission (particle activation, writing initial data to GPU buffers)\n if (useGPUCompute && computePipeline) {\n type ModifierComputePipeline =\n import('./webgpu/compute-modifiers.js').ModifierComputePipeline;\n const cp = computePipeline as ModifierComputePipeline;\n\n // Core physics uniforms\n setUniformFloat(cp.uniforms.delta, delta);\n setUniformFloat(cp.uniforms.deltaMs, delta * 1000);\n setUniformVec3(\n cp.uniforms.gravityVelocity,\n gravityVelocity.x,\n gravityVelocity.y,\n gravityVelocity.z\n );\n setUniformVec3(\n cp.uniforms.worldPositionChange,\n generalData.worldPositionChange.x,\n generalData.worldPositionChange.y,\n generalData.worldPositionChange.z\n );\n setUniformFloat(\n cp.uniforms.simulationSpaceWorld,\n simulationSpace === SimulationSpace.WORLD ? 1 : 0\n );\n\n // Noise uniforms\n // GPU simplex noise output is not normalised by FBM's octave accumulator,\n // so we scale noisePower by the pre-computed divisor (fbmMax).\n const noiseData = generalData.noise;\n setUniformFloat(cp.uniforms.noiseStrength, noiseData.strength);\n setUniformFloat(\n cp.uniforms.noisePower,\n noiseData.noisePower / noiseData.fbmMax\n );\n setUniformFloat(cp.uniforms.noiseFrequency, noiseData.frequency);\n setUniformFloat(cp.uniforms.noisePositionAmount, noiseData.positionAmount);\n setUniformFloat(cp.uniforms.noiseRotationAmount, noiseData.rotationAmount);\n setUniformFloat(cp.uniforms.noiseSizeAmount, noiseData.sizeAmount);\n\n // Force field buffer update — write encoded data into curveData tail\n if (\n cp.forceFieldInfo &&\n hasForceFields &&\n _tslMaterialFactory?.encodeForceFieldsForGPU\n ) {\n const encodedFF = _tslMaterialFactory.encodeForceFieldsForGPU(\n _localForceFields,\n generalData.particleSystemId,\n generalData.normalizedLifetimePercentage\n );\n const curveArr = cp.buffers.curveData.array as Float32Array;\n curveArr.set(encodedFF, cp.forceFieldInfo.offset);\n cp.buffers.curveData.needsUpdate = true;\n setUniformFloat(\n cp.forceFieldInfo.countUniform,\n normalizedForceFields.length\n );\n }\n\n // Collision plane buffer update — write encoded data into curveData tail\n if (\n cp.collisionPlaneInfo &&\n hasCollisionPlanes &&\n _tslMaterialFactory?.encodeCollisionPlanesForGPU\n ) {\n const encodedCP = _tslMaterialFactory.encodeCollisionPlanesForGPU(\n _localCollisionPlanes\n );\n const curveArr = cp.buffers.curveData.array as Float32Array;\n curveArr.set(encodedCP, cp.collisionPlaneInfo.offset);\n cp.buffers.curveData.needsUpdate = true;\n setUniformFloat(\n cp.collisionPlaneInfo.countUniform,\n normalizedCollisionPlanes.length\n );\n }\n\n // Flush emit queue — uploads queued particle data to GPU and sets the\n // emit count uniform so the compute shader's scatter pass can initialise\n // newly emitted particles without overwriting existing GPU state.\n if (_tslMaterialFactory?.flushEmitQueue) {\n _tslMaterialFactory.flushEmitQueue(cp.buffers);\n }\n\n // Signal onBeforeRender to dispatch compute\n props.computeDispatchReady = true;\n\n // CPU-side death detection (for sub-emitter callbacks + freeList).\n // When death sub-emitters exist we also run a lightweight CPU shadow\n // simulation (velocity integration, gravity, orbital velocity, force\n // fields) so that positionArr contains an approximate current position\n // instead of the stale emission-time value — the GPU buffer is not\n // readable from the CPU without an async readback.\n for (let index = 0; index < creationTimesLength; index++) {\n const base = index * SCALAR_STRIDE;\n if (scalarArr[base + S_IS_ACTIVE]) {\n const particleLifetime = now - creationTimes[index];\n if (particleLifetime > scalarArr[base + S_START_LIFETIME]) {\n if (onParticleDeath)\n onParticleDeath(index, positionArr, velocities[index], now);\n deactivateParticle(index);\n } else if (onParticleDeath) {\n // Shadow simulation: keep CPU-side position in sync for sub-emitters.\n // We intentionally avoid calling applyModifiers() here because it\n // sets attributes.position.needsUpdate = true, which triggers a full\n // CPU→GPU upload that overwrites GPU-computed positions for ALL\n // particles. Instead we do the minimal physics inline without\n // touching needsUpdate.\n const velocity = velocities[index];\n velocity.x -= gravityVelocity.x * delta;\n velocity.y -= gravityVelocity.y * delta;\n velocity.z -= gravityVelocity.z * delta;\n\n if (hasForceFields) {\n applyForceFields({\n particleSystemId: generalData.particleSystemId,\n forceFields: _localForceFields,\n velocity,\n positionArr,\n positionIndex: index * 3,\n delta,\n systemLifetimePercentage:\n generalData.normalizedLifetimePercentage,\n });\n }\n\n const positionIndex = index * 3;\n if (simulationSpace === SimulationSpace.WORLD) {\n positionArr[positionIndex] -= worldPositionChange.x;\n positionArr[positionIndex + 1] -= worldPositionChange.y;\n positionArr[positionIndex + 2] -= worldPositionChange.z;\n }\n positionArr[positionIndex] += velocity.x * delta;\n positionArr[positionIndex + 1] += velocity.y * delta;\n positionArr[positionIndex + 2] += velocity.z * delta;\n\n // Orbital velocity (mirrors CPU applyModifiers orbital logic)\n if (generalData.orbitalVelocityData) {\n const orbData = generalData.orbitalVelocityData[index];\n const { speed, positionOffset, valueModifiers } = orbData;\n const pctLife =\n particleLifetime / scalarArr[base + S_START_LIFETIME];\n\n positionArr[positionIndex] -= positionOffset.x;\n positionArr[positionIndex + 1] -= positionOffset.y;\n positionArr[positionIndex + 2] -= positionOffset.z;\n\n const sx = valueModifiers.x ? valueModifiers.x(pctLife) : speed.x;\n const sy = valueModifiers.y ? valueModifiers.y(pctLife) : speed.y;\n const sz = valueModifiers.z ? valueModifiers.z(pctLife) : speed.z;\n\n _shadowOrbitalEuler.set(sx * delta, sz * delta, sy * delta);\n positionOffset.applyEuler(_shadowOrbitalEuler);\n\n positionArr[positionIndex] += positionOffset.x;\n positionArr[positionIndex + 1] += positionOffset.y;\n positionArr[positionIndex + 2] += positionOffset.z;\n }\n\n // Collision planes (shadow sim — for KILL death detection only)\n if (hasCollisionPlanes) {\n applyCollisionPlanes({\n collisionPlanes: _localCollisionPlanes,\n velocity,\n positionArr,\n positionIndex,\n scalarArr,\n scalarBase: base,\n deactivateParticle: (pi: number) => {\n if (onParticleDeath)\n onParticleDeath(pi, positionArr, velocities[pi], now);\n deactivateParticle(pi);\n },\n particleIndex: index,\n });\n }\n }\n }\n }\n } else {\n // ── CPU Path ────────────────────────────────────────────────────────\n\n let positionNeedsUpdate = false;\n let scalarNeedsUpdate = false;\n\n _modifierParams.delta = delta;\n _modifierParams.generalData = generalData;\n _modifierParams.normalizedConfig = normalizedConfig;\n _modifierParams.attributes = ma;\n _modifierParams.scalarArray = scalarArr;\n\n for (let index = 0; index < creationTimesLength; index++) {\n const base = index * SCALAR_STRIDE;\n if (scalarArr[base + S_IS_ACTIVE]) {\n const particleLifetime = now - creationTimes[index];\n if (particleLifetime > scalarArr[base + S_START_LIFETIME]) {\n if (onParticleDeath)\n onParticleDeath(index, positionArr, velocities[index], now);\n deactivateParticle(index);\n } else {\n const velocity = velocities[index];\n velocity.x -= gravityVelocity.x * delta;\n velocity.y -= gravityVelocity.y * delta;\n velocity.z -= gravityVelocity.z * delta;\n\n if (hasForceFields) {\n applyForceFields({\n particleSystemId: generalData.particleSystemId,\n forceFields: _localForceFields,\n velocity,\n positionArr,\n positionIndex: index * 3,\n delta,\n systemLifetimePercentage:\n generalData.normalizedLifetimePercentage,\n });\n }\n\n if (\n gravity !== 0 ||\n velocity.x !== 0 ||\n velocity.y !== 0 ||\n velocity.z !== 0 ||\n worldPositionChange.x !== 0 ||\n worldPositionChange.y !== 0 ||\n worldPositionChange.z !== 0\n ) {\n const positionIndex = index * 3;\n\n if (simulationSpace === SimulationSpace.WORLD) {\n positionArr[positionIndex] -= worldPositionChange.x;\n positionArr[positionIndex + 1] -= worldPositionChange.y;\n positionArr[positionIndex + 2] -= worldPositionChange.z;\n }\n\n positionArr[positionIndex] += velocity.x * delta;\n positionArr[positionIndex + 1] += velocity.y * delta;\n positionArr[positionIndex + 2] += velocity.z * delta;\n positionNeedsUpdate = true;\n }\n\n // Collision planes — after position update, before modifiers\n if (hasCollisionPlanes) {\n const killed = applyCollisionPlanes({\n collisionPlanes: _localCollisionPlanes,\n velocity,\n positionArr,\n positionIndex: index * 3,\n scalarArr,\n scalarBase: base,\n deactivateParticle: (pi: number) => {\n if (onParticleDeath)\n onParticleDeath(pi, positionArr, velocities[pi], now);\n deactivateParticle(pi);\n },\n particleIndex: index,\n });\n if (killed) {\n positionNeedsUpdate = true;\n continue;\n }\n }\n\n scalarArr[base + S_LIFETIME] = particleLifetime;\n scalarNeedsUpdate = true;\n\n _modifierParams.particleLifetimePercentage =\n particleLifetime / scalarArr[base + S_START_LIFETIME];\n _modifierParams.particleIndex = index;\n applyModifiers(_modifierParams);\n }\n }\n }\n\n if (positionNeedsUpdate) ma.position.needsUpdate = true;\n if (scalarNeedsUpdate) props.scalarInterleavedBuffer.needsUpdate = true;\n } // end of CPU/GPU compute branch\n\n if (isEnabled && (looping || lifetime < duration * 1000)) {\n const emissionDelta = now - lastEmissionTime;\n const neededParticlesByTime = emission.rateOverTime\n ? Math.floor(\n calculateValue(\n generalData.particleSystemId,\n emission.rateOverTime,\n generalData.normalizedLifetimePercentage\n ) *\n (emissionDelta / 1000)\n )\n : 0;\n\n const rateOverDistance = emission.rateOverDistance\n ? calculateValue(\n generalData.particleSystemId,\n emission.rateOverDistance,\n generalData.normalizedLifetimePercentage\n )\n : 0;\n const neededParticlesByDistance =\n rateOverDistance > 0 && generalData.distanceFromLastEmitByDistance > 0\n ? Math.floor(\n generalData.distanceFromLastEmitByDistance / (1 / rateOverDistance!)\n )\n : 0;\n const useDistanceStep = neededParticlesByDistance > 0;\n if (useDistanceStep) {\n _distanceStep.x =\n (currentWorldPosition.x - _lastWorldPositionSnapshot.x) /\n neededParticlesByDistance;\n _distanceStep.y =\n (currentWorldPosition.y - _lastWorldPositionSnapshot.y) /\n neededParticlesByDistance;\n _distanceStep.z =\n (currentWorldPosition.z - _lastWorldPositionSnapshot.z) /\n neededParticlesByDistance;\n }\n let neededParticles = neededParticlesByTime + neededParticlesByDistance;\n\n if (rateOverDistance > 0 && neededParticlesByDistance >= 1) {\n generalData.distanceFromLastEmitByDistance = 0;\n }\n\n // Process burst emissions\n if (emission.bursts && generalData.burstStates) {\n const bursts = emission.bursts;\n const burstStates = generalData.burstStates;\n const currentIterationTime = normalizedLifetime;\n\n for (let i = 0; i < bursts.length; i++) {\n const burst = bursts[i];\n const state = burstStates[i];\n const burstTimeMs = burst.time * 1000;\n const cycles = burst.cycles ?? 1;\n const intervalMs = (burst.interval ?? 0) * 1000;\n const probability = burst.probability ?? 1;\n\n // Check if we've looped and need to reset burst states\n if (\n looping &&\n currentIterationTime < burstTimeMs &&\n state.cyclesExecuted > 0\n ) {\n state.cyclesExecuted = 0;\n state.lastCycleTime = 0;\n state.probabilityPassed = false;\n }\n\n // Check if all cycles for this burst have been executed\n if (state.cyclesExecuted >= cycles) continue;\n\n // Calculate the time for the next cycle\n const nextCycleTime = burstTimeMs + state.cyclesExecuted * intervalMs;\n\n // Check if it's time for the next cycle\n if (currentIterationTime >= nextCycleTime) {\n // On first cycle, determine if probability check passes\n if (state.cyclesExecuted === 0) {\n state.probabilityPassed = Math.random() < probability;\n }\n\n // Only emit if probability check passed\n if (state.probabilityPassed) {\n const burstCount = Math.floor(\n calculateValue(\n generalData.particleSystemId,\n burst.count,\n generalData.normalizedLifetimePercentage\n )\n );\n neededParticles += burstCount;\n }\n\n state.cyclesExecuted++;\n state.lastCycleTime = currentIterationTime;\n }\n }\n }\n\n if (neededParticles > 0) {\n let generatedParticlesByDistanceNeeds = 0;\n\n for (let i = 0; i < neededParticles; i++) {\n if (freeList.length === 0) break;\n const particleIndex = freeList.pop()!;\n\n _tempPosition.x = 0;\n _tempPosition.y = 0;\n _tempPosition.z = 0;\n if (\n useDistanceStep &&\n generatedParticlesByDistanceNeeds < neededParticlesByDistance\n ) {\n _tempPosition.x = _distanceStep.x * generatedParticlesByDistanceNeeds;\n _tempPosition.y = _distanceStep.y * generatedParticlesByDistanceNeeds;\n _tempPosition.z = _distanceStep.z * generatedParticlesByDistanceNeeds;\n generatedParticlesByDistanceNeeds++;\n }\n activateParticle({\n particleIndex,\n activationTime: now,\n position: _tempPosition,\n });\n if (onParticleBirth)\n onParticleBirth(\n particleIndex,\n ma.position.array,\n velocities[particleIndex],\n now\n );\n props.lastEmissionTime = now;\n }\n }\n\n if (onUpdate)\n onUpdate({\n particleSystem,\n delta,\n elapsed,\n lifetime,\n normalizedLifetime,\n iterationCount: iterationCount + 1,\n });\n } else if (onComplete)\n onComplete({\n particleSystem,\n });\n\n // Trail geometry update: record position history and rebuild ribbon\n if (props.trailMesh) {\n updateTrailGeometry(props, now);\n }\n};\n\n/**\n * Evaluates a Catmull-Rom spline at parameter `t` (0..1) between points p1 and p2,\n * using p0 and p3 as control points. Writes result into `out`.\n */\nconst catmullRom = (\n out: Float32Array,\n outIdx: number,\n p0x: number,\n p0y: number,\n p0z: number,\n p1x: number,\n p1y: number,\n p1z: number,\n p2x: number,\n p2y: number,\n p2z: number,\n p3x: number,\n p3y: number,\n p3z: number,\n t: number\n) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[outIdx] =\n 0.5 *\n (2 * p1x +\n (-p0x + p2x) * t +\n (2 * p0x - 5 * p1x + 4 * p2x - p3x) * t2 +\n (-p0x + 3 * p1x - 3 * p2x + p3x) * t3);\n out[outIdx + 1] =\n 0.5 *\n (2 * p1y +\n (-p0y + p2y) * t +\n (2 * p0y - 5 * p1y + 4 * p2y - p3y) * t2 +\n (-p0y + 3 * p1y - 3 * p2y + p3y) * t3);\n out[outIdx + 2] =\n 0.5 *\n (2 * p1z +\n (-p0z + p2z) * t +\n (2 * p0z - 5 * p1z + 4 * p2z - p3z) * t2 +\n (-p0z + 3 * p1z - 3 * p2z + p3z) * t3);\n};\n\n/** Zeroes out a single trail vertex (both left+right sides). */\nconst clearTrailVertex = (\n vIdx: number,\n cIdx: number,\n aIdx: number,\n uvIdx: number,\n trailPosArr: Float32Array,\n trailNextArr: Float32Array,\n trailHalfWidthArr: Float32Array,\n trailUVArr: Float32Array,\n trailAlphaArr: Float32Array,\n trailColorArr: Float32Array,\n fallbackX: number,\n fallbackY: number,\n fallbackZ: number\n) => {\n trailPosArr[vIdx] = fallbackX;\n trailPosArr[vIdx + 1] = fallbackY;\n trailPosArr[vIdx + 2] = fallbackZ;\n trailPosArr[vIdx + 3] = fallbackX;\n trailPosArr[vIdx + 4] = fallbackY;\n trailPosArr[vIdx + 5] = fallbackZ;\n trailNextArr[vIdx] = fallbackX;\n trailNextArr[vIdx + 1] = fallbackY;\n trailNextArr[vIdx + 2] = fallbackZ;\n trailNextArr[vIdx + 3] = fallbackX;\n trailNextArr[vIdx + 4] = fallbackY;\n trailNextArr[vIdx + 5] = fallbackZ;\n trailHalfWidthArr[aIdx] = 0;\n trailHalfWidthArr[aIdx + 1] = 0;\n trailUVArr[uvIdx] = 0;\n trailUVArr[uvIdx + 1] = 0;\n trailUVArr[uvIdx + 2] = 0;\n trailUVArr[uvIdx + 3] = 0;\n trailAlphaArr[aIdx] = 0;\n trailAlphaArr[aIdx + 1] = 0;\n trailColorArr[cIdx] = 0;\n trailColorArr[cIdx + 1] = 0;\n trailColorArr[cIdx + 2] = 0;\n trailColorArr[cIdx + 3] = 0;\n trailColorArr[cIdx + 4] = 0;\n trailColorArr[cIdx + 5] = 0;\n trailColorArr[cIdx + 6] = 0;\n trailColorArr[cIdx + 7] = 0;\n};\n\n/**\n * Writes a single trail ribbon vertex pair (left+right) into the typed arrays.\n */\nconst writeTrailVertex = (\n vIdx: number,\n cIdx: number,\n aIdx: number,\n uvIdx: number,\n hx: number,\n hy: number,\n hz: number,\n nx: number,\n ny: number,\n nz: number,\n halfWidth: number,\n t: number,\n alpha: number,\n fr: number,\n fg: number,\n fb: number,\n ca: number,\n trailPosArr: Float32Array,\n trailNextArr: Float32Array,\n trailHalfWidthArr: Float32Array,\n trailUVArr: Float32Array,\n trailAlphaArr: Float32Array,\n trailColorArr: Float32Array\n) => {\n trailPosArr[vIdx] = hx;\n trailPosArr[vIdx + 1] = hy;\n trailPosArr[vIdx + 2] = hz;\n trailPosArr[vIdx + 3] = hx;\n trailPosArr[vIdx + 4] = hy;\n trailPosArr[vIdx + 5] = hz;\n trailNextArr[vIdx] = nx;\n trailNextArr[vIdx + 1] = ny;\n trailNextArr[vIdx + 2] = nz;\n trailNextArr[vIdx + 3] = nx;\n trailNextArr[vIdx + 4] = ny;\n trailNextArr[vIdx + 5] = nz;\n trailHalfWidthArr[aIdx] = halfWidth;\n trailHalfWidthArr[aIdx + 1] = halfWidth;\n trailUVArr[uvIdx] = 0;\n trailUVArr[uvIdx + 1] = t;\n trailUVArr[uvIdx + 2] = 1;\n trailUVArr[uvIdx + 3] = t;\n trailAlphaArr[aIdx] = alpha;\n trailAlphaArr[aIdx + 1] = alpha;\n trailColorArr[cIdx] = fr;\n trailColorArr[cIdx + 1] = fg;\n trailColorArr[cIdx + 2] = fb;\n trailColorArr[cIdx + 3] = ca;\n trailColorArr[cIdx + 4] = fr;\n trailColorArr[cIdx + 5] = fg;\n trailColorArr[cIdx + 6] = fb;\n trailColorArr[cIdx + 7] = ca;\n};\n\n// Scratch buffers reused each frame to avoid per-particle allocations\nlet _rawPoints: Float32Array | null = null;\nlet _rawPointsSize = 0;\nlet _smoothedPoints: Float32Array | null = null;\nlet _smoothedPointsSize = 0;\n// Scratch buffer for connected ribbon particle indices (reused each frame)\nlet _ribbonIndices: Uint16Array | null = null;\nlet _ribbonIndicesSize = 0;\nlet _ribbonCount = 0;\n\n/**\n * Records current particle positions into the history ring buffer,\n * then rebuilds the triangle-strip ribbon geometry for all active particles.\n *\n * Supports:\n * - Adaptive sampling (minVertexDistance): frame-rate independent trail density\n * - Max time (maxTime): time-based trail expiry\n * - Catmull-Rom smoothing: eliminates sharp kinks between samples\n * - Twist prevention: consistent ribbon orientation during rapid direction changes\n * - Connected ribbons (ribbonId): multiple particles forming a single ribbon\n */\nconst updateTrailGeometry = (props: ParticleSystemInstance, now: number) => {\n const {\n generalData,\n trailPositionAttr,\n trailAlphaAttr,\n trailColorAttr,\n trailNextAttr: trailNextAttrCached,\n trailHalfWidthAttr: trailHalfWidthAttrCached,\n trailUVAttr: trailUVAttrCached,\n trailWidthCurveFn,\n trailOpacityCurveFn,\n trailColorOverTrailFns,\n trailConfig,\n mappedAttributes: ma,\n } = props;\n\n if (\n !trailPositionAttr ||\n !trailAlphaAttr ||\n !trailColorAttr ||\n !trailNextAttrCached ||\n !trailHalfWidthAttrCached ||\n !trailUVAttrCached ||\n !trailWidthCurveFn ||\n !trailOpacityCurveFn ||\n !trailConfig ||\n !generalData.positionHistory ||\n !generalData.positionHistoryIndex ||\n !generalData.positionHistoryCount\n )\n return;\n\n const trailLength = trailConfig.length;\n const positionHistory = generalData.positionHistory;\n const historyIndex = generalData.positionHistoryIndex;\n const historyCount = generalData.positionHistoryCount;\n const sampleTimes = generalData.trailSampleTimes;\n const lastSampledPos = generalData.trailLastSampledPosition;\n const prevNormal = generalData.trailPrevNormal;\n const minVertexDist = trailConfig.minVertexDistance;\n const minVertexDistSq = minVertexDist * minVertexDist;\n const maxTime = trailConfig.maxTime;\n const maxTimeMs = maxTime * 1000;\n const useSmoothing = trailConfig.smoothing;\n const subdivisions = trailConfig.smoothingSubdivisions;\n const useTwistPrevention = trailConfig.twistPrevention;\n const ribbonId = trailConfig.ribbonId;\n\n const trailScalarArr = props.scalarArray;\n const positionArr = ma.position.array;\n\n const trailPosArr = trailPositionAttr.array as Float32Array;\n const trailAlphaArr = trailAlphaAttr.array as Float32Array;\n const trailColorArr = trailColorAttr.array as Float32Array;\n const trailNextArr = trailNextAttrCached.array as Float32Array;\n const trailUVArr = trailUVAttrCached.array as Float32Array;\n const trailHalfWidthArr = trailHalfWidthAttrCached.array as Float32Array;\n const verticesPerParticle = trailLength * 2;\n const creationTimesLength = generalData.creationTimes.length;\n let hasUpdates = false;\n\n // --- Connected Ribbons: collect particles sharing the same ribbonId ---\n const useRibbon = ribbonId !== undefined;\n let ribbonLeader = -1;\n if (useRibbon) {\n // Pre-allocate scratch buffer for ribbon indices\n if (!_ribbonIndices || _ribbonIndicesSize < creationTimesLength) {\n _ribbonIndices = new Uint16Array(creationTimesLength);\n _ribbonIndicesSize = creationTimesLength;\n }\n _ribbonCount = 0;\n for (let i = 0; i < creationTimesLength; i++) {\n if (trailScalarArr[i * SCALAR_STRIDE + S_IS_ACTIVE])\n _ribbonIndices[_ribbonCount++] = i;\n }\n // Insertion sort by creation time (typically nearly-sorted, O(n) best case)\n for (let i = 1; i < _ribbonCount; i++) {\n const key = _ribbonIndices[i];\n const keyTime = generalData.creationTimes[key];\n let j = i - 1;\n while (j >= 0 && generalData.creationTimes[_ribbonIndices[j]] > keyTime) {\n _ribbonIndices[j + 1] = _ribbonIndices[j];\n j--;\n }\n _ribbonIndices[j + 1] = key;\n }\n if (_ribbonCount > 0) ribbonLeader = _ribbonIndices[0];\n }\n\n for (let index = 0; index < creationTimesLength; index++) {\n const vertBase = index * verticesPerParticle;\n\n if (trailScalarArr[index * SCALAR_STRIDE + S_IS_ACTIVE]) {\n // Skip individual trail build for non-leader ribbon particles\n // (the leader's trail will be built by the connected ribbon section)\n if (useRibbon && _ribbonCount >= 2 && index !== ribbonLeader) {\n // Still record position history for this particle (needed for sampling)\n const posIdx = index * 3;\n const px = positionArr[posIdx];\n const py = positionArr[posIdx + 1];\n const pz = positionArr[posIdx + 2];\n const histBase = (index * trailLength + historyIndex[index]) * 3;\n positionHistory[histBase] = px;\n positionHistory[histBase + 1] = py;\n positionHistory[histBase + 2] = pz;\n if (sampleTimes) {\n sampleTimes[index * trailLength + historyIndex[index]] = now;\n }\n historyIndex[index] = (historyIndex[index] + 1) % trailLength;\n if (historyCount[index] < trailLength) historyCount[index]++;\n continue;\n }\n hasUpdates = true;\n const posIdx = index * 3;\n const px = positionArr[posIdx];\n const py = positionArr[posIdx + 1];\n const pz = positionArr[posIdx + 2];\n\n // --- Adaptive Sampling: only push a new sample if distance threshold met ---\n let shouldSample = true;\n if (minVertexDist > 0 && lastSampledPos && historyCount[index] > 0) {\n const lsIdx = index * 3;\n const dx = px - lastSampledPos[lsIdx];\n const dy = py - lastSampledPos[lsIdx + 1];\n const dz = pz - lastSampledPos[lsIdx + 2];\n if (dx * dx + dy * dy + dz * dz < minVertexDistSq) {\n shouldSample = false;\n }\n }\n\n if (shouldSample) {\n // Record the sample\n const histBase = (index * trailLength + historyIndex[index]) * 3;\n positionHistory[histBase] = px;\n positionHistory[histBase + 1] = py;\n positionHistory[histBase + 2] = pz;\n\n // Record timestamp for maxTime\n if (sampleTimes) {\n sampleTimes[index * trailLength + historyIndex[index]] = now;\n }\n\n historyIndex[index] = (historyIndex[index] + 1) % trailLength;\n if (historyCount[index] < trailLength) historyCount[index]++;\n\n // Update last sampled position\n if (lastSampledPos) {\n const lsIdx = index * 3;\n lastSampledPos[lsIdx] = px;\n lastSampledPos[lsIdx + 1] = py;\n lastSampledPos[lsIdx + 2] = pz;\n }\n }\n\n // --- MaxTime: determine effective count (expire old segments) ---\n let rawCount = historyCount[index];\n let effectiveCount = rawCount;\n if (maxTime > 0 && sampleTimes && rawCount > 0) {\n const sampleBase = index * trailLength;\n effectiveCount = 0;\n for (let s = 0; s < rawCount; s++) {\n const sampleSlot =\n (historyIndex[index] - 1 - s + trailLength * 2) % trailLength;\n const age = now - sampleTimes[sampleBase + sampleSlot];\n if (age <= maxTimeMs) {\n effectiveCount++;\n } else {\n break; // older samples are even older, stop\n }\n }\n }\n\n const count = effectiveCount;\n const ribbonWidth = trailConfig.width;\n\n // Get particle color from interleaved scalar buffer\n const trailBase = index * SCALAR_STRIDE;\n const cr = trailScalarArr[trailBase + S_COLOR_R];\n const cg = trailScalarArr[trailBase + S_COLOR_G];\n const cb = trailScalarArr[trailBase + S_COLOR_B];\n const ca = trailScalarArr[trailBase + S_COLOR_A];\n\n const ringOff = index * trailLength * 3;\n\n // --- Collect raw history points for this particle ---\n // We need them for both smoothing and the ribbon build.\n // rawPts: flat array of [x, y, z, x, y, z, ...] for count entries\n // rawPts[0..2] = head (most recent), rawPts[(count-1)*3..(count-1)*3+2] = tail\n const rawPtsSize = count * 3;\n // Reuse a scratch float array for raw points\n if (!_rawPoints || _rawPointsSize < rawPtsSize) {\n _rawPoints = new Float32Array(rawPtsSize);\n _rawPointsSize = rawPtsSize;\n }\n const rawPts = _rawPoints;\n for (let s = 0; s < count; s++) {\n const histSlot =\n ((historyIndex[index] - 1 - s + trailLength * 2) % trailLength) * 3 +\n ringOff;\n rawPts[s * 3] = positionHistory[histSlot];\n rawPts[s * 3 + 1] = positionHistory[histSlot + 1];\n rawPts[s * 3 + 2] = positionHistory[histSlot + 2];\n }\n\n // --- Catmull-Rom Smoothing ---\n let finalPts: Float32Array;\n let finalCount: number;\n\n if (useSmoothing && count >= 3) {\n // Interpolate between each pair of raw points with subdivisions\n const segmentCount = count - 1;\n finalCount = segmentCount * subdivisions + 1;\n const neededSize = finalCount * 3;\n\n // Resize global scratch buffer if needed\n if (!_smoothedPoints || _smoothedPointsSize < neededSize) {\n _smoothedPoints = new Float32Array(neededSize);\n _smoothedPointsSize = neededSize;\n }\n finalPts = _smoothedPoints;\n\n for (let seg = 0; seg < segmentCount; seg++) {\n // Control points: p0, p1, p2, p3\n const i0 = Math.max(0, seg - 1);\n const i1 = seg;\n const i2 = Math.min(count - 1, seg + 1);\n const i3 = Math.min(count - 1, seg + 2);\n\n const p0x = rawPts[i0 * 3],\n p0y = rawPts[i0 * 3 + 1],\n p0z = rawPts[i0 * 3 + 2];\n const p1x = rawPts[i1 * 3],\n p1y = rawPts[i1 * 3 + 1],\n p1z = rawPts[i1 * 3 + 2];\n const p2x = rawPts[i2 * 3],\n p2y = rawPts[i2 * 3 + 1],\n p2z = rawPts[i2 * 3 + 2];\n const p3x = rawPts[i3 * 3],\n p3y = rawPts[i3 * 3 + 1],\n p3z = rawPts[i3 * 3 + 2];\n\n for (let sub = 0; sub < subdivisions; sub++) {\n const t = sub / subdivisions;\n const outIdx = (seg * subdivisions + sub) * 3;\n catmullRom(\n finalPts,\n outIdx,\n p0x,\n p0y,\n p0z,\n p1x,\n p1y,\n p1z,\n p2x,\n p2y,\n p2z,\n p3x,\n p3y,\n p3z,\n t\n );\n }\n }\n // Last point = last raw point\n const lastOutIdx = (finalCount - 1) * 3;\n finalPts[lastOutIdx] = rawPts[(count - 1) * 3];\n finalPts[lastOutIdx + 1] = rawPts[(count - 1) * 3 + 1];\n finalPts[lastOutIdx + 2] = rawPts[(count - 1) * 3 + 2];\n } else {\n finalPts = rawPts;\n finalCount = count;\n }\n\n // Limit final count to the number of slots we can fill\n if (finalCount > trailLength) finalCount = trailLength;\n\n // Collapse degenerate segments: when two consecutive smoothed points are\n // nearly identical the shader tangent becomes zero, producing distorted\n // \"squished\" ribbon quads. Shift such points to the next distinct neighbor.\n if (useSmoothing && finalCount >= 2) {\n const MIN_SEG_DIST_SQ = 0.0001 * 0.0001;\n for (let d = 1; d < finalCount; d++) {\n const pi = (d - 1) * 3;\n const ci = d * 3;\n const dx = finalPts[ci] - finalPts[pi];\n const dy = finalPts[ci + 1] - finalPts[pi + 1];\n const dz = finalPts[ci + 2] - finalPts[pi + 2];\n if (dx * dx + dy * dy + dz * dz < MIN_SEG_DIST_SQ) {\n // Snap to previous point — the shader will get a near-zero tangent\n // but the vertex pair collapses to the same position, hiding it\n finalPts[ci] = finalPts[pi];\n finalPts[ci + 1] = finalPts[pi + 1];\n finalPts[ci + 2] = finalPts[pi + 2];\n }\n }\n }\n\n // --- Build ribbon vertices ---\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (vertBase + s * 2) * 3;\n const cIdx = (vertBase + s * 2) * 4;\n const aIdx = vertBase + s * 2;\n const uvIdxBase = (vertBase + s * 2) * 2;\n\n if (s >= finalCount) {\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n px,\n py,\n pz\n );\n continue;\n }\n\n const hx = finalPts[s * 3];\n const hy = finalPts[s * 3 + 1];\n const hz = finalPts[s * 3 + 2];\n\n // Compute an averaged tangent direction for the shader.\n // At interior points we average the forward and backward segment\n // directions so the billboard plane transitions smoothly through\n // bends instead of snapping per-segment.\n let nx: number, ny: number, nz: number;\n if (s > 0 && s < finalCount - 1) {\n // Interior: average of (prev→current) and (current→next)\n const px2 = finalPts[(s - 1) * 3];\n const py2 = finalPts[(s - 1) * 3 + 1];\n const pz2 = finalPts[(s - 1) * 3 + 2];\n const nx2 = finalPts[(s + 1) * 3];\n const ny2 = finalPts[(s + 1) * 3 + 1];\n const nz2 = finalPts[(s + 1) * 3 + 2];\n // Averaged tangent = (current - prev) + (next - current) = next - prev\n const atx = nx2 - px2;\n const aty = ny2 - py2;\n const atz = nz2 - pz2;\n const atLen = Math.sqrt(atx * atx + aty * aty + atz * atz);\n if (atLen > 0.0001) {\n // trailNext = current + normalized averaged tangent (shader computes tangent as trailNext - position)\n nx = hx + atx / atLen;\n ny = hy + aty / atLen;\n nz = hz + atz / atLen;\n } else {\n nx = finalPts[(s + 1) * 3];\n ny = finalPts[(s + 1) * 3 + 1];\n nz = finalPts[(s + 1) * 3 + 2];\n }\n } else if (s < finalCount - 1) {\n // Head: use forward direction\n nx = finalPts[(s + 1) * 3];\n ny = finalPts[(s + 1) * 3 + 1];\n nz = finalPts[(s + 1) * 3 + 2];\n } else if (finalCount >= 2) {\n // Tail: reuse the direction from the previous segment so the\n // ribbon end keeps the same orientation as the last real segment\n // instead of collapsing when the tangent aligns with the Y axis.\n const prevX = finalPts[(s - 1) * 3];\n const prevY = finalPts[(s - 1) * 3 + 1];\n const prevZ = finalPts[(s - 1) * 3 + 2];\n nx = hx + (hx - prevX);\n ny = hy + (hy - prevY);\n nz = hz + (hz - prevZ);\n } else {\n // Single point: nudge to avoid zero tangent\n nx = hx;\n ny = hy + 0.001;\n nz = hz;\n }\n\n // Trail percentage (0=head, 1=tail)\n const t = finalCount > 1 ? s / (finalCount - 1) : 0;\n\n // --- MaxTime: apply additional age-based fade ---\n let timeFade = 1.0;\n if (maxTime > 0 && sampleTimes && effectiveCount > 0) {\n // Map the current smoothed vertex back to the raw sample timeline.\n // When smoothing is active we interpolate between the two bracketing\n // raw samples' timestamps so the fade is smooth instead of stepping.\n const sampleBase = index * trailLength;\n if (useSmoothing && rawCount >= 2) {\n const rawF = (s / Math.max(finalCount - 1, 1)) * (rawCount - 1);\n const rawLo = Math.min(Math.floor(rawF), rawCount - 1);\n const rawHi = Math.min(rawLo + 1, rawCount - 1);\n const frac = rawF - rawLo;\n const slotLo =\n (historyIndex[index] - 1 - rawLo + trailLength * 2) % trailLength;\n const slotHi =\n (historyIndex[index] - 1 - rawHi + trailLength * 2) % trailLength;\n const ageLo = now - sampleTimes[sampleBase + slotLo];\n const ageHi = now - sampleTimes[sampleBase + slotHi];\n const age = ageLo + (ageHi - ageLo) * frac;\n timeFade = 1.0 - Math.min(age / maxTimeMs, 1.0);\n } else {\n const rawS = Math.min(s, rawCount - 1);\n const sampleSlot =\n (historyIndex[index] - 1 - rawS + trailLength * 2) % trailLength;\n const age = now - sampleTimes[sampleBase + sampleSlot];\n timeFade = 1.0 - Math.min(age / maxTimeMs, 1.0);\n }\n }\n\n const widthScale = trailWidthCurveFn(t);\n const opacityScale = trailOpacityCurveFn(t);\n const halfWidth = ribbonWidth * widthScale * 0.5;\n const alpha = ca * opacityScale * timeFade;\n\n const fr = trailColorOverTrailFns\n ? cr * trailColorOverTrailFns.r(t)\n : cr;\n const fg = trailColorOverTrailFns\n ? cg * trailColorOverTrailFns.g(t)\n : cg;\n const fb = trailColorOverTrailFns\n ? cb * trailColorOverTrailFns.b(t)\n : cb;\n\n writeTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n hx,\n hy,\n hz,\n nx,\n ny,\n nz,\n halfWidth,\n t,\n alpha,\n fr,\n fg,\n fb,\n ca,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr\n );\n }\n\n // --- Twist Prevention ---\n // After building the ribbon, ensure ribbon normals are consistent.\n // We compare the implied normal direction of consecutive segments and\n // flip if the dot product with the previous frame's normal is negative.\n if (useTwistPrevention && prevNormal && finalCount >= 2) {\n const nIdx = index * 3;\n // Compute current head tangent\n const tx = finalPts[3] - finalPts[0];\n const ty = finalPts[4] - finalPts[1];\n const tz = finalPts[5] - finalPts[2];\n const tLen = Math.sqrt(tx * tx + ty * ty + tz * tz);\n if (tLen > 0.0001) {\n const ntx = tx / tLen;\n const nty = ty / tLen;\n const ntz = tz / tLen;\n // Use a consistent up vector to compute a reference normal\n let upx = 0,\n upy = 1,\n upz = 0;\n const dot = ntx * upx + nty * upy + ntz * upz;\n if (Math.abs(dot) > 0.999) {\n upx = 1;\n upy = 0;\n upz = 0;\n }\n // cross(tangent, up) = normal\n let cnx = nty * upz - ntz * upy;\n let cny = ntz * upx - ntx * upz;\n let cnz = ntx * upy - nty * upx;\n const cnLen = Math.sqrt(cnx * cnx + cny * cny + cnz * cnz);\n if (cnLen > 0.0001) {\n cnx /= cnLen;\n cny /= cnLen;\n cnz /= cnLen;\n }\n\n // Check dot product with previous normal — if negative, flip\n const prevNx = prevNormal[nIdx];\n const prevNy = prevNormal[nIdx + 1];\n const prevNz = prevNormal[nIdx + 2];\n const hasPrev = prevNx !== 0 || prevNy !== 0 || prevNz !== 0;\n if (hasPrev) {\n const normalDot = cnx * prevNx + cny * prevNy + cnz * prevNz;\n if (normalDot < 0) {\n // Flip all ribbon offsets for this particle by swapping left/right half-widths\n for (let s = 0; s < Math.min(finalCount, trailLength); s++) {\n const aIdx = vertBase + s * 2;\n const hw = trailHalfWidthArr[aIdx];\n trailHalfWidthArr[aIdx] = -hw;\n trailHalfWidthArr[aIdx + 1] = -hw;\n }\n // Also flip the stored normal for next frame\n cnx = -cnx;\n cny = -cny;\n cnz = -cnz;\n }\n }\n\n // Store current normal for next frame\n prevNormal[nIdx] = cnx;\n prevNormal[nIdx + 1] = cny;\n prevNormal[nIdx + 2] = cnz;\n }\n }\n } else if (historyCount[index] > 0) {\n // Particle just became inactive — collapse ribbon and clear history once\n hasUpdates = true;\n historyCount[index] = 0;\n historyIndex[index] = 0;\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (vertBase + s * 2) * 3;\n const cIdx = (vertBase + s * 2) * 4;\n const aIdx = vertBase + s * 2;\n const uvIdxBase = (vertBase + s * 2) * 2;\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n 0,\n 0,\n 0\n );\n }\n }\n }\n\n // --- Connected Ribbons: chain particle positions with Catmull-Rom interpolation ---\n if (useRibbon && _ribbonCount >= 2 && _ribbonIndices) {\n hasUpdates = true;\n const leader = _ribbonIndices[0];\n const leaderVertBase = leader * verticesPerParticle;\n\n // The ribbon uses each particle's current position as a control point,\n // then fills `trailLength` vertices by Catmull-Rom interpolation between them.\n // This produces a smooth, continuous ribbon through all particle positions.\n const controlCount = _ribbonCount;\n const filledCount = Math.min(\n trailLength,\n Math.max(controlCount * 4, controlCount)\n );\n const chainSize = filledCount * 3;\n if (!_rawPoints || _rawPointsSize < chainSize) {\n _rawPoints = new Float32Array(chainSize);\n _rawPointsSize = chainSize;\n }\n\n if (controlCount === 2) {\n // Only 2 particles: linearly interpolate between them\n const p0Idx = _ribbonIndices[0] * 3;\n const p1Idx = _ribbonIndices[1] * 3;\n for (let i = 0; i < filledCount; i++) {\n const t = i / (filledCount - 1);\n _rawPoints[i * 3] =\n positionArr[p0Idx] + t * (positionArr[p1Idx] - positionArr[p0Idx]);\n _rawPoints[i * 3 + 1] =\n positionArr[p0Idx + 1] +\n t * (positionArr[p1Idx + 1] - positionArr[p0Idx + 1]);\n _rawPoints[i * 3 + 2] =\n positionArr[p0Idx + 2] +\n t * (positionArr[p1Idx + 2] - positionArr[p0Idx + 2]);\n }\n } else {\n // 3+ particles: Catmull-Rom interpolation through all control points\n const segments = controlCount - 1;\n const ptsPerSeg = Math.max(1, Math.floor((filledCount - 1) / segments));\n let wi = 0;\n for (let seg = 0; seg < segments && wi < filledCount; seg++) {\n const i0 = Math.max(0, seg - 1);\n const i1 = seg;\n const i2 = Math.min(controlCount - 1, seg + 1);\n const i3 = Math.min(controlCount - 1, seg + 2);\n const p0i = _ribbonIndices[i0] * 3;\n const p1i = _ribbonIndices[i1] * 3;\n const p2i = _ribbonIndices[i2] * 3;\n const p3i = _ribbonIndices[i3] * 3;\n const subCount = seg === segments - 1 ? filledCount - wi : ptsPerSeg;\n for (let sub = 0; sub < subCount && wi < filledCount; sub++) {\n const t = sub / subCount;\n catmullRom(\n _rawPoints,\n wi * 3,\n positionArr[p0i],\n positionArr[p0i + 1],\n positionArr[p0i + 2],\n positionArr[p1i],\n positionArr[p1i + 1],\n positionArr[p1i + 2],\n positionArr[p2i],\n positionArr[p2i + 1],\n positionArr[p2i + 2],\n positionArr[p3i],\n positionArr[p3i + 1],\n positionArr[p3i + 2],\n t\n );\n wi++;\n }\n }\n // Ensure last point is the last particle's position\n if (wi > 0) {\n const lastPIdx = _ribbonIndices[controlCount - 1] * 3;\n _rawPoints[(wi - 1) * 3] = positionArr[lastPIdx];\n _rawPoints[(wi - 1) * 3 + 1] = positionArr[lastPIdx + 1];\n _rawPoints[(wi - 1) * 3 + 2] = positionArr[lastPIdx + 2];\n }\n }\n\n const leaderBase = leader * SCALAR_STRIDE;\n const leaderCr = trailScalarArr[leaderBase + S_COLOR_R];\n const leaderCg = trailScalarArr[leaderBase + S_COLOR_G];\n const leaderCb = trailScalarArr[leaderBase + S_COLOR_B];\n const leaderCa = trailScalarArr[leaderBase + S_COLOR_A];\n\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (leaderVertBase + s * 2) * 3;\n const cIdx = (leaderVertBase + s * 2) * 4;\n const aIdx = leaderVertBase + s * 2;\n const uvIdxBase = (leaderVertBase + s * 2) * 2;\n\n if (s >= filledCount) {\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n 0,\n 0,\n 0\n );\n continue;\n }\n\n const ptIdx = s * 3;\n const ptx = _rawPoints[ptIdx];\n const pty = _rawPoints[ptIdx + 1];\n const ptz = _rawPoints[ptIdx + 2];\n\n // Averaged tangent for interior points\n let nx: number, ny: number, nz: number;\n if (s > 0 && s < filledCount - 1) {\n const px2 = _rawPoints[(s - 1) * 3];\n const py2 = _rawPoints[(s - 1) * 3 + 1];\n const pz2 = _rawPoints[(s - 1) * 3 + 2];\n const nx2 = _rawPoints[(s + 1) * 3];\n const ny2 = _rawPoints[(s + 1) * 3 + 1];\n const nz2 = _rawPoints[(s + 1) * 3 + 2];\n const atx = nx2 - px2;\n const aty = ny2 - py2;\n const atz = nz2 - pz2;\n const atLen = Math.sqrt(atx * atx + aty * aty + atz * atz);\n if (atLen > 0.0001) {\n nx = ptx + atx / atLen;\n ny = pty + aty / atLen;\n nz = ptz + atz / atLen;\n } else {\n nx = _rawPoints[(s + 1) * 3];\n ny = _rawPoints[(s + 1) * 3 + 1];\n nz = _rawPoints[(s + 1) * 3 + 2];\n }\n } else if (s < filledCount - 1) {\n nx = _rawPoints[(s + 1) * 3];\n ny = _rawPoints[(s + 1) * 3 + 1];\n nz = _rawPoints[(s + 1) * 3 + 2];\n } else if (filledCount >= 2) {\n // Tail: reuse previous segment direction\n const prevX = _rawPoints[(s - 1) * 3];\n const prevY = _rawPoints[(s - 1) * 3 + 1];\n const prevZ = _rawPoints[(s - 1) * 3 + 2];\n nx = ptx + (ptx - prevX);\n ny = pty + (pty - prevY);\n nz = ptz + (ptz - prevZ);\n } else {\n nx = ptx;\n ny = pty + 0.001;\n nz = ptz;\n }\n\n const t = filledCount > 1 ? s / (filledCount - 1) : 0;\n\n // --- MaxTime: apply age-based fade to connected ribbon ---\n let ribbonTimeFade = 1.0;\n if (maxTime > 0 && controlCount >= 2) {\n // Map the vertex to the nearest control point(s) and use\n // their creation times to compute an interpolated age.\n const ctrlF = t * (controlCount - 1);\n const ctrlLo = Math.min(Math.floor(ctrlF), controlCount - 1);\n const ctrlHi = Math.min(ctrlLo + 1, controlCount - 1);\n const frac = ctrlF - ctrlLo;\n const ageLo = now - generalData.creationTimes[_ribbonIndices[ctrlLo]];\n const ageHi = now - generalData.creationTimes[_ribbonIndices[ctrlHi]];\n const age = ageLo + (ageHi - ageLo) * frac;\n ribbonTimeFade = 1.0 - Math.min(age / maxTimeMs, 1.0);\n }\n\n const widthScale = trailWidthCurveFn(t);\n const opacityScale = trailOpacityCurveFn(t);\n const halfWidth = trailConfig.width * widthScale * 0.5;\n const alpha = leaderCa * opacityScale * ribbonTimeFade;\n const fr = trailColorOverTrailFns\n ? leaderCr * trailColorOverTrailFns.r(t)\n : leaderCr;\n const fg = trailColorOverTrailFns\n ? leaderCg * trailColorOverTrailFns.g(t)\n : leaderCg;\n const fb = trailColorOverTrailFns\n ? leaderCb * trailColorOverTrailFns.b(t)\n : leaderCb;\n\n writeTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n ptx,\n pty,\n ptz,\n nx,\n ny,\n nz,\n halfWidth,\n t,\n alpha,\n fr,\n fg,\n fb,\n leaderCa,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr\n );\n }\n\n // --- Twist Prevention for connected ribbon (applied to leader) ---\n if (useTwistPrevention && prevNormal && filledCount >= 2) {\n const nIdx = leader * 3;\n const tx = _rawPoints[3] - _rawPoints[0];\n const ty = _rawPoints[4] - _rawPoints[1];\n const tz = _rawPoints[5] - _rawPoints[2];\n const tLen = Math.sqrt(tx * tx + ty * ty + tz * tz);\n if (tLen > 0.0001) {\n const ntx = tx / tLen;\n const nty = ty / tLen;\n const ntz = tz / tLen;\n let upx = 0,\n upy = 1,\n upz = 0;\n const dot = ntx * upx + nty * upy + ntz * upz;\n if (Math.abs(dot) > 0.999) {\n upx = 1;\n upy = 0;\n upz = 0;\n }\n let cnx = nty * upz - ntz * upy;\n let cny = ntz * upx - ntx * upz;\n let cnz = ntx * upy - nty * upx;\n const cnLen = Math.sqrt(cnx * cnx + cny * cny + cnz * cnz);\n if (cnLen > 0.0001) {\n cnx /= cnLen;\n cny /= cnLen;\n cnz /= cnLen;\n }\n const prevNx = prevNormal[nIdx];\n const prevNy = prevNormal[nIdx + 1];\n const prevNz = prevNormal[nIdx + 2];\n const hasPrev = prevNx !== 0 || prevNy !== 0 || prevNz !== 0;\n if (hasPrev) {\n const normalDot = cnx * prevNx + cny * prevNy + cnz * prevNz;\n if (normalDot < 0) {\n for (let s = 0; s < Math.min(filledCount, trailLength); s++) {\n const aIdx = leaderVertBase + s * 2;\n const hw = trailHalfWidthArr[aIdx];\n trailHalfWidthArr[aIdx] = -hw;\n trailHalfWidthArr[aIdx + 1] = -hw;\n }\n cnx = -cnx;\n cny = -cny;\n cnz = -cnz;\n }\n }\n prevNormal[nIdx] = cnx;\n prevNormal[nIdx + 1] = cny;\n prevNormal[nIdx + 2] = cnz;\n }\n }\n\n // Clear non-leader ribbon particles' trail vertices\n for (let ri = 1; ri < _ribbonCount; ri++) {\n const pIdx = _ribbonIndices[ri];\n const pVertBase = pIdx * verticesPerParticle;\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (pVertBase + s * 2) * 3;\n const cIdx = (pVertBase + s * 2) * 4;\n const aIdx = pVertBase + s * 2;\n const uvIdxBase = (pVertBase + s * 2) * 2;\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n 0,\n 0,\n 0\n );\n }\n }\n }\n\n if (hasUpdates) {\n trailPositionAttr.needsUpdate = true;\n trailAlphaAttr.needsUpdate = true;\n trailColorAttr.needsUpdate = true;\n trailNextAttrCached.needsUpdate = true;\n trailHalfWidthAttrCached.needsUpdate = true;\n trailUVAttrCached.needsUpdate = true;\n }\n};\n\nexport const updateParticleSystems = (cycleData: CycleData) => {\n createdParticleSystems.forEach((props) =>\n updateParticleSystemInstance(props, cycleData)\n );\n};\n","import * as THREE from 'three';\nimport {\n CurveFunctionId,\n curveFunctionIdMap,\n getCurveFunction,\n} from './three-particles-curves.js';\nimport {\n CollisionPlaneMode,\n ForceFieldFalloff,\n ForceFieldType,\n LifeTimeCurve,\n} from './three-particles-enums.js';\nimport { blendingMap } from './three-particles.js';\nimport type {\n BezierCurve,\n CollisionPlaneConfig,\n CurveFunction,\n EasingCurve,\n ForceFieldConfig,\n LifetimeCurve,\n ParticleSystemConfig,\n} from './types.js';\n\n/** Current serialization format version */\nconst SERIALIZATION_VERSION = 1;\n\ntype BlendingKey = keyof typeof blendingMap;\ntype RawObject = Record<string, unknown>;\n\n// Reverse blending map: THREE.Blending number → string key\nconst reverseBlendingMap = new Map<number, BlendingKey>(\n (Object.entries(blendingMap) as [BlendingKey, number][]).map(([k, v]) => [\n v,\n k,\n ])\n);\n\n// Reverse curve function map: function reference → CurveFunctionId string\nconst reverseCurveFunctionMap = new Map<CurveFunction, string>();\nfor (const [id, fn] of Object.entries(curveFunctionIdMap) as [\n string,\n CurveFunction,\n][]) {\n if (fn) reverseCurveFunctionMap.set(fn, id);\n}\n\n// ─── SERIALIZATION ───────────────────────────────────────────────────────────\n\nfunction serializeAny(value: unknown, key?: string): unknown {\n if (value === null || value === undefined) return value;\n if (value instanceof THREE.Vector3)\n return { x: value.x, y: value.y, z: value.z };\n if (value instanceof THREE.Vector2) return { x: value.x, y: value.y };\n if (value instanceof THREE.Texture) return undefined;\n if (typeof value === 'function') return undefined;\n if (Array.isArray(value)) return value.map((item) => serializeAny(item));\n if (typeof value === 'object') {\n const obj = value as RawObject;\n\n // EasingCurve: replace curveFunction with curveFunctionId\n if (\n obj['type'] === LifeTimeCurve.EASING &&\n typeof obj['curveFunction'] === 'function'\n ) {\n const id = reverseCurveFunctionMap.get(\n obj['curveFunction'] as CurveFunction\n );\n if (!id) {\n throw new Error(\n 'Cannot serialize a custom curveFunction. Use a predefined CurveFunctionId instead.'\n );\n }\n return {\n type: LifeTimeCurve.EASING,\n curveFunctionId: id,\n ...(obj['scale'] !== undefined ? { scale: obj['scale'] } : {}),\n };\n }\n\n const result: RawObject = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k === 'onUpdate' || k === 'onComplete') continue;\n if (k === 'blending' && typeof v === 'number') {\n result[k] = reverseBlendingMap.get(v as THREE.Blending) ?? v;\n continue;\n }\n const serialized = serializeAny(v, k);\n if (serialized !== undefined) result[k] = serialized;\n }\n return result;\n }\n return value;\n}\n\n/**\n * Serializes a `ParticleSystemConfig` to a JSON string.\n *\n * - `THREE.Vector3` / `THREE.Vector2` are converted to plain `{x, y, z}` / `{x, y}` objects.\n * - `renderer.blending` is converted to its string identifier (e.g. `\"THREE.AdditiveBlending\"`).\n * - `EasingCurve.curveFunction` is replaced by a `curveFunctionId` string.\n * Only predefined `CurveFunctionId` functions can be serialized; custom functions throw.\n * - `THREE.Texture` (`map`), callback fields (`onUpdate`, `onComplete`) are omitted.\n * - An `_editorData` field and other unknown fields are preserved as-is.\n * - A `_version` field is added for forward-compatibility.\n *\n * @param config - The particle system configuration to serialize.\n * @returns A JSON string representation of the config.\n * @throws If the config contains a custom (non-predefined) `curveFunction`.\n *\n * @example\n * ```typescript\n * import { serializeParticleSystem } from '@newkrok/three-particles';\n *\n * const json = serializeParticleSystem(config);\n * localStorage.setItem('myEffect', json);\n * ```\n */\nexport function serializeParticleSystem(config: ParticleSystemConfig): string {\n const serialized = serializeAny(config) as RawObject;\n return JSON.stringify({ _version: SERIALIZATION_VERSION, ...serialized });\n}\n\n// ─── DESERIALIZATION ──────────────────────────────────────────────────────────\n\n/**\n * Reconstructs a `LifetimeCurve` from its serialized form.\n * Handles:\n * - Legacy editor format: `{ bezierPoints: [...] }` (no `type` field → treated as BEZIER)\n * - Normal BEZIER: `{ type: \"BEZIER\", bezierPoints: [...] }`\n * - Serialized EASING: `{ type: \"EASING\", curveFunctionId: \"...\" }`\n */\nfunction deserializeCurve(raw: unknown): LifetimeCurve {\n const obj = raw as RawObject;\n\n // Legacy format from editor: bezierPoints present but no type\n if (Array.isArray(obj['bezierPoints']) && !obj['type']) {\n return { type: LifeTimeCurve.BEZIER, ...obj } as BezierCurve;\n }\n\n if (obj['type'] === LifeTimeCurve.EASING) {\n const id = obj['curveFunctionId'] as CurveFunctionId;\n const fn = getCurveFunction(id);\n if (!fn) {\n throw new Error(\n `Unknown curveFunctionId: \"${id}\". Use a value from CurveFunctionId.`\n );\n }\n const curve: EasingCurve = {\n type: LifeTimeCurve.EASING,\n curveFunction: fn,\n };\n if (obj['scale'] !== undefined) curve.scale = obj['scale'] as number;\n return curve;\n }\n\n // BEZIER (explicit type) or passthrough\n return obj as BezierCurve;\n}\n\n/**\n * Deserializes a value that can be `Constant | RandomBetweenTwoConstants | LifetimeCurve`.\n * Numbers pass through; objects are inspected for curve shape.\n */\nfunction deserializeCurveOrValue(\n value: unknown\n): number | Record<string, unknown> | LifetimeCurve | undefined {\n if (typeof value === 'number') return value;\n if (!value || typeof value !== 'object') return value as undefined;\n const obj = value as RawObject;\n const looksLikeCurve =\n Array.isArray(obj['bezierPoints']) ||\n obj['type'] === LifeTimeCurve.BEZIER ||\n obj['type'] === LifeTimeCurve.EASING ||\n typeof obj['curveFunctionId'] === 'string';\n if (looksLikeCurve) return deserializeCurve(obj);\n return obj; // RandomBetweenTwoConstants or other plain object\n}\n\nfunction deserializeVector3(raw: unknown): THREE.Vector3 | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const { x = 0, y = 0, z = 0 } = raw as { x?: number; y?: number; z?: number };\n return new THREE.Vector3(x, y, z);\n}\n\nfunction deserializeVector2(raw: unknown): THREE.Vector2 | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const { x = 1, y = 1 } = raw as { x?: number; y?: number };\n return new THREE.Vector2(x, y);\n}\n\nfunction deserializeConfig(raw: RawObject): ParticleSystemConfig {\n const config: ParticleSystemConfig = {};\n\n // transform\n if (raw['transform'] && typeof raw['transform'] === 'object') {\n const t = raw['transform'] as RawObject;\n config.transform = {\n position: deserializeVector3(t['position']),\n rotation: deserializeVector3(t['rotation']),\n scale: deserializeVector3(t['scale']),\n };\n }\n\n // scalar / enum fields (pass through)\n for (const field of [\n 'duration',\n 'looping',\n 'gravity',\n 'simulationSpace',\n 'simulationBackend',\n 'maxParticles',\n ] as const) {\n if (field in raw) (config as RawObject)[field] = raw[field];\n }\n\n // start value fields (Constant | RandomBetweenTwoConstants | LifetimeCurve)\n for (const field of [\n 'startDelay',\n 'startLifetime',\n 'startSpeed',\n 'startSize',\n 'startOpacity',\n 'startRotation',\n ] as const) {\n if (field in raw)\n (config as RawObject)[field] = deserializeCurveOrValue(raw[field]);\n }\n\n // startColor (plain MinMaxColor — no reconstruction needed)\n if ('startColor' in raw)\n config.startColor = raw['startColor'] as ParticleSystemConfig['startColor'];\n\n // emission\n if (raw['emission'] && typeof raw['emission'] === 'object') {\n const e = raw['emission'] as RawObject;\n config.emission = {\n rateOverTime: deserializeCurveOrValue(e['rateOverTime']) as NonNullable<\n ParticleSystemConfig['emission']\n >['rateOverTime'],\n rateOverDistance: deserializeCurveOrValue(\n e['rateOverDistance']\n ) as NonNullable<ParticleSystemConfig['emission']>['rateOverDistance'],\n bursts: Array.isArray(e['bursts'])\n ? (e['bursts'] as NonNullable<\n ParticleSystemConfig['emission']\n >['bursts'])\n : [],\n };\n }\n\n // shape (plain object with enum string values — no reconstruction needed)\n if ('shape' in raw)\n config.shape = raw['shape'] as ParticleSystemConfig['shape'];\n\n // renderer: convert blending string → THREE.Blending number\n if (raw['renderer'] && typeof raw['renderer'] === 'object') {\n const r = raw['renderer'] as RawObject;\n const blending =\n typeof r['blending'] === 'string'\n ? (blendingMap[r['blending'] as BlendingKey] ?? THREE.NormalBlending)\n : ((r['blending'] as number | undefined) ?? THREE.NormalBlending);\n config.renderer = { ...r, blending } as ParticleSystemConfig['renderer'];\n }\n\n // velocityOverLifetime\n if (\n raw['velocityOverLifetime'] &&\n typeof raw['velocityOverLifetime'] === 'object'\n ) {\n const vol = raw['velocityOverLifetime'] as RawObject;\n const deserializeAxis = (\n axis: unknown\n ): { x?: unknown; y?: unknown; z?: unknown } => {\n if (!axis || typeof axis !== 'object') return {};\n const a = axis as RawObject;\n return {\n ...(a['x'] !== undefined ? { x: deserializeCurveOrValue(a['x']) } : {}),\n ...(a['y'] !== undefined ? { y: deserializeCurveOrValue(a['y']) } : {}),\n ...(a['z'] !== undefined ? { z: deserializeCurveOrValue(a['z']) } : {}),\n };\n };\n config.velocityOverLifetime = {\n isActive: (vol['isActive'] as boolean) ?? false,\n linear: deserializeAxis(vol['linear']) as NonNullable<\n ParticleSystemConfig['velocityOverLifetime']\n >['linear'],\n orbital: deserializeAxis(vol['orbital']) as NonNullable<\n ParticleSystemConfig['velocityOverLifetime']\n >['orbital'],\n };\n }\n\n // sizeOverLifetime / opacityOverLifetime — both have isActive + lifetimeCurve\n for (const field of ['sizeOverLifetime', 'opacityOverLifetime'] as const) {\n if (raw[field] && typeof raw[field] === 'object') {\n const m = raw[field] as RawObject;\n (config as RawObject)[field] = {\n isActive: (m['isActive'] as boolean) ?? false,\n lifetimeCurve: deserializeCurve(m['lifetimeCurve']),\n };\n }\n }\n\n // colorOverLifetime — r/g/b are LifetimeCurves; isActive defaults to true when present\n if (\n raw['colorOverLifetime'] &&\n typeof raw['colorOverLifetime'] === 'object'\n ) {\n const col = raw['colorOverLifetime'] as RawObject;\n config.colorOverLifetime = {\n isActive: (col['isActive'] as boolean) ?? true,\n r: deserializeCurve(col['r']),\n g: deserializeCurve(col['g']),\n b: deserializeCurve(col['b']),\n };\n }\n\n // rotationOverLifetime (isActive + RandomBetweenTwoConstants — no curves)\n if (\n raw['rotationOverLifetime'] &&\n typeof raw['rotationOverLifetime'] === 'object'\n ) {\n config.rotationOverLifetime = raw[\n 'rotationOverLifetime'\n ] as ParticleSystemConfig['rotationOverLifetime'];\n }\n\n // noise (NoiseConfig is plain data — no reconstruction needed)\n if (raw['noise'] && typeof raw['noise'] === 'object') {\n config.noise = raw['noise'] as ParticleSystemConfig['noise'];\n }\n\n // textureSheetAnimation — reconstruct tiles Vector2, deserialize startFrame\n if (\n raw['textureSheetAnimation'] &&\n typeof raw['textureSheetAnimation'] === 'object'\n ) {\n const tsa = raw['textureSheetAnimation'] as RawObject;\n config.textureSheetAnimation = {\n ...(tsa as ParticleSystemConfig['textureSheetAnimation']),\n tiles: deserializeVector2(tsa['tiles']),\n startFrame: deserializeCurveOrValue(tsa['startFrame']) as NonNullable<\n ParticleSystemConfig['textureSheetAnimation']\n >['startFrame'],\n };\n }\n\n // subEmitters — recursively deserialize nested configs\n if (Array.isArray(raw['subEmitters'])) {\n config.subEmitters = (raw['subEmitters'] as RawObject[]).map((se) => ({\n ...(se as NonNullable<ParticleSystemConfig['subEmitters']>[number]),\n config: deserializeConfig(se['config'] as RawObject),\n }));\n }\n\n // forceFields — array of ForceFieldConfig objects\n if (Array.isArray(raw['forceFields'])) {\n config.forceFields = (raw['forceFields'] as RawObject[]).map((ff) => {\n const result: ForceFieldConfig = {};\n if ('isActive' in ff) result.isActive = ff['isActive'] as boolean;\n if ('type' in ff) result.type = ff['type'] as ForceFieldType;\n if (ff['position']) result.position = deserializeVector3(ff['position']);\n if (ff['direction'])\n result.direction = deserializeVector3(ff['direction']);\n if ('strength' in ff)\n result.strength = deserializeCurveOrValue(\n ff['strength']\n ) as ForceFieldConfig['strength'];\n if ('range' in ff)\n result.range =\n ff['range'] === null ? Infinity : (ff['range'] as number);\n if ('falloff' in ff) result.falloff = ff['falloff'] as ForceFieldFalloff;\n return result;\n });\n }\n\n // collisionPlanes — array of CollisionPlaneConfig objects\n if (Array.isArray(raw['collisionPlanes'])) {\n config.collisionPlanes = (raw['collisionPlanes'] as RawObject[]).map(\n (cp) => {\n const result: CollisionPlaneConfig = {};\n if ('isActive' in cp) result.isActive = cp['isActive'] as boolean;\n if ('mode' in cp) result.mode = cp['mode'] as CollisionPlaneMode;\n if (cp['position'])\n result.position = deserializeVector3(cp['position']);\n if (cp['normal']) result.normal = deserializeVector3(cp['normal']);\n if ('dampen' in cp) result.dampen = cp['dampen'] as number;\n if ('lifetimeLoss' in cp)\n result.lifetimeLoss = cp['lifetimeLoss'] as number;\n return result;\n }\n );\n }\n\n // _editorData and any other unknown fields — preserve as-is\n for (const key of Object.keys(raw)) {\n if (!(key in config) && key !== '_version' && raw[key] !== null) {\n (config as RawObject)[key] = raw[key];\n }\n }\n\n return config;\n}\n\n/**\n * Deserializes a JSON string produced by `serializeParticleSystem` (or by the\n * three-particles-editor) into a `ParticleSystemConfig` object.\n *\n * - Blending strings (e.g. `\"THREE.AdditiveBlending\"`) are converted back to\n * `THREE.Blending` constants.\n * - `{x, y, z}` objects under `transform` are reconstructed as `THREE.Vector3`.\n * - `{x, y}` objects under `textureSheetAnimation.tiles` are reconstructed as `THREE.Vector2`.\n * - Legacy Bézier curves without a `type` field (editor format) are normalized.\n * - Easing curves stored as `{ type: \"EASING\", curveFunctionId }` have their\n * `curveFunction` resolved from the predefined map.\n * - `_editorData` and other unknown fields are preserved.\n *\n * @param json - A JSON string produced by `serializeParticleSystem` or the editor.\n * @returns A fully reconstructed `ParticleSystemConfig`.\n *\n * @example\n * ```typescript\n * import { deserializeParticleSystem } from '@newkrok/three-particles';\n *\n * const config = deserializeParticleSystem(localStorage.getItem('myEffect')!);\n * createParticleSystem(config);\n * ```\n */\nexport function deserializeParticleSystem(json: string): ParticleSystemConfig {\n const parsed = JSON.parse(json) as RawObject & { _version?: number };\n\n const { _version: _, ...raw } = parsed;\n return deserializeConfig(raw);\n}\n"]}
1
+ {"version":3,"sources":["../src/js/effects/three-particles/version.ts","../src/js/effects/three-particles/color-utils.ts","../src/js/effects/three-particles/three-particles-bezier.ts","../src/js/effects/three-particles/three-particles-curves.ts","../src/js/effects/three-particles/three-particles-enums.ts","../src/js/effects/three-particles/three-particles-constants.ts","../src/js/effects/three-particles/three-particles-utils.ts","../src/js/effects/three-particles/three-particles-modifiers.ts","../src/js/effects/three-particles/three-particles-renderer-detect.ts","../src/js/effects/three-particles/shaders/instanced-particle-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/instanced-particle-vertex-shader.glsl.ts","../src/js/effects/three-particles/shaders/mesh-particle-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/mesh-particle-vertex-shader.glsl.ts","../src/js/effects/three-particles/shaders/particle-system-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/particle-system-vertex-shader.glsl.ts","../src/js/effects/three-particles/shaders/trail-fragment-shader.glsl.ts","../src/js/effects/three-particles/shaders/trail-vertex-shader.glsl.ts","../src/js/effects/three-particles/three-particles-collision.ts","../src/js/effects/three-particles/three-particles-forces.ts","../src/js/effects/three-particles/three-particles.ts","../src/js/effects/three-particles/three-particles-serialization.ts"],"names":["CurveFunctionId","SimulationSpace","Shape","EmitFrom","TimeMode","LifeTimeCurve","SubEmitterTrigger","ForceFieldType","RendererType","ForceFieldFalloff","CollisionPlaneMode","SimulationBackend","THREE","THREE2","THREE3","THREE4","posIdx","px","py","pz","THREE6"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The semver version of `@newkrok/three-particles`, injected at build time\n * from `package.json` via `tsup`'s `define` option (see `tsup.config.ts`).\n *\n * Exposed for runtime introspection (debugging, bug reports). Mirrors the\n * three.js `REVISION` + `window.__THREE__` pattern.\n *\n * In test environments (jest/ts-jest) the build-time define isn't applied,\n * so `__THREE_PARTICLES_VERSION__` is undefined; we fall back to `'0.0.0-dev'`\n * so imports don't throw.\n */\ndeclare const __THREE_PARTICLES_VERSION__: string;\n\nexport const REVISION: string =\n typeof __THREE_PARTICLES_VERSION__ !== 'undefined'\n ? __THREE_PARTICLES_VERSION__\n : '0.0.0-dev';\n\nif (typeof globalThis !== 'undefined') {\n const g = globalThis as { __THREE_PARTICLES__?: string };\n if (g.__THREE_PARTICLES__ && g.__THREE_PARTICLES__ !== REVISION) {\n // eslint-disable-next-line no-console\n console.warn(\n 'WARNING: Multiple instances of @newkrok/three-particles being imported.'\n );\n } else {\n g.__THREE_PARTICLES__ = REVISION;\n }\n}\n","/**\n * Standard IEC 61966-2-1 sRGB → linear transfer function.\n * Matches `THREE.ColorManagement.SRGBToLinear` and the GLSL\n * `ShaderChunk.colorspace_fragment` implementation, so that user-provided\n * colors go through the exact same conversion the rest of the Three.js\n * pipeline uses for sRGB-tagged inputs.\n *\n * Input: a channel value in [0, 1] interpreted as sRGB.\n * Output: the corresponding linear value in [0, 1].\n */\nexport const sRGBToLinear = (c: number): number =>\n c < 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n\n/**\n * Standard IEC 61966-2-1 linear → sRGB transfer function.\n * Inverse of {@link sRGBToLinear}. Useful for one-shot migration of\n * legacy color values that were authored under the old raw-byte pipeline.\n */\nexport const linearToSRGB = (c: number): number =>\n c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;\n\n/**\n * Converts an sRGB {r, g, b} triplet to linear space.\n * Used when uploading user-authored colors (e.g. `backgroundColor`) as\n * shader uniforms that must match the linear-space texture samples and\n * vertex colors used elsewhere in the pipeline. Missing channels default\n * to 0 to mirror the permissive shape of the `Rgb` config type.\n */\nexport const rgbSRGBToLinear = (c: {\n r?: number;\n g?: number;\n b?: number;\n}): { r: number; g: number; b: number } => ({\n r: sRGBToLinear(c.r ?? 0),\n g: sRGBToLinear(c.g ?? 0),\n b: sRGBToLinear(c.b ?? 0),\n});\n","import { BezierPoint, CurveFunction } from './types.js';\n\nconst cache: Array<{\n bezierPoints: Array<BezierPoint>;\n curveFunction: CurveFunction;\n referencedBy: Array<number>;\n}> = [];\n\nconst nCr = (n: number, k: number) => {\n let z = 1;\n for (let i = 1; i <= k; i++) z *= (n + 1 - i) / i;\n return z;\n};\n\nexport const createBezierCurveFunction = (\n particleSystemId: number,\n bezierPoints: Array<BezierPoint>\n) => {\n const cacheEntry = cache.find((item) => item.bezierPoints === bezierPoints);\n\n if (cacheEntry) {\n if (!cacheEntry.referencedBy.includes(particleSystemId))\n cacheEntry.referencedBy.push(particleSystemId);\n return cacheEntry.curveFunction;\n }\n\n const entry = {\n referencedBy: [particleSystemId],\n bezierPoints,\n curveFunction: (percentage: number): number => {\n if (percentage < 0) return bezierPoints[0].y;\n if (percentage > 1) return bezierPoints[bezierPoints.length - 1].y;\n\n let start = 0;\n let stop = bezierPoints.length - 1;\n\n bezierPoints.find((point, index) => {\n const result = percentage < (point.percentage ?? 0);\n if (result) stop = index;\n else if (point.percentage !== undefined) start = index;\n return result;\n });\n\n const n = stop - start;\n const calculatedPercentage =\n (percentage - (bezierPoints[start].percentage ?? 0)) /\n ((bezierPoints[stop].percentage ?? 1) -\n (bezierPoints[start].percentage ?? 0));\n\n let value = 0;\n for (let i = 0; i <= n; i++) {\n const p = bezierPoints[start + i];\n const c =\n nCr(n, i) *\n Math.pow(1 - calculatedPercentage, n - i) *\n Math.pow(calculatedPercentage, i);\n value += c * p.y;\n }\n return value;\n },\n };\n\n cache.push(entry);\n return entry.curveFunction;\n};\n\nexport const removeBezierCurveFunction = (particleSystemId: number) => {\n while (true) {\n const index = cache.findIndex((item) =>\n item.referencedBy.includes(particleSystemId)\n );\n if (index === -1) break;\n const entry = cache[index];\n entry.referencedBy = entry.referencedBy.filter(\n (id) => id !== particleSystemId\n );\n if (entry.referencedBy.length === 0) cache.splice(index, 1);\n }\n};\n\nexport const getBezierCacheSize = () => cache.length;\n","import Easing from 'easing-functions';\nimport { CurveFunction } from './types.js';\n\n/**\n * Predefined easing function identifiers for animating particle properties\n * over their lifetime.\n *\n * These functions control the rate of change and create different animation\n * feels. Each type has three variants:\n * - **IN**: Starts slow, accelerates toward the end\n * - **OUT**: Starts fast, decelerates toward the end\n * - **IN_OUT**: Combines both, slow at start and end, fast in middle\n *\n * @enum {string}\n *\n * @see {@link https://easings.net/} - Visual reference for easing functions\n */\nexport const enum CurveFunctionId {\n /** Use custom Bezier curve (not an easing function) */\n BEZIER = 'BEZIER',\n\n /** Linear interpolation with constant rate of change */\n LINEAR = 'LINEAR',\n\n /** Quadratic (t²) easing - gentle acceleration */\n QUADRATIC_IN = 'QUADRATIC_IN',\n /** Quadratic (t²) easing - gentle deceleration */\n QUADRATIC_OUT = 'QUADRATIC_OUT',\n /** Quadratic (t²) easing - gentle acceleration then deceleration */\n QUADRATIC_IN_OUT = 'QUADRATIC_IN_OUT',\n\n /** Cubic (t³) easing - moderate acceleration */\n CUBIC_IN = 'CUBIC_IN',\n /** Cubic (t³) easing - moderate deceleration */\n CUBIC_OUT = 'CUBIC_OUT',\n /** Cubic (t³) easing - moderate acceleration then deceleration */\n CUBIC_IN_OUT = 'CUBIC_IN_OUT',\n\n /** Quartic (t⁴) easing - strong acceleration */\n QUARTIC_IN = 'QUARTIC_IN',\n /** Quartic (t⁴) easing - strong deceleration */\n QUARTIC_OUT = 'QUARTIC_OUT',\n /** Quartic (t⁴) easing - strong acceleration then deceleration */\n QUARTIC_IN_OUT = 'QUARTIC_IN_OUT',\n\n /** Quintic (t⁵) easing - very strong acceleration */\n QUINTIC_IN = 'QUINTIC_IN',\n /** Quintic (t⁵) easing - very strong deceleration */\n QUINTIC_OUT = 'QUINTIC_OUT',\n /** Quintic (t⁵) easing - very strong acceleration then deceleration */\n QUINTIC_IN_OUT = 'QUINTIC_IN_OUT',\n\n /** Sinusoidal easing - smooth, natural acceleration */\n SINUSOIDAL_IN = 'SINUSOIDAL_IN',\n /** Sinusoidal easing - smooth, natural deceleration */\n SINUSOIDAL_OUT = 'SINUSOIDAL_OUT',\n /** Sinusoidal easing - smooth acceleration then deceleration */\n SINUSOIDAL_IN_OUT = 'SINUSOIDAL_IN_OUT',\n\n /** Exponential easing - dramatic, explosive acceleration */\n EXPONENTIAL_IN = 'EXPONENTIAL_IN',\n /** Exponential easing - dramatic, explosive deceleration */\n EXPONENTIAL_OUT = 'EXPONENTIAL_OUT',\n /** Exponential easing - dramatic acceleration then deceleration */\n EXPONENTIAL_IN_OUT = 'EXPONENTIAL_IN_OUT',\n\n /** Circular easing - sharp acceleration with curved trajectory */\n CIRCULAR_IN = 'CIRCULAR_IN',\n /** Circular easing - sharp deceleration with curved trajectory */\n CIRCULAR_OUT = 'CIRCULAR_OUT',\n /** Circular easing - sharp acceleration then deceleration */\n CIRCULAR_IN_OUT = 'CIRCULAR_IN_OUT',\n\n /** Elastic easing - oscillates back before accelerating (spring-like) */\n ELASTIC_IN = 'ELASTIC_IN',\n /** Elastic easing - overshoots then oscillates back (spring-like) */\n ELASTIC_OUT = 'ELASTIC_OUT',\n /** Elastic easing - oscillates at both ends (spring-like) */\n ELASTIC_IN_OUT = 'ELASTIC_IN_OUT',\n\n /** Back easing - pulls back before accelerating forward */\n BACK_IN = 'BACK_IN',\n /** Back easing - overshoots forward then pulls back */\n BACK_OUT = 'BACK_OUT',\n /** Back easing - pulls back, overshoots, then settles */\n BACK_IN_OUT = 'BACK_IN_OUT',\n\n /** Bounce easing - bounces at the start */\n BOUNCE_IN = 'BOUNCE_IN',\n /** Bounce easing - bounces at the end (like a ball landing) */\n BOUNCE_OUT = 'BOUNCE_OUT',\n /** Bounce easing - bounces at both start and end */\n BOUNCE_IN_OUT = 'BOUNCE_IN_OUT',\n}\n\nexport const curveFunctionIdMap: Partial<\n Record<CurveFunctionId, CurveFunction>\n> = {\n [CurveFunctionId.LINEAR]: Easing.Linear.None,\n [CurveFunctionId.QUADRATIC_IN]: Easing.Quadratic.In,\n [CurveFunctionId.QUADRATIC_OUT]: Easing.Quadratic.Out,\n [CurveFunctionId.QUADRATIC_IN_OUT]: Easing.Quadratic.InOut,\n [CurveFunctionId.CUBIC_IN]: Easing.Cubic.In,\n [CurveFunctionId.CUBIC_OUT]: Easing.Cubic.Out,\n [CurveFunctionId.CUBIC_IN_OUT]: Easing.Cubic.InOut,\n [CurveFunctionId.QUARTIC_IN]: Easing.Quartic.In,\n [CurveFunctionId.QUARTIC_OUT]: Easing.Quartic.Out,\n [CurveFunctionId.QUARTIC_IN_OUT]: Easing.Quartic.InOut,\n [CurveFunctionId.QUINTIC_IN]: Easing.Quintic.In,\n [CurveFunctionId.QUINTIC_OUT]: Easing.Quintic.Out,\n [CurveFunctionId.QUINTIC_IN_OUT]: Easing.Quintic.InOut,\n [CurveFunctionId.SINUSOIDAL_IN]: Easing.Sinusoidal.In,\n [CurveFunctionId.SINUSOIDAL_OUT]: Easing.Sinusoidal.Out,\n [CurveFunctionId.SINUSOIDAL_IN_OUT]: Easing.Sinusoidal.InOut,\n [CurveFunctionId.EXPONENTIAL_IN]: Easing.Exponential.In,\n [CurveFunctionId.EXPONENTIAL_OUT]: Easing.Exponential.Out,\n [CurveFunctionId.EXPONENTIAL_IN_OUT]: Easing.Exponential.InOut,\n [CurveFunctionId.CIRCULAR_IN]: Easing.Circular.In,\n [CurveFunctionId.CIRCULAR_OUT]: Easing.Circular.Out,\n [CurveFunctionId.CIRCULAR_IN_OUT]: Easing.Circular.InOut,\n [CurveFunctionId.ELASTIC_IN]: Easing.Elastic.In,\n [CurveFunctionId.ELASTIC_OUT]: Easing.Elastic.Out,\n [CurveFunctionId.ELASTIC_IN_OUT]: Easing.Elastic.InOut,\n [CurveFunctionId.BACK_IN]: Easing.Back.In,\n [CurveFunctionId.BACK_OUT]: Easing.Back.Out,\n [CurveFunctionId.BACK_IN_OUT]: Easing.Back.InOut,\n [CurveFunctionId.BOUNCE_IN]: Easing.Bounce.In,\n [CurveFunctionId.BOUNCE_OUT]: Easing.Bounce.Out,\n [CurveFunctionId.BOUNCE_IN_OUT]: Easing.Bounce.InOut,\n};\n\n/**\n * Resolves a curve function from an identifier or returns the function itself.\n *\n * This utility function allows you to use either a {@link CurveFunctionId} string\n * identifier or a custom function directly.\n *\n * @param curveFunctionId - Either a {@link CurveFunctionId} enum value or a\n * custom {@link CurveFunction} implementation\n * @returns The actual easing function that takes a normalized time value (0-1)\n * and returns the eased value\n *\n * @example\n * ```typescript\n * import { getCurveFunction, CurveFunctionId } from '@newkrok/three-particles';\n *\n * // Using a predefined easing function\n * const easingFunc = getCurveFunction(CurveFunctionId.CUBIC_OUT);\n * console.log(easingFunc(0.5)); // Returns eased value at 50% progress\n *\n * // Using a custom function\n * const customEasing = (t: number) => t * t; // Quadratic\n * const customFunc = getCurveFunction(customEasing);\n * console.log(customFunc(0.5)); // Returns 0.25\n * ```\n */\nexport const getCurveFunction = (\n curveFunctionId: CurveFunctionId | CurveFunction\n): CurveFunction =>\n typeof curveFunctionId === 'function'\n ? curveFunctionId\n : curveFunctionIdMap[curveFunctionId]!;\n","/**\n * Defines the coordinate space in which particles are simulated.\n *\n * @enum {string}\n */\nexport const enum SimulationSpace {\n /**\n * Particles move relative to the emitter's local coordinate system.\n * When the emitter moves or rotates, particles move with it.\n * Ideal for effects attached to moving objects (e.g., engine trails, character auras).\n */\n LOCAL = 'LOCAL',\n\n /**\n * Particles move in world space and are independent of the emitter's transform.\n * Once emitted, particles remain stationary or move according to their velocity in world coordinates.\n * Ideal for environmental effects (e.g., smoke, explosions, ambient particles).\n */\n WORLD = 'WORLD',\n}\n\n/**\n * Defines the geometric shape from which particles are emitted.\n *\n * @enum {string}\n */\nexport const enum Shape {\n /**\n * Emit particles from a spherical volume or shell.\n * Configure with {@link Sphere} properties (radius, arc, radiusThickness).\n */\n SPHERE = 'SPHERE',\n\n /**\n * Emit particles from a conical volume or shell.\n * Configure with {@link Cone} properties (angle, radius, arc, radiusThickness).\n * Useful for directional effects like fire, smoke plumes, or spray effects.\n */\n CONE = 'CONE',\n\n /**\n * Emit particles from a box volume, shell, or edges.\n * Configure with {@link Box} properties (scale, emitFrom).\n * Useful for area-based effects like dust clouds or rain.\n */\n BOX = 'BOX',\n\n /**\n * Emit particles from a circular area or edge.\n * Configure with {@link Circle} properties (radius, arc, radiusThickness).\n * Useful for ground impacts, rings, or radial effects.\n */\n CIRCLE = 'CIRCLE',\n\n /**\n * Emit particles from a rectangular area.\n * Configure with {@link Rectangle} properties (scale, rotation).\n * Useful for planar effects like rain on a surface or screen effects.\n */\n RECTANGLE = 'RECTANGLE',\n}\n\n/**\n * Defines where on a shape particles are emitted from.\n * Not all shapes support all emit modes.\n *\n * @enum {string}\n */\nexport const enum EmitFrom {\n /**\n * Emit particles from random positions within the entire volume of the shape.\n * Supported by: SPHERE, CONE, BOX.\n */\n VOLUME = 'VOLUME',\n\n /**\n * Emit particles from the surface/shell of the shape.\n * Supported by: SPHERE, CONE, BOX.\n */\n SHELL = 'SHELL',\n\n /**\n * Emit particles from the edges of the shape.\n * Supported by: BOX.\n */\n EDGE = 'EDGE',\n}\n\n/**\n * Defines how texture sheet animation is timed.\n *\n * @enum {string}\n */\nexport const enum TimeMode {\n /**\n * Animation frames are based on the particle's lifetime percentage.\n * The animation completes once over the particle's lifetime.\n */\n LIFETIME = 'LIFETIME',\n\n /**\n * Animation frames are based on frames per second (FPS).\n * The animation runs at a fixed speed regardless of particle lifetime.\n */\n FPS = 'FPS',\n}\n\n/**\n * Defines the type of curve function used for animating values over a particle's lifetime.\n *\n * @enum {string}\n */\nexport const enum LifeTimeCurve {\n /**\n * Use custom Bezier curves with control points.\n * Provides maximum control over the animation curve shape.\n * See {@link BezierCurve} for configuration.\n */\n BEZIER = 'BEZIER',\n\n /**\n * Use predefined easing functions (e.g., easeInQuad, easeOutCubic).\n * Convenient for common animation patterns.\n * See {@link EasingCurve} and {@link CurveFunctionId} for available functions.\n */\n EASING = 'EASING',\n}\n\n/**\n * Defines when a sub-emitter is triggered relative to a particle's lifecycle.\n *\n * @enum {string}\n */\nexport const enum SubEmitterTrigger {\n /**\n * Trigger the sub-emitter when a particle is born (activated).\n * Useful for trail effects that start immediately with each particle.\n */\n BIRTH = 'BIRTH',\n\n /**\n * Trigger the sub-emitter when a particle dies (reaches end of lifetime).\n * Useful for cascading effects like explosions spawning smoke.\n */\n DEATH = 'DEATH',\n}\n\n/**\n * Defines the type of force field that affects particles.\n *\n * @enum {string}\n */\nexport const enum ForceFieldType {\n /**\n * Attract or repel particles toward/from a point in space.\n * Positive strength attracts, negative strength repels.\n * Configure with position, strength, range, and falloff.\n */\n POINT = 'POINT',\n\n /**\n * Apply a constant directional force to all particles (like wind).\n * Configure with direction and strength.\n */\n DIRECTIONAL = 'DIRECTIONAL',\n}\n\n/**\n * Defines the rendering technique used for particles.\n *\n * @enum {string}\n */\nexport const enum RendererType {\n /**\n * Render particles as point sprites using `THREE.Points`.\n * This is the default renderer, efficient for small to medium particle counts.\n * Note: point size is limited by `gl_PointSize` hardware caps (typically 64–256 px).\n */\n POINTS = 'POINTS',\n\n /**\n * Render particles as camera-facing quads using `THREE.InstancedBufferGeometry`.\n * Removes the `gl_PointSize` hardware limit, supports stretched billboards,\n * and enables batching multiple emitters into fewer draw calls.\n * Recommended for 10 000+ particles or when large on-screen particle sizes are needed.\n */\n INSTANCED = 'INSTANCED',\n\n /**\n * Render each particle as a ribbon trail connecting its current and previous positions.\n * Each particle stores a configurable number of position history samples, and the\n * renderer builds a camera-facing triangle-strip ribbon through those samples.\n *\n * Trail width and opacity can taper along the ribbon length for effects like\n * sword slashes, magic missiles, comet tails, and speed lines.\n *\n * Configure trail-specific properties via {@link TrailConfig} on the renderer.\n */\n TRAIL = 'TRAIL',\n\n /**\n * Render each particle as a 3D mesh using GPU instancing (`InstancedBufferGeometry`).\n * Instead of flat billboard sprites, particles are rendered as real 3D geometry\n * (e.g., cubes, spheres, tori, or any custom `THREE.BufferGeometry`).\n *\n * Key differences from billboard renderers:\n * - **3D rotation**: Particles rotate in all three axes (quaternion-based).\n * - **Normals**: Mesh geometry retains normals, enabling basic lighting.\n * - **Arbitrary geometry**: Any `THREE.BufferGeometry` can be used per particle.\n *\n * All existing modifiers (sizeOverLifetime, colorOverLifetime, noise, force fields,\n * sub-emitters) work with mesh particles.\n *\n * Configure mesh-specific properties via {@link MeshConfig} on the renderer.\n */\n MESH = 'MESH',\n}\n\n/**\n * Defines how force diminishes with distance from a POINT force field center.\n * Only applicable to {@link ForceFieldType.POINT} force fields.\n *\n * @enum {string}\n */\nexport const enum ForceFieldFalloff {\n /**\n * No falloff — force is constant within range.\n */\n NONE = 'NONE',\n\n /**\n * Force decreases linearly with distance: `1 - d/range`.\n */\n LINEAR = 'LINEAR',\n\n /**\n * Force decreases with the square of distance: `1 - (d/range)²`.\n * More physically realistic than linear fallback.\n */\n QUADRATIC = 'QUADRATIC',\n}\n\n/**\n * Defines the behavior when a particle crosses a collision plane.\n *\n * @enum {string}\n */\nexport const enum CollisionPlaneMode {\n /**\n * Kill the particle immediately when it crosses the plane.\n * The particle is deactivated and returned to the free list.\n * Ideal for boundaries like water surfaces where bubbles pop.\n */\n KILL = 'KILL',\n\n /**\n * Clamp the particle's position to the plane surface.\n * The velocity component along the plane normal is zeroed.\n * The particle stays alive and slides along the plane.\n */\n CLAMP = 'CLAMP',\n\n /**\n * Bounce the particle off the plane.\n * The velocity is reflected across the plane normal and dampened.\n * Use `dampen` to control energy loss on bounce.\n */\n BOUNCE = 'BOUNCE',\n}\n\n/**\n * Defines the simulation backend used for particle updates.\n *\n * @enum {string}\n */\nexport const enum SimulationBackend {\n /**\n * Automatically select the best backend based on the renderer type.\n * Uses GPU compute when a WebGPU-capable renderer is detected, otherwise falls back to CPU.\n */\n AUTO = 'AUTO',\n\n /**\n * Force CPU-based simulation (JavaScript update loop).\n * Always available regardless of renderer type.\n */\n CPU = 'CPU',\n\n /**\n * Force GPU compute shader simulation.\n * Requires a WebGPU-capable renderer (e.g. `THREE.WebGPURenderer`).\n * Falls back to CPU if the renderer does not support compute.\n */\n GPU = 'GPU',\n}\n","/**\n * Interleaved scalar buffer layout constants.\n *\n * All per-particle float attributes (except position and quat) are packed\n * into a single InterleavedBuffer to stay within the WebGPU vertex buffer\n * limit of 8.\n *\n * Buffer layout per particle (stride = 10 floats):\n * ```\n * [isActive, lifetime, startLifetime, startFrame, size, rotation, colorR, colorG, colorB, colorA]\n * ```\n */\n\n/** Number of float32 elements per particle in the interleaved scalar buffer. */\nexport const SCALAR_STRIDE = 10;\n\n/** Offset for the isActive flag (0 = inactive, 1 = active). */\nexport const S_IS_ACTIVE = 0;\n\n/** Offset for the current lifetime of the particle in milliseconds. */\nexport const S_LIFETIME = 1;\n\n/** Offset for the total lifetime of the particle in milliseconds. */\nexport const S_START_LIFETIME = 2;\n\n/** Offset for the texture sheet animation start frame index. */\nexport const S_START_FRAME = 3;\n\n/** Offset for the particle size. */\nexport const S_SIZE = 4;\n\n/** Offset for the particle rotation (radians). */\nexport const S_ROTATION = 5;\n\n/** Offset for the red color channel (0..1). */\nexport const S_COLOR_R = 6;\n\n/** Offset for the green color channel (0..1). */\nexport const S_COLOR_G = 7;\n\n/** Offset for the blue color channel (0..1). */\nexport const S_COLOR_B = 8;\n\n/** Offset for the alpha (opacity) channel (0..1). */\nexport const S_COLOR_A = 9;\n\n// ─── Shared rendering constants ─────────────────────────────────────────────\n\n/** Scale factor converting particle size to pixel-equivalent point size. */\nexport const POINT_SIZE_SCALE = 100.0;\n\n/** Minimum alpha below which fragments are discarded. */\nexport const ALPHA_DISCARD_THRESHOLD = 0.001;\n","import * as THREE from 'three';\n\nimport { createBezierCurveFunction } from './three-particles-bezier.js';\nimport { EmitFrom, LifeTimeCurve } from './three-particles-enums.js';\nimport {\n Constant,\n LifetimeCurve,\n Point3D,\n RandomBetweenTwoConstants,\n} from './types.js';\n\n/**\n * Calculates random position and velocity for particles emitted from a sphere.\n *\n * Supports emission from the entire volume or just the shell of the sphere.\n * Uses spherical coordinates for uniform distribution across the surface.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Sphere configuration\n * @param params.radius - Radius of the sphere\n * @param params.radiusThickness - Controls emission from volume (1.0) vs shell (0.0)\n * @param params.arc - Arc angle in degrees (360 = full sphere, 180 = hemisphere)\n *\n * @remarks\n * - `radiusThickness = 1.0`: Emit from entire volume\n * - `radiusThickness = 0.0`: Emit only from surface shell\n * - Particles are emitted radially outward from the center\n *\n * @see {@link Sphere} - Configuration type for sphere shape\n */\nexport const calculateRandomPositionAndVelocityOnSphere = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n {\n radius,\n radiusThickness,\n arc,\n }: { radius: number; radiusThickness: number; arc: number }\n) => {\n const u = Math.random() * (arc / 360);\n const v = Math.random();\n const randomizedDistanceRatio = Math.random();\n const theta = 2 * Math.PI * u;\n const phi = Math.acos(2 * v - 1);\n const sinPhi = Math.sin(phi);\n\n const xDirection = sinPhi * Math.cos(theta);\n const yDirection = sinPhi * Math.sin(theta);\n const zDirection = Math.cos(phi);\n const normalizedThickness = 1 - radiusThickness;\n\n position.x =\n radius * normalizedThickness * xDirection +\n radius * radiusThickness * randomizedDistanceRatio * xDirection;\n position.y =\n radius * normalizedThickness * yDirection +\n radius * radiusThickness * randomizedDistanceRatio * yDirection;\n position.z =\n radius * normalizedThickness * zDirection +\n radius * radiusThickness * randomizedDistanceRatio * zDirection;\n\n position.applyQuaternion(quaternion);\n\n const speedMultiplierByPosition = 1 / position.length();\n velocity.set(\n position.x * speedMultiplierByPosition * speed,\n position.y * speedMultiplierByPosition * speed,\n position.z * speedMultiplierByPosition * speed\n );\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a cone.\n *\n * Useful for directional particle effects like fire, smoke plumes, fountains,\n * or spray effects. The cone emits particles in a spreading pattern.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Cone configuration\n * @param params.radius - Base radius of the cone\n * @param params.radiusThickness - Controls emission from volume (1.0) vs shell (0.0)\n * @param params.arc - Arc angle in degrees (360 = full cone, 180 = half cone)\n * @param params.angle - Cone opening angle in degrees (default: 90)\n * Smaller values create tighter cones\n *\n * @remarks\n * - The cone emits from its base (circular area) outward\n * - Particles travel in a conical spread pattern\n * - `angle = 0`: Straight line (no spread)\n * - `angle = 90`: Wide cone\n * - Common for fire (10-30°), smoke (30-60°), explosions (60-90°)\n *\n * @see {@link Cone} - Configuration type for cone shape\n */\nexport const calculateRandomPositionAndVelocityOnCone = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n {\n radius,\n radiusThickness,\n arc,\n angle = 90,\n }: {\n radius: number;\n radiusThickness: number;\n arc: number;\n angle?: number;\n }\n) => {\n const theta = 2 * Math.PI * Math.random() * (arc / 360);\n const randomizedDistanceRatio = Math.random();\n\n const xDirection = Math.cos(theta);\n const yDirection = Math.sin(theta);\n const normalizedThickness = 1 - radiusThickness;\n\n position.x =\n radius * normalizedThickness * xDirection +\n radius * radiusThickness * randomizedDistanceRatio * xDirection;\n position.y =\n radius * normalizedThickness * yDirection +\n radius * radiusThickness * randomizedDistanceRatio * yDirection;\n position.z = 0;\n\n position.applyQuaternion(quaternion);\n\n const positionLength = position.length();\n const normalizedAngle = Math.abs(\n (positionLength / radius) * THREE.MathUtils.degToRad(angle)\n );\n const sinNormalizedAngle = Math.sin(normalizedAngle);\n\n const speedMultiplierByPosition = 1 / positionLength;\n velocity.set(\n position.x * sinNormalizedAngle * speedMultiplierByPosition * speed,\n position.y * sinNormalizedAngle * speedMultiplierByPosition * speed,\n Math.cos(normalizedAngle) * speed\n );\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a box.\n *\n * Supports three emission modes: volume, shell (surface), and edges.\n * Useful for area-based effects like dust clouds, rain, or geometric patterns.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Box configuration\n * @param params.scale - Size of the box on each axis (width, height, depth)\n * @param params.emitFrom - Emission mode:\n * - `VOLUME`: Random positions throughout the entire box volume\n * - `SHELL`: Random positions on the 6 faces (surface)\n * - `EDGE`: Random positions along the 12 edges\n *\n * @remarks\n * - All particles emit with velocity along the +Z axis (forward)\n * - Box is centered at the origin before rotation\n * - VOLUME mode: Best for rain, snow, or volumetric clouds\n * - SHELL mode: Best for hollow effects or surface particles\n * - EDGE mode: Best for wireframe effects or particle outlines\n *\n * @see {@link Box} - Configuration type for box shape\n * @see {@link EmitFrom} - Emission mode enum\n */\nexport const calculateRandomPositionAndVelocityOnBox = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n { scale, emitFrom }: { scale: Point3D; emitFrom: EmitFrom }\n) => {\n const _scale = scale as Required<Point3D>;\n switch (emitFrom) {\n case EmitFrom.VOLUME:\n position.x = Math.random() * _scale.x - _scale.x / 2;\n position.y = Math.random() * _scale.y - _scale.y / 2;\n position.z = Math.random() * _scale.z - _scale.z / 2;\n break;\n\n case EmitFrom.SHELL:\n const side = Math.floor(Math.random() * 6);\n const perpendicularAxis = side % 3;\n const shellResult = [];\n shellResult[perpendicularAxis] = side > 2 ? 1 : 0;\n shellResult[(perpendicularAxis + 1) % 3] = Math.random();\n shellResult[(perpendicularAxis + 2) % 3] = Math.random();\n position.x = shellResult[0] * _scale.x - _scale.x / 2;\n position.y = shellResult[1] * _scale.y - _scale.y / 2;\n position.z = shellResult[2] * _scale.z - _scale.z / 2;\n break;\n\n case EmitFrom.EDGE:\n const side2 = Math.floor(Math.random() * 6);\n const perpendicularAxis2 = side2 % 3;\n const edge = Math.floor(Math.random() * 4);\n const edgeResult = [];\n edgeResult[perpendicularAxis2] = side2 > 2 ? 1 : 0;\n edgeResult[(perpendicularAxis2 + 1) % 3] =\n edge < 2 ? Math.random() : edge - 2;\n edgeResult[(perpendicularAxis2 + 2) % 3] =\n edge < 2 ? edge : Math.random();\n position.x = edgeResult[0] * _scale.x - _scale.x / 2;\n position.y = edgeResult[1] * _scale.y - _scale.y / 2;\n position.z = edgeResult[2] * _scale.z - _scale.z / 2;\n break;\n }\n\n position.applyQuaternion(quaternion);\n\n velocity.set(0, 0, speed);\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a circle.\n *\n * Emits particles from a circular area or ring. Useful for ground impacts,\n * radial effects, magic circles, or any circular planar emission.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Circle configuration\n * @param params.radius - Radius of the circle\n * @param params.radiusThickness - Controls emission from area (1.0) vs edge (0.0)\n * @param params.arc - Arc angle in degrees (360 = full circle, 180 = semicircle)\n *\n * @remarks\n * - Circle lies in the XY plane by default (Z = 0)\n * - Particles emit along the +Z axis (perpendicular to circle)\n * - `radiusThickness = 1.0`: Filled circle (disc)\n * - `radiusThickness = 0.0`: Ring (circle edge only)\n * - Good for ground impact effects, teleport circles, or radial bursts\n *\n * @see {@link Circle} - Configuration type for circle shape\n */\nexport const calculateRandomPositionAndVelocityOnCircle = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n {\n radius,\n radiusThickness,\n arc,\n }: { radius: number; radiusThickness: number; arc: number }\n) => {\n const theta = 2 * Math.PI * Math.random() * (arc / 360);\n const randomizedDistanceRatio = Math.random();\n\n const xDirection = Math.cos(theta);\n const yDirection = Math.sin(theta);\n const normalizedThickness = 1 - radiusThickness;\n\n position.x =\n radius * normalizedThickness * xDirection +\n radius * radiusThickness * randomizedDistanceRatio * xDirection;\n position.y =\n radius * normalizedThickness * yDirection +\n radius * radiusThickness * randomizedDistanceRatio * yDirection;\n position.z = 0;\n\n position.applyQuaternion(quaternion);\n\n const positionLength = position.length();\n const speedMultiplierByPosition = 1 / positionLength;\n velocity.set(\n position.x * speedMultiplierByPosition * speed,\n position.y * speedMultiplierByPosition * speed,\n 0\n );\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Calculates random position and velocity for particles emitted from a rectangle.\n *\n * Emits particles from a rectangular planar area. Useful for rain on a surface,\n * screen-space effects, or any planar emission pattern.\n *\n * @param position - Output vector for the particle's starting position\n * @param quaternion - Rotation to apply to the emission shape\n * @param velocity - Output vector for the particle's initial velocity\n * @param speed - Speed multiplier for the velocity\n * @param params - Rectangle configuration\n * @param params.rotation - Local rotation of the rectangle (degrees) before\n * applying quaternion\n * @param params.scale - Size of the rectangle (width and height)\n *\n * @remarks\n * - Rectangle lies in the XY plane by default\n * - Particles emit along the +Z axis (perpendicular to rectangle)\n * - The rotation parameter allows tilting the rectangle before the main\n * quaternion rotation is applied\n * - Good for rain effects, screen particles, or planar area emissions\n *\n * @see {@link Rectangle} - Configuration type for rectangle shape\n */\nexport const calculateRandomPositionAndVelocityOnRectangle = (\n position: THREE.Vector3,\n quaternion: THREE.Quaternion,\n velocity: THREE.Vector3,\n speed: number,\n { rotation, scale }: { rotation: Point3D; scale: Point3D }\n) => {\n const _scale = scale as Required<Point3D>;\n const _rotation = rotation as Required<Point3D>;\n\n const xOffset = Math.random() * _scale.x - _scale.x / 2;\n const yOffset = Math.random() * _scale.y - _scale.y / 2;\n const rotationX = THREE.MathUtils.degToRad(_rotation.x);\n const rotationY = THREE.MathUtils.degToRad(_rotation.y);\n position.x = xOffset * Math.cos(rotationY);\n position.y = yOffset * Math.cos(rotationX);\n position.z = xOffset * Math.sin(rotationY) - yOffset * Math.sin(rotationX);\n\n position.applyQuaternion(quaternion);\n\n velocity.set(0, 0, speed);\n velocity.applyQuaternion(quaternion);\n};\n\n/**\n * Creates a solid white 1x1 texture for mesh particles.\n * Unlike the circle texture used by point/billboard renderers, mesh particles\n * need a neutral texture so the geometry shape is visible.\n * @returns {THREE.CanvasTexture | null} The generated texture or null if context fails.\n */\nexport const createDefaultMeshTexture = (): THREE.CanvasTexture | null => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const context = canvas.getContext('2d');\n if (context) {\n context.fillStyle = 'white';\n context.fillRect(0, 0, 1, 1);\n const texture = new THREE.CanvasTexture(canvas);\n texture.needsUpdate = true;\n return texture;\n }\n return null;\n } catch {\n return null;\n }\n};\n\n/**\n * Creates a default white circle texture using CanvasTexture.\n * @returns {THREE.CanvasTexture | null} The generated texture or null if context fails.\n */\nexport const createDefaultParticleTexture = (): THREE.CanvasTexture | null => {\n try {\n const canvas = document.createElement('canvas');\n const size = 64;\n canvas.width = size;\n canvas.height = size;\n const context = canvas.getContext('2d');\n if (context) {\n const centerX = size / 2;\n const centerY = size / 2;\n const radius = size / 2 - 2; // Small padding\n\n context.beginPath();\n context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);\n context.fillStyle = 'white';\n context.fill();\n const texture = new THREE.CanvasTexture(canvas);\n texture.needsUpdate = true;\n return texture;\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n 'Could not get 2D context to generate default particle texture.'\n );\n return null;\n }\n } catch (error) {\n // Handle potential errors (e.g., document not available in non-browser env)\n // eslint-disable-next-line no-console\n console.warn('Error creating default particle texture:', error);\n return null;\n }\n};\n\nexport const isLifeTimeCurve = (\n value: Constant | RandomBetweenTwoConstants | LifetimeCurve\n): value is LifetimeCurve => {\n return typeof value !== 'number' && 'type' in value;\n};\n\nexport const getCurveFunctionFromConfig = (\n particleSystemId: number,\n lifetimeCurve: LifetimeCurve\n) => {\n if (lifetimeCurve.type === LifeTimeCurve.BEZIER) {\n return createBezierCurveFunction(\n particleSystemId,\n lifetimeCurve.bezierPoints\n ); // Bézier curve\n }\n\n if (lifetimeCurve.type === LifeTimeCurve.EASING) {\n return lifetimeCurve.curveFunction; // Easing curve\n }\n\n throw new Error(`Unsupported value type: ${lifetimeCurve}`);\n};\n\nexport const calculateValue = (\n particleSystemId: number,\n value: Constant | RandomBetweenTwoConstants | LifetimeCurve,\n time: number = 0\n): number => {\n if (typeof value === 'number') {\n return value; // Constant value\n }\n\n if ('min' in value && 'max' in value) {\n if (value.min === value.max) {\n return value.min ?? 0; // Constant value\n }\n return THREE.MathUtils.randFloat(value.min ?? 0, value.max ?? 1); // Random range\n }\n\n const lifetimeCurve = value as LifetimeCurve;\n return (\n getCurveFunctionFromConfig(particleSystemId, lifetimeCurve)(time) *\n (lifetimeCurve.scale ?? 1)\n );\n};\n","import * as THREE from 'three';\n\nimport {\n SCALAR_STRIDE,\n S_SIZE,\n S_ROTATION,\n S_COLOR_R,\n S_COLOR_G,\n S_COLOR_B,\n S_COLOR_A,\n} from './three-particles-constants.js';\nimport { calculateValue } from './three-particles-utils.js';\nimport {\n GeneralData,\n MappedAttributes,\n NormalizedParticleSystemConfig,\n} from './types.js';\n\nconst noiseInput = new THREE.Vector3(0, 0, 0);\nconst orbitalEuler = new THREE.Euler();\n\n/**\n * Applies all active modifiers to a single particle during the update cycle.\n *\n * This function handles the animation and modification of particle properties over its lifetime,\n * including velocity (linear and orbital), size, opacity, color, rotation, and noise-based effects.\n * It is called once per particle per frame by the {@link updateParticleSystems} function.\n *\n * @param params - Configuration object containing:\n * @param params.delta - Time elapsed since the last frame in seconds. Used for velocity and rotation calculations.\n * @param params.generalData - Internal particle system state and cached values.\n * @param params.normalizedConfig - The normalized particle system configuration with all modifiers.\n * @param params.attributes - Three.js buffer attributes for position, size, rotation, and color.\n * @param params.particleLifetimePercentage - Normalized lifetime of the particle (0.0 to 1.0).\n * - 0.0 = particle just born\n * - 1.0 = particle at end of life\n * @param params.particleIndex - Index of the particle in the buffer arrays.\n *\n * @remarks\n * The function modifies the following particle properties based on configuration:\n *\n * - **Linear Velocity**: Moves particles in a straight line (velocityOverLifetime.linear)\n * - **Orbital Velocity**: Rotates particles around their emission point (velocityOverLifetime.orbital)\n * - **Size Over Lifetime**: Scales particle size based on lifetime curve (sizeOverLifetime)\n * - **Opacity Over Lifetime**: Fades particles in/out based on lifetime curve (opacityOverLifetime)\n * - **Color Over Lifetime**: Animates RGB channels independently based on lifetime curves (colorOverLifetime)\n * - **Rotation Over Lifetime**: Rotates particles around their center (rotationOverLifetime)\n * - **Noise**: Adds organic, turbulent motion to position, rotation, and size (noise)\n *\n * Each modifier only runs if it's active in the configuration, optimizing performance for simple effects.\n *\n * @example\n * ```typescript\n * // This function is called internally by updateParticleSystems\n * // You typically don't need to call it directly\n *\n * // However, understanding its behavior helps configure particle systems:\n * const config = {\n * sizeOverLifetime: {\n * isActive: true,\n * lifetimeCurve: {\n * type: 'BEZIER',\n * bezierPoints: [\n * { x: 0, y: 0, percentage: 0 }, // Start at 0% size\n * { x: 0.5, y: 1, percentage: 0.5 }, // Grow to 100% at midlife\n * { x: 1, y: 0, percentage: 1 } // Shrink to 0% at end\n * ]\n * }\n * },\n * opacityOverLifetime: {\n * isActive: true,\n * lifetimeCurve: {\n * type: 'EASING',\n * curveFunction: 'easeOutQuad'\n * }\n * }\n * };\n * ```\n *\n * @see {@link updateParticleSystems} - Calls this function for each active particle\n * @see {@link VelocityOverLifetime} - Configuration for velocity modifiers\n * @see {@link NoiseConfig} - Configuration for noise-based effects\n */\nexport const applyModifiers = ({\n delta,\n generalData,\n normalizedConfig,\n attributes,\n scalarArray,\n particleLifetimePercentage,\n particleIndex,\n}: {\n delta: number;\n generalData: GeneralData;\n normalizedConfig: NormalizedParticleSystemConfig;\n attributes: MappedAttributes;\n scalarArray: Float32Array;\n particleLifetimePercentage: number;\n particleIndex: number;\n}) => {\n const {\n particleSystemId,\n startValues,\n lifetimeValues,\n linearVelocityData,\n orbitalVelocityData,\n noise,\n } = generalData;\n\n const positionIndex = particleIndex * 3;\n const positionArr = attributes.position.array;\n const base = particleIndex * SCALAR_STRIDE;\n\n if (linearVelocityData) {\n const { speed, valueModifiers } = linearVelocityData[particleIndex];\n\n const normalizedXSpeed = valueModifiers.x\n ? valueModifiers.x(particleLifetimePercentage)\n : speed.x;\n\n const normalizedYSpeed = valueModifiers.y\n ? valueModifiers.y(particleLifetimePercentage)\n : speed.y;\n\n const normalizedZSpeed = valueModifiers.z\n ? valueModifiers.z(particleLifetimePercentage)\n : speed.z;\n\n positionArr[positionIndex] += normalizedXSpeed * delta;\n positionArr[positionIndex + 1] += normalizedYSpeed * delta;\n positionArr[positionIndex + 2] += normalizedZSpeed * delta;\n\n attributes.position.needsUpdate = true;\n }\n\n if (orbitalVelocityData) {\n const { speed, positionOffset, valueModifiers } =\n orbitalVelocityData[particleIndex];\n\n positionArr[positionIndex] -= positionOffset.x;\n positionArr[positionIndex + 1] -= positionOffset.y;\n positionArr[positionIndex + 2] -= positionOffset.z;\n\n const normalizedXSpeed = valueModifiers.x\n ? valueModifiers.x(particleLifetimePercentage)\n : speed.x;\n\n const normalizedYSpeed = valueModifiers.y\n ? valueModifiers.y(particleLifetimePercentage)\n : speed.y;\n\n const normalizedZSpeed = valueModifiers.z\n ? valueModifiers.z(particleLifetimePercentage)\n : speed.z;\n\n orbitalEuler.set(\n normalizedXSpeed * delta,\n normalizedZSpeed * delta,\n normalizedYSpeed * delta\n );\n positionOffset.applyEuler(orbitalEuler);\n\n positionArr[positionIndex] += positionOffset.x;\n positionArr[positionIndex + 1] += positionOffset.y;\n positionArr[positionIndex + 2] += positionOffset.z;\n\n attributes.position.needsUpdate = true;\n }\n\n if (normalizedConfig.sizeOverLifetime.isActive) {\n const multiplier = calculateValue(\n particleSystemId,\n normalizedConfig.sizeOverLifetime.lifetimeCurve,\n particleLifetimePercentage\n );\n scalarArray[base + S_SIZE] =\n startValues.startSize[particleIndex] * multiplier;\n }\n\n if (normalizedConfig.opacityOverLifetime.isActive) {\n const multiplier = calculateValue(\n particleSystemId,\n normalizedConfig.opacityOverLifetime.lifetimeCurve,\n particleLifetimePercentage\n );\n scalarArray[base + S_COLOR_A] =\n startValues.startOpacity[particleIndex] * multiplier;\n }\n\n if (normalizedConfig.colorOverLifetime.isActive) {\n const rMultiplier = calculateValue(\n particleSystemId,\n normalizedConfig.colorOverLifetime.r,\n particleLifetimePercentage\n );\n const gMultiplier = calculateValue(\n particleSystemId,\n normalizedConfig.colorOverLifetime.g,\n particleLifetimePercentage\n );\n const bMultiplier = calculateValue(\n particleSystemId,\n normalizedConfig.colorOverLifetime.b,\n particleLifetimePercentage\n );\n\n scalarArray[base + S_COLOR_R] =\n startValues.startColorR[particleIndex] * rMultiplier;\n scalarArray[base + S_COLOR_G] =\n startValues.startColorG[particleIndex] * gMultiplier;\n scalarArray[base + S_COLOR_B] =\n startValues.startColorB[particleIndex] * bMultiplier;\n }\n\n if (lifetimeValues.rotationOverLifetime) {\n scalarArray[base + S_ROTATION] +=\n lifetimeValues.rotationOverLifetime[particleIndex] * delta * 0.02;\n }\n\n if (noise.isActive) {\n const {\n sampler,\n strength,\n noisePower,\n offsets,\n positionAmount,\n rotationAmount,\n sizeAmount,\n } = noise;\n let noiseOnPosition;\n\n const noisePosition =\n (particleLifetimePercentage + (offsets ? offsets[particleIndex] : 0)) *\n 10 *\n strength;\n\n noiseInput.set(noisePosition, 0, 0);\n noiseOnPosition = sampler!.get3(noiseInput);\n positionArr[positionIndex] += noiseOnPosition * noisePower * positionAmount;\n\n if (rotationAmount !== 0) {\n scalarArray[base + S_ROTATION] +=\n noiseOnPosition * noisePower * rotationAmount;\n }\n\n if (sizeAmount !== 0) {\n scalarArray[base + S_SIZE] += noiseOnPosition * noisePower * sizeAmount;\n }\n\n noiseInput.set(noisePosition, noisePosition, 0);\n noiseOnPosition = sampler!.get3(noiseInput);\n positionArr[positionIndex + 1] +=\n noiseOnPosition * noisePower * positionAmount;\n\n noiseInput.set(noisePosition, noisePosition, noisePosition);\n noiseOnPosition = sampler!.get3(noiseInput);\n positionArr[positionIndex + 2] +=\n noiseOnPosition * noisePower * positionAmount;\n\n attributes.position.needsUpdate = true;\n }\n\n // Sync packed quaternion vec4 from scalar rotation for mesh particles.\n // This runs after noise so the quaternion reflects the final rotation value.\n if (attributes.quat) {\n const rotZ = scalarArray[base + S_ROTATION];\n const halfZ = rotZ * 0.5;\n const qi = particleIndex * 4;\n attributes.quat.array[qi] = 0;\n attributes.quat.array[qi + 1] = 0;\n attributes.quat.array[qi + 2] = Math.sin(halfZ);\n attributes.quat.array[qi + 3] = Math.cos(halfZ);\n attributes.quat.needsUpdate = true;\n }\n};\n","import { SimulationBackend } from './three-particles-enums.js';\n\n/**\n * Checks whether the given renderer supports GPU compute dispatches.\n *\n * Uses duck-typing: a renderer is considered WebGPU-capable when it exposes\n * a `.compute()` method and a `.hasFeature()` method (both present on\n * `THREE.WebGPURenderer` but absent from `THREE.WebGLRenderer`).\n *\n * @param renderer - Any Three.js renderer instance.\n * @returns `true` when the renderer supports compute shaders.\n */\nexport function isComputeCapableRenderer(renderer: unknown): boolean {\n return (\n renderer !== null &&\n renderer !== undefined &&\n typeof renderer === 'object' &&\n 'compute' in renderer &&\n typeof (renderer as Record<string, unknown>).compute === 'function' &&\n 'hasFeature' in renderer &&\n typeof (renderer as Record<string, unknown>).hasFeature === 'function'\n );\n}\n\n/**\n * Resolves the effective simulation backend based on the user's preference\n * and the capabilities of the provided renderer.\n *\n * | Preference | WebGPURenderer | WebGLRenderer |\n * |------------|---------------|---------------|\n * | `AUTO` | `GPU` | `CPU` |\n * | `CPU` | `CPU` | `CPU` |\n * | `GPU` | `GPU` | `CPU` (fallback) |\n *\n * @param renderer - The Three.js renderer instance used for rendering.\n * @param preference - The user-specified simulation backend preference.\n * @returns The resolved {@link SimulationBackend} (`CPU` or `GPU`).\n */\nexport function resolveSimulationBackend(\n renderer: unknown,\n preference: SimulationBackend = SimulationBackend.AUTO\n): SimulationBackend.CPU | SimulationBackend.GPU {\n const gpuCapable = isComputeCapableRenderer(renderer);\n\n if (preference === SimulationBackend.CPU) {\n return SimulationBackend.CPU;\n }\n\n if (preference === SimulationBackend.GPU) {\n return gpuCapable ? SimulationBackend.GPU : SimulationBackend.CPU;\n }\n\n // AUTO: use GPU when available\n return gpuCapable ? SimulationBackend.GPU : SimulationBackend.CPU;\n}\n","const InstancedParticleFragmentShader = `\n uniform sampler2D map;\n uniform float elapsed;\n uniform float fps;\n uniform bool useFPSForFrameIndex;\n uniform vec2 tiles;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying vec2 vUv;\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n gl_FragColor = vColor;\n\n // Rotate UV around centre (matches Points renderer behaviour)\n vec2 center = vec2(0.5);\n vec2 centeredPoint = vUv - center;\n\n mat2 rotation = mat2(\n cos(vRotation), sin(vRotation),\n -sin(vRotation), cos(vRotation)\n );\n\n centeredPoint = rotation * centeredPoint;\n vec2 centeredMiddlePoint = centeredPoint + center;\n\n // Discard pixels outside the inscribed circle\n float dist = distance(centeredMiddlePoint, center);\n if (dist > 0.5) discard;\n\n float frameIndex = round(vStartFrame) + (\n useFPSForFrameIndex == true\n ? fps == 0.0\n ? 0.0\n : max((vLifetime / 1000.0) * fps, 0.0)\n : max(min(floor(min(vLifetime / vStartLifetime, 1.0) * (tiles.x * tiles.y)), tiles.x * tiles.y - 1.0), 0.0)\n );\n\n float spriteXIndex = floor(mod(frameIndex, tiles.x));\n float spriteYIndex = floor(mod(frameIndex / tiles.x, tiles.y));\n\n vec2 uvPoint = vec2(\n centeredMiddlePoint.x / tiles.x + spriteXIndex / tiles.x,\n centeredMiddlePoint.y / tiles.y + spriteYIndex / tiles.y\n );\n\n vec4 rotatedTexture = texture2D(map, uvPoint);\n\n gl_FragColor = gl_FragColor * rotatedTexture;\n\n if (discardBackgroundColor && abs(length(rotatedTexture.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n #include <logdepthbuf_fragment>\n #include <colorspace_fragment>\n }\n`;\n\nexport default InstancedParticleFragmentShader;\n","const InstancedParticleVertexShader = `\n attribute float instanceSize;\n attribute vec4 instanceColor;\n attribute float instanceLifetime;\n attribute float instanceStartLifetime;\n attribute float instanceRotation;\n attribute float instanceStartFrame;\n attribute vec3 instanceOffset;\n\n uniform float viewportHeight;\n\n varying vec2 vUv;\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n void main()\n {\n // Early-out for dead particles: skip all transforms and emit a degenerate\n // position that produces zero-area triangles.\n if (instanceColor.a <= 0.0) {\n gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n return;\n }\n\n vColor = instanceColor;\n vLifetime = instanceLifetime;\n vStartLifetime = instanceStartLifetime;\n vStartFrame = instanceStartFrame;\n vRotation = instanceRotation;\n\n vec4 mvPosition = modelViewMatrix * vec4(instanceOffset, 1.0);\n\n // Match the Points renderer pixel size: gl_PointSize = size * 100.0 / distance.\n // A view-space offset of d produces d * projectionMatrix[1][1] / w * (viewportHeight/2) pixels,\n // where w = -mvPosition.z for perspective. Solving for d so the result equals\n // the gl_PointSize pixel count:\n // d = size * 100.0 / distance\n // * (-mvPosition.z)\n // / (projectionMatrix[1][1] * viewportHeight * 0.5)\n // Since distance ≈ -mvPosition.z for view-aligned particles the two cancel out,\n // leaving a distance-independent expression. We keep them explicit so particles\n // off the viewing axis still scale correctly.\n float dist = length(mvPosition.xyz);\n float pointSizePx = instanceSize * 100.0 / dist;\n float perspectiveSize = pointSizePx * (-mvPosition.z)\n / (projectionMatrix[1][1] * viewportHeight * 0.5);\n\n // Billboard: offset quad vertices in view space (no rotation here;\n // rotation is applied to UVs in the fragment shader to keep behaviour\n // identical to the Points renderer).\n mvPosition.xy += position.xy * perspectiveSize;\n\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n // Pass UV for texture sampling (quad ranges from -0.5..0.5, map to 0..1).\n // Flip Y to match gl_PointCoord convention (Y runs top-to-bottom).\n vUv = vec2(position.x + 0.5, 0.5 - position.y);\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default InstancedParticleVertexShader;\n","const MeshParticleFragmentShader = `\n uniform sampler2D map;\n uniform float elapsed;\n uniform float fps;\n uniform bool useFPSForFrameIndex;\n uniform vec2 tiles;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying vec3 vNormal;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n gl_FragColor = vColor;\n\n // Use mesh UVs directly for texture sampling\n vec2 uvPoint = vUv;\n\n // Apply texture sheet animation if tiles > 1x1\n if (tiles.x > 1.0 || tiles.y > 1.0) {\n float frameIndex = round(vStartFrame) + (\n useFPSForFrameIndex == true\n ? fps == 0.0\n ? 0.0\n : max((vLifetime / 1000.0) * fps, 0.0)\n : max(min(floor(min(vLifetime / vStartLifetime, 1.0) * (tiles.x * tiles.y)), tiles.x * tiles.y - 1.0), 0.0)\n );\n\n float spriteXIndex = floor(mod(frameIndex, tiles.x));\n float spriteYIndex = floor(mod(frameIndex / tiles.x, tiles.y));\n\n uvPoint = vec2(\n vUv.x / tiles.x + spriteXIndex / tiles.x,\n vUv.y / tiles.y + spriteYIndex / tiles.y\n );\n }\n\n vec4 texColor = texture2D(map, uvPoint);\n gl_FragColor = gl_FragColor * texColor;\n\n if (discardBackgroundColor && abs(length(texColor.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n // Simple directional lighting from camera direction\n float lightIntensity = 0.5 + 0.5 * max(dot(vNormal, vec3(0.0, 0.0, 1.0)), 0.0);\n gl_FragColor.rgb *= lightIntensity;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n #include <logdepthbuf_fragment>\n #include <colorspace_fragment>\n }\n`;\n\nexport default MeshParticleFragmentShader;\n","const MeshParticleVertexShader = `\n attribute float instanceSize;\n attribute vec4 instanceColor;\n attribute float instanceLifetime;\n attribute float instanceStartLifetime;\n attribute float instanceRotation;\n attribute float instanceStartFrame;\n attribute vec3 instanceOffset;\n attribute vec4 instanceQuat;\n\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vStartFrame;\n varying float vRotation;\n varying vec3 vNormal;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n vec3 applyQuaternion(vec3 v, vec4 q) {\n vec3 t = 2.0 * cross(q.xyz, v);\n return v + q.w * t + cross(q.xyz, t);\n }\n\n void main()\n {\n // Early-out for dead particles: skip all expensive transforms and emit\n // a degenerate position that produces zero-area triangles.\n if (instanceColor.a <= 0.0) {\n gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n return;\n }\n\n vColor = instanceColor;\n vLifetime = instanceLifetime;\n vStartLifetime = instanceStartLifetime;\n vStartFrame = instanceStartFrame;\n vRotation = instanceRotation;\n\n // Apply quaternion rotation to the mesh vertex position\n vec3 rotatedPosition = applyQuaternion(position, instanceQuat);\n\n // Scale mesh by particle size\n vec3 scaledPosition = rotatedPosition * instanceSize;\n\n // Apply instance offset (particle world position)\n vec3 worldPos = scaledPosition + instanceOffset;\n\n vec4 mvPosition = modelViewMatrix * vec4(worldPos, 1.0);\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n // Transform normal by quaternion for lighting\n vNormal = normalize((modelViewMatrix * vec4(applyQuaternion(normal, instanceQuat), 0.0)).xyz);\n\n // Pass through UVs from the mesh geometry\n vUv = uv;\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default MeshParticleVertexShader;\n","const ParticleSystemFragmentShader = `\n uniform sampler2D map;\n uniform float elapsed;\n uniform float fps;\n uniform bool useFPSForFrameIndex;\n uniform vec2 tiles;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vRotation;\n varying float vStartFrame;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n gl_FragColor = vColor;\n float mid = 0.5;\n\n float frameIndex = round(vStartFrame) + (\n useFPSForFrameIndex == true\n ? fps == 0.0\n ? 0.0\n : max((vLifetime / 1000.0) * fps, 0.0)\n : max(min(floor(min(vLifetime / vStartLifetime, 1.0) * (tiles.x * tiles.y)), tiles.x * tiles.y - 1.0), 0.0)\n );\n \n float spriteXIndex = floor(mod(frameIndex, tiles.x));\n float spriteYIndex = floor(mod(frameIndex / tiles.x, tiles.y));\n\n vec2 frameUV = vec2(\n gl_PointCoord.x / tiles.x + spriteXIndex / tiles.x,\n gl_PointCoord.y / tiles.y + spriteYIndex / tiles.y);\n\n vec2 center = vec2(0.5, 0.5);\n vec2 centeredPoint = gl_PointCoord - center;\n\n mat2 rotation = mat2(\n cos(vRotation), sin(vRotation),\n -sin(vRotation), cos(vRotation)\n );\n\n centeredPoint = rotation * centeredPoint;\n vec2 centeredMiddlePoint = vec2(\n centeredPoint.x + center.x,\n centeredPoint.y + center.y\n );\n\n float dist = distance(centeredMiddlePoint, center);\n if (dist > 0.5) discard;\n\n vec2 uvPoint = vec2(\n centeredMiddlePoint.x / tiles.x + spriteXIndex / tiles.x,\n centeredMiddlePoint.y / tiles.y + spriteYIndex / tiles.y\n );\n\n vec4 rotatedTexture = texture2D(map, uvPoint);\n\n gl_FragColor = gl_FragColor * rotatedTexture;\n\n if (discardBackgroundColor && abs(length(rotatedTexture.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n #include <logdepthbuf_fragment>\n #include <colorspace_fragment>\n }\n`;\n\nexport default ParticleSystemFragmentShader;\n","const ParticleSystemVertexShader = `\n attribute float size;\n attribute vec4 color;\n attribute float lifetime;\n attribute float startLifetime;\n attribute float rotation;\n attribute float startFrame;\n\n varying mat4 vPosition;\n varying vec4 vColor;\n varying float vLifetime;\n varying float vStartLifetime;\n varying float vRotation;\n varying float vStartFrame;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n void main()\n {\n vColor = color;\n vLifetime = lifetime;\n vStartLifetime = startLifetime;\n vRotation = rotation;\n vStartFrame = startFrame;\n\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n gl_PointSize = size * (100.0 / length(mvPosition.xyz));\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default ParticleSystemVertexShader;\n","const TrailFragmentShader = `\n uniform sampler2D map;\n uniform bool useMap;\n uniform bool discardBackgroundColor;\n uniform vec3 backgroundColor;\n uniform float backgroundColorTolerance;\n uniform bool softParticlesEnabled;\n uniform float softParticlesIntensity;\n uniform sampler2D sceneDepthTexture;\n uniform vec2 cameraNearFar;\n\n varying float vAlpha;\n varying vec4 vColor;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_fragment>\n\n float linearizeDepth(float depthSample, float near, float far) {\n float z_ndc = 2.0 * depthSample - 1.0;\n return 2.0 * near * far / (far + near - z_ndc * (far - near));\n }\n\n void main()\n {\n // Soft edge: always fade near ribbon edges\n float edgeDist = 1.0 - abs(vUv.x * 2.0 - 1.0);\n float softEdge = smoothstep(0.0, 0.4, edgeDist);\n\n gl_FragColor = vColor;\n\n if (useMap) {\n // Use texture luminance as brightness modulation on top of soft edge\n vec4 texColor = texture2D(map, vUv);\n float texBrightness = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));\n gl_FragColor.rgb *= (0.5 + texBrightness * 0.5);\n gl_FragColor.a *= texColor.a;\n }\n\n gl_FragColor.a *= vAlpha * softEdge;\n\n if (gl_FragColor.a < 0.001) discard;\n\n if (softParticlesEnabled) {\n vec2 screenUV = gl_FragCoord.xy / vec2(textureSize(sceneDepthTexture, 0));\n float sceneDepthSample = texture2D(sceneDepthTexture, screenUV).r;\n float sceneDepthLinear = linearizeDepth(sceneDepthSample, cameraNearFar.x, cameraNearFar.y);\n float depthDiff = sceneDepthLinear - vViewZ;\n float softFade = smoothstep(0.0, softParticlesIntensity, depthDiff);\n gl_FragColor.a *= softFade;\n if (gl_FragColor.a < 0.001) discard;\n }\n\n if (discardBackgroundColor && abs(length(gl_FragColor.rgb - backgroundColor.rgb)) < backgroundColorTolerance) discard;\n\n #include <logdepthbuf_fragment>\n #include <colorspace_fragment>\n }\n`;\n\nexport default TrailFragmentShader;\n","const TrailVertexShader = `\n attribute float trailAlpha;\n attribute vec4 trailColor;\n attribute float trailOffset;\n attribute float trailHalfWidth;\n attribute vec3 trailNext;\n attribute vec2 trailUV;\n\n varying float vAlpha;\n varying vec4 vColor;\n varying vec2 vUv;\n varying float vViewZ;\n\n #include <common>\n #include <logdepthbuf_pars_vertex>\n\n void main()\n {\n vAlpha = trailAlpha;\n vColor = trailColor;\n vUv = trailUV;\n\n // Compute tangent from current position to next sample\n vec3 tangent = trailNext - position;\n float tangentLen = length(tangent);\n if (tangentLen < 0.0001) {\n tangent = vec3(0.0, 1.0, 0.0);\n } else {\n tangent = tangent / tangentLen;\n }\n\n // Billboard: perpendicular = cross(tangent, viewDirection)\n vec3 worldPos = (modelMatrix * vec4(position, 1.0)).xyz;\n vec3 viewDir = normalize(cameraPosition - worldPos);\n vec3 perp = cross(tangent, viewDir);\n float perpLen = length(perp);\n\n // When tangent is nearly parallel to view direction, the cross product\n // collapses and the ribbon becomes edge-on (invisible). Build a stable\n // fallback perpendicular from the camera's right axis — this keeps the\n // ribbon in screen-space and prevents it from flipping into an arbitrary\n // plane when viewed edge-on.\n vec3 camRight = vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);\n vec3 fallbackPerp = normalize(camRight - tangent * dot(camRight, tangent));\n\n if (perpLen < 0.0001) {\n perp = fallbackPerp;\n } else {\n perp = perp / perpLen;\n // Smoothly blend toward the fallback when the billboard perp weakens.\n // The wide range (0..0.7) ensures a gradual transition so the ribbon\n // does not snap abruptly when rotating toward edge-on.\n float blendFactor = smoothstep(0.0, 0.7, perpLen);\n perp = normalize(mix(fallbackPerp, perp, blendFactor));\n }\n\n vec3 offsetPos = position + perp * trailOffset * trailHalfWidth;\n vec4 mvPosition = modelViewMatrix * vec4(offsetPos, 1.0);\n vViewZ = -mvPosition.z;\n gl_Position = projectionMatrix * mvPosition;\n\n #include <logdepthbuf_vertex>\n }\n`;\n\nexport default TrailVertexShader;\n","import * as THREE from 'three';\n\nimport { S_LIFETIME, S_START_LIFETIME } from './three-particles-constants.js';\nimport { CollisionPlaneMode } from './three-particles-enums.js';\nimport { NormalizedCollisionPlaneConfig } from './types.js';\n\n// Pre-allocated vectors to avoid GC pressure in the hot loop\nconst _planeToParticle = new THREE.Vector3();\nconst _normalComponent = new THREE.Vector3();\n\n/**\n * Applies all active collision planes to a single particle.\n *\n * Collision planes define infinite surfaces in 3D space. When a particle's\n * signed distance to the plane becomes negative (i.e., it crosses from the\n * front side to the back side), the configured response mode is triggered:\n *\n * - **KILL**: Deactivate the particle immediately.\n * - **CLAMP**: Project the particle back onto the plane surface and zero the\n * velocity component along the plane normal.\n * - **BOUNCE**: Reflect the velocity across the plane normal, apply damping,\n * project the position back onto the plane, and optionally reduce lifetime.\n *\n * Called once per active particle per frame in the update loop,\n * after position update and before modifiers.\n *\n * @returns `true` if the particle was killed (caller should skip remaining processing).\n */\nexport const applyCollisionPlanes = ({\n collisionPlanes,\n velocity,\n positionArr,\n positionIndex,\n scalarArr,\n scalarBase,\n deactivateParticle,\n particleIndex,\n}: {\n collisionPlanes: ReadonlyArray<NormalizedCollisionPlaneConfig>;\n velocity: THREE.Vector3;\n positionArr: THREE.TypedArray;\n positionIndex: number;\n scalarArr: Float32Array;\n scalarBase: number;\n deactivateParticle: (particleIndex: number) => void;\n particleIndex: number;\n}): boolean => {\n for (let i = 0; i < collisionPlanes.length; i++) {\n const plane = collisionPlanes[i];\n if (!plane.isActive) continue;\n\n const normal = plane.normal;\n const planePos = plane.position;\n\n // Vector from plane position to particle position\n _planeToParticle.set(\n (positionArr[positionIndex] as number) - planePos.x,\n (positionArr[positionIndex + 1] as number) - planePos.y,\n (positionArr[positionIndex + 2] as number) - planePos.z\n );\n\n // Signed distance: positive = front side, negative = crossed the plane\n const signedDistance = _planeToParticle.dot(normal);\n\n if (signedDistance >= 0) continue;\n\n // Particle has crossed the plane — apply response\n switch (plane.mode) {\n case CollisionPlaneMode.KILL:\n deactivateParticle(particleIndex);\n return true;\n\n case CollisionPlaneMode.CLAMP:\n // Project position back onto the plane surface\n positionArr[positionIndex] =\n (positionArr[positionIndex] as number) - signedDistance * normal.x;\n positionArr[positionIndex + 1] =\n (positionArr[positionIndex + 1] as number) -\n signedDistance * normal.y;\n positionArr[positionIndex + 2] =\n (positionArr[positionIndex + 2] as number) -\n signedDistance * normal.z;\n\n // Remove velocity component along the plane normal\n const velDotNormal =\n velocity.x * normal.x + velocity.y * normal.y + velocity.z * normal.z;\n if (velDotNormal < 0) {\n velocity.x -= velDotNormal * normal.x;\n velocity.y -= velDotNormal * normal.y;\n velocity.z -= velDotNormal * normal.z;\n }\n break;\n\n case CollisionPlaneMode.BOUNCE: {\n // Project position back onto the plane surface\n positionArr[positionIndex] =\n (positionArr[positionIndex] as number) - signedDistance * normal.x;\n positionArr[positionIndex + 1] =\n (positionArr[positionIndex + 1] as number) -\n signedDistance * normal.y;\n positionArr[positionIndex + 2] =\n (positionArr[positionIndex + 2] as number) -\n signedDistance * normal.z;\n\n // Reflect velocity: v' = v - 2 * dot(v, n) * n\n const vDotN =\n velocity.x * normal.x + velocity.y * normal.y + velocity.z * normal.z;\n _normalComponent.set(\n 2 * vDotN * normal.x,\n 2 * vDotN * normal.y,\n 2 * vDotN * normal.z\n );\n velocity.x = (velocity.x - _normalComponent.x) * plane.dampen;\n velocity.y = (velocity.y - _normalComponent.y) * plane.dampen;\n velocity.z = (velocity.z - _normalComponent.z) * plane.dampen;\n\n // Apply lifetime loss\n if (plane.lifetimeLoss > 0) {\n const startLifetime = scalarArr[scalarBase + S_START_LIFETIME];\n scalarArr[scalarBase + S_LIFETIME] +=\n plane.lifetimeLoss * startLifetime;\n }\n break;\n }\n }\n }\n\n return false;\n};\n","import * as THREE from 'three';\n\nimport { ForceFieldFalloff, ForceFieldType } from './three-particles-enums.js';\nimport { calculateValue } from './three-particles-utils.js';\nimport { NormalizedForceFieldConfig } from './types.js';\n\n// Pre-allocated vector to avoid GC pressure in the hot loop\nconst _forceDirection = new THREE.Vector3();\n\nconst applyPointForce = (\n field: NormalizedForceFieldConfig,\n strength: number,\n velocity: THREE.Vector3,\n positionArr: THREE.TypedArray,\n positionIndex: number,\n delta: number\n): void => {\n _forceDirection.set(\n field.position.x - (positionArr[positionIndex] as number),\n field.position.y - (positionArr[positionIndex + 1] as number),\n field.position.z - (positionArr[positionIndex + 2] as number)\n );\n\n const distance = _forceDirection.length();\n\n if (distance < 0.0001) return;\n if (field.range !== Infinity && distance > field.range) return;\n\n _forceDirection.divideScalar(distance);\n\n let falloffMultiplier = 1.0;\n if (field.range !== Infinity) {\n const normalizedDistance = distance / field.range;\n switch (field.falloff) {\n case ForceFieldFalloff.LINEAR:\n falloffMultiplier = 1.0 - normalizedDistance;\n break;\n case ForceFieldFalloff.QUADRATIC:\n falloffMultiplier = 1.0 - normalizedDistance * normalizedDistance;\n break;\n case ForceFieldFalloff.NONE:\n falloffMultiplier = 1.0;\n break;\n }\n }\n\n const force = strength * falloffMultiplier * delta;\n velocity.x += _forceDirection.x * force;\n velocity.y += _forceDirection.y * force;\n velocity.z += _forceDirection.z * force;\n};\n\nconst applyDirectionalForce = (\n field: NormalizedForceFieldConfig,\n strength: number,\n velocity: THREE.Vector3,\n delta: number\n): void => {\n const force = strength * delta;\n velocity.x += field.direction.x * force;\n velocity.y += field.direction.y * force;\n velocity.z += field.direction.z * force;\n};\n\n/**\n * Applies all active force fields to a single particle's velocity.\n *\n * Force fields modify particle velocity (not position directly), matching\n * the gravity application pattern. This preserves momentum and integrates\n * naturally with the existing velocity system.\n *\n * Called once per active particle per frame in the update loop,\n * after gravity and before position update.\n *\n * @param params - Configuration object containing:\n * @param params.particleSystemId - Unique ID for the particle system (used by calculateValue).\n * @param params.forceFields - Array of normalized force field configurations.\n * @param params.velocity - The particle's current velocity vector (modified in place).\n * @param params.positionArr - The position buffer array for all particles.\n * @param params.positionIndex - The index into positionArr for this particle's X coordinate.\n * @param params.delta - Time elapsed since last frame in seconds.\n * @param params.systemLifetimePercentage - Normalized system lifetime (0.0 to 1.0) for curve evaluation.\n *\n * @example\n * ```typescript\n * // This function is called internally by updateParticleSystems\n * // You typically don't need to call it directly\n *\n * // Configure force fields in your particle system:\n * const config = {\n * forceFields: [\n * {\n * type: ForceFieldType.POINT,\n * position: new THREE.Vector3(0, 5, 0),\n * strength: 3.0,\n * range: 10,\n * falloff: ForceFieldFalloff.LINEAR,\n * },\n * ],\n * };\n * ```\n *\n * @see {@link ForceFieldConfig} - User-facing configuration type\n * @see {@link ForceFieldType} - Available force field types\n * @see {@link ForceFieldFalloff} - Available falloff modes\n */\nexport const applyForceFields = ({\n particleSystemId,\n forceFields,\n velocity,\n positionArr,\n positionIndex,\n delta,\n systemLifetimePercentage,\n}: {\n particleSystemId: number;\n forceFields: Array<NormalizedForceFieldConfig>;\n velocity: THREE.Vector3;\n positionArr: THREE.TypedArray;\n positionIndex: number;\n delta: number;\n systemLifetimePercentage: number;\n}): void => {\n for (let i = 0; i < forceFields.length; i++) {\n const field = forceFields[i];\n if (!field.isActive) continue;\n\n const strength = calculateValue(\n particleSystemId,\n field.strength,\n systemLifetimePercentage\n );\n\n if (strength === 0) continue;\n\n if (field.type === ForceFieldType.POINT) {\n applyPointForce(\n field,\n strength,\n velocity,\n positionArr,\n positionIndex,\n delta\n );\n } else if (field.type === ForceFieldType.DIRECTIONAL) {\n applyDirectionalForce(field, strength, velocity, delta);\n }\n }\n};\n","import { ObjectUtils } from '@newkrok/three-utils';\nimport * as THREE from 'three';\nimport { FBM } from 'three-noise/build/three-noise.module.js';\nimport { rgbSRGBToLinear, sRGBToLinear } from './color-utils.js';\nimport InstancedParticleFragmentShader from './shaders/instanced-particle-fragment-shader.glsl.js';\nimport InstancedParticleVertexShader from './shaders/instanced-particle-vertex-shader.glsl.js';\nimport MeshParticleFragmentShader from './shaders/mesh-particle-fragment-shader.glsl.js';\nimport MeshParticleVertexShader from './shaders/mesh-particle-vertex-shader.glsl.js';\nimport ParticleSystemFragmentShader from './shaders/particle-system-fragment-shader.glsl.js';\nimport ParticleSystemVertexShader from './shaders/particle-system-vertex-shader.glsl.js';\nimport TrailFragmentShader from './shaders/trail-fragment-shader.glsl.js';\nimport TrailVertexShader from './shaders/trail-vertex-shader.glsl.js';\nimport { removeBezierCurveFunction } from './three-particles-bezier.js';\nimport { applyCollisionPlanes } from './three-particles-collision.js';\nimport {\n SCALAR_STRIDE,\n S_IS_ACTIVE,\n S_LIFETIME,\n S_START_LIFETIME,\n S_START_FRAME,\n S_SIZE,\n S_ROTATION,\n S_COLOR_R,\n S_COLOR_G,\n S_COLOR_B,\n S_COLOR_A,\n} from './three-particles-constants.js';\nimport {\n CollisionPlaneMode,\n EmitFrom,\n ForceFieldFalloff,\n ForceFieldType,\n LifeTimeCurve,\n RendererType,\n Shape,\n SimulationBackend,\n SimulationSpace,\n SubEmitterTrigger,\n TimeMode,\n} from './three-particles-enums';\nimport { applyForceFields } from './three-particles-forces.js';\nimport { applyModifiers } from './three-particles-modifiers.js';\nimport { isComputeCapableRenderer } from './three-particles-renderer-detect.js';\nimport {\n calculateRandomPositionAndVelocityOnBox,\n calculateRandomPositionAndVelocityOnCircle,\n calculateRandomPositionAndVelocityOnCone,\n calculateRandomPositionAndVelocityOnRectangle,\n calculateRandomPositionAndVelocityOnSphere,\n calculateValue,\n getCurveFunctionFromConfig,\n isLifeTimeCurve,\n createDefaultMeshTexture,\n createDefaultParticleTexture,\n} from './three-particles-utils.js';\n\nimport {\n CollisionPlaneConfig,\n Constant,\n CurveFunction,\n CycleData,\n ForceFieldConfig,\n GeneralData,\n LifetimeCurve,\n MappedAttributes,\n NormalizedCollisionPlaneConfig,\n NormalizedForceFieldConfig,\n NormalizedParticleSystemConfig,\n ParticleSystem,\n ParticleSystemConfig,\n ParticleSystemInstance,\n Point3D,\n RandomBetweenTwoConstants,\n ShapeConfig,\n SubEmitterConfig,\n MeshConfig,\n TrailConfig,\n} from './types.js';\n\nexport * from './types.js';\n\nconst normalizeTrailCurve = (\n curve: LifetimeCurve | undefined,\n defaultCurve: LifetimeCurve\n): LifetimeCurve => {\n if (!curve) return defaultCurve;\n const raw = curve as Record<string, unknown>;\n if (!raw.type && Array.isArray(raw.bezierPoints)) {\n return { type: LifeTimeCurve.BEZIER, ...raw } as LifetimeCurve;\n }\n return curve;\n};\n\n// Re-export so downstream consumers can access stride constants from the main module.\nexport {\n SCALAR_STRIDE,\n S_IS_ACTIVE,\n S_LIFETIME,\n S_START_LIFETIME,\n S_START_FRAME,\n S_SIZE,\n S_ROTATION,\n S_COLOR_R,\n S_COLOR_G,\n S_COLOR_B,\n S_COLOR_A,\n} from './three-particles-constants.js';\n\nlet _particleSystemId = 0;\nlet createdParticleSystems: Array<ParticleSystemInstance> = [];\n\n// ─── GPU Compute Uniform Helpers ────────────────────────────────────────────\n// Centralise the `as unknown as` casts for setting TSL uniform values.\n// The TSL uniform nodes expose `.value` at runtime but their TypeScript\n// type (`ShaderNodeObject<Node>`) does not declare it.\n\n/** Sets a TSL float uniform's value. */\nconst setUniformFloat = (u: unknown, v: number): void => {\n (u as { value: number }).value = v;\n};\n\n/** Sets a TSL vec3 uniform's value. */\nconst setUniformVec3 = (u: unknown, x: number, y: number, z: number): void => {\n (\n u as { value: { set: (x: number, y: number, z: number) => void } }\n ).value.set(x, y, z);\n};\n\n// ─── WebGPU TSL Material Support (opt-in via registerTSLMaterialFactory) ─────\n\ntype TSLMaterialFactory = {\n createTSLParticleMaterial: (\n rendererType: RendererType,\n sharedUniforms: Record<string, { value: unknown }>,\n rendererConfig: {\n transparent: boolean;\n blending: THREE.Blending;\n depthTest: boolean;\n depthWrite: boolean;\n },\n gpuCompute?: boolean\n ) => THREE.Material;\n createTSLTrailMaterial: (\n trailUniforms: Record<string, { value: unknown }>,\n rendererConfig: {\n transparent: boolean;\n blending: THREE.Blending;\n depthTest: boolean;\n depthWrite: boolean;\n }\n ) => THREE.Material;\n // GPU compute functions — use opaque types to avoid pulling WebGPU/TSL\n // types into the DTS output.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createComputePipeline?: (...args: any[]) => any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n writeParticleToModifierBuffers?: (...args: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deactivateParticleInModifierBuffers?: (...args: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n flushEmitQueue?: (...args: any[]) => number;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n registerCurveDataLength?: (...args: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n encodeForceFieldsForGPU?: (...args: any[]) => Float32Array;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n encodeCollisionPlanesForGPU?: (...args: any[]) => Float32Array;\n};\n\nlet _tslMaterialFactory: TSLMaterialFactory | null = null;\n\n/**\n * Registers the TSL (Three Shading Language) material factory for WebGPU support.\n *\n * Call this **once** before creating any particle systems that use WebGPU rendering.\n * The factory functions are imported from the `@newkrok/three-particles/webgpu` sub-module.\n *\n * When registered, all particle systems will use TSL-based `NodeMaterial` (compiles to WGSL)\n * instead of GLSL `ShaderMaterial`. If the factory also includes the GPU compute functions\n * (`createComputePipeline`, `writeParticleToModifierBuffers`, etc.), particle systems with\n * `simulationBackend: 'AUTO'` or `'GPU'` will run physics and modifiers on the GPU.\n *\n * @param factory - Object containing TSL material creators and optional GPU compute helpers.\n *\n * @example\n * ```typescript\n * import { registerTSLMaterialFactory } from '@newkrok/three-particles';\n * import {\n * createTSLParticleMaterial,\n * createTSLTrailMaterial,\n * createComputePipeline,\n * writeParticleToModifierBuffers,\n * deactivateParticleInModifierBuffers,\n * flushEmitQueue,\n * registerCurveDataLength,\n * encodeForceFieldsForGPU,\n * } from '@newkrok/three-particles/webgpu';\n *\n * registerTSLMaterialFactory({\n * createTSLParticleMaterial,\n * createTSLTrailMaterial,\n * createComputePipeline,\n * writeParticleToModifierBuffers,\n * deactivateParticleInModifierBuffers,\n * flushEmitQueue,\n * registerCurveDataLength,\n * encodeForceFieldsForGPU,\n * });\n * ```\n */\nexport const registerTSLMaterialFactory = (\n factory: TSLMaterialFactory\n): void => {\n _tslMaterialFactory = factory;\n};\n\n// Pre-allocated objects for updateParticleSystemInstance to avoid GC pressure\nconst _subEmitterPosition = new THREE.Vector3();\nconst _subLocalPosition = new THREE.Vector3();\nconst _shadowOrbitalEuler = new THREE.Euler(0, 0, 0, 'XYZ');\nconst _lastWorldPositionSnapshot = new THREE.Vector3();\n// Force field local-space conversion helpers (reused across frames)\nconst _localForceFieldPos = new THREE.Vector3();\nconst _localForceFieldDir = new THREE.Vector3();\nconst _inverseQuat = new THREE.Quaternion();\n\n/**\n * Compares two typed-array slices for value equality.\n * Used to gate GPU buffer `needsUpdate` flagging so we only re-upload when\n * the encoded data actually changed. See the force-field / collision-plane\n * upload block in `updateParticleSystemInstance` for the reasoning.\n */\nconst arraySlicesEqual = (\n a: Float32Array,\n aOffset: number,\n b: Float32Array,\n bOffset: number,\n length: number\n): boolean => {\n for (let i = 0; i < length; i++) {\n if (a[aOffset + i] !== b[bOffset + i]) return false;\n }\n return true;\n};\nlet _localForceFields: Array<NormalizedForceFieldConfig> = [];\n// Collision plane local-space conversion helpers (reused across frames)\nconst _localCollisionPlanePos = new THREE.Vector3();\nconst _localCollisionPlaneNormal = new THREE.Vector3();\nlet _localCollisionPlanes: Array<NormalizedCollisionPlaneConfig> = [];\n// Trail ribbon helpers (reused across frames to avoid allocations)\nconst _trailDir = new THREE.Vector3();\nconst _trailPerp = new THREE.Vector3();\nconst _trailToCam = new THREE.Vector3();\nconst _distanceStep = { x: 0, y: 0, z: 0 };\nconst _tempPosition = { x: 0, y: 0, z: 0 };\nconst _modifierParams = {\n delta: 0,\n generalData: null as unknown as GeneralData,\n normalizedConfig: null as unknown as NormalizedParticleSystemConfig,\n attributes: null as unknown as MappedAttributes,\n scalarArray: null as unknown as Float32Array,\n particleLifetimePercentage: 0,\n particleIndex: 0,\n};\n\n/**\n * Converts a plain {x, y, z} object to a THREE.Vector3, using the fallback if undefined.\n */\nconst toVector3 = (\n v: { x?: number; y?: number; z?: number } | undefined,\n fallback: THREE.Vector3\n): THREE.Vector3 =>\n v ? new THREE.Vector3(v.x ?? 0, v.y ?? 0, v.z ?? 0) : fallback.clone();\n\n/**\n * Normalizes raw force field configs into the internal representation with THREE.Vector3 fields.\n */\nconst normalizeForceFields = (\n rawForceFields: Array<ForceFieldConfig> | undefined\n): Array<NormalizedForceFieldConfig> =>\n (rawForceFields ?? []).map((ff: ForceFieldConfig) => ({\n isActive: ff.isActive ?? true,\n type: ff.type ?? ForceFieldType.POINT,\n position: toVector3(ff.position, new THREE.Vector3(0, 0, 0)),\n direction: toVector3(ff.direction, new THREE.Vector3(0, 1, 0)).normalize(),\n strength: ff.strength ?? 1,\n range: Math.max(0, ff.range ?? Infinity),\n falloff: ff.falloff ?? ForceFieldFalloff.LINEAR,\n }));\n\n/**\n * Normalizes raw collision plane configs into the internal representation with THREE.Vector3 fields.\n */\nconst normalizeCollisionPlanes = (\n rawPlanes: Array<CollisionPlaneConfig> | undefined\n): Array<NormalizedCollisionPlaneConfig> =>\n (rawPlanes ?? []).map((cp: CollisionPlaneConfig) => ({\n isActive: cp.isActive ?? true,\n position: toVector3(cp.position, new THREE.Vector3(0, 0, 0)),\n normal: toVector3(cp.normal, new THREE.Vector3(0, 1, 0)).normalize(),\n mode: cp.mode ?? CollisionPlaneMode.KILL,\n dampen: Math.max(0, Math.min(1, cp.dampen ?? 0.5)),\n lifetimeLoss: Math.max(0, Math.min(1, cp.lifetimeLoss ?? 0)),\n }));\n\n/**\n * Mapping of blending mode string identifiers to Three.js blending constants.\n *\n * Used for converting serialized particle system configurations (e.g., from JSON)\n * to actual Three.js blending mode constants.\n *\n * @example\n * ```typescript\n * import { blendingMap } from '@newkrok/three-particles';\n *\n * // Convert string to Three.js constant\n * const blending = blendingMap['THREE.AdditiveBlending'];\n * // blending === THREE.AdditiveBlending\n * ```\n */\nexport const blendingMap = {\n 'THREE.NoBlending': THREE.NoBlending,\n 'THREE.NormalBlending': THREE.NormalBlending,\n 'THREE.AdditiveBlending': THREE.AdditiveBlending,\n 'THREE.SubtractiveBlending': THREE.SubtractiveBlending,\n 'THREE.MultiplyBlending': THREE.MultiplyBlending,\n};\n\n/**\n * Returns a deep copy of the default particle system configuration.\n *\n * This is useful when you want to start with default settings and modify specific properties\n * without affecting the internal default configuration object.\n *\n * @returns A new object containing all default particle system settings\n *\n * @example\n * ```typescript\n * import { getDefaultParticleSystemConfig, createParticleSystem } from '@newkrok/three-particles';\n *\n * // Get default config and modify it\n * const config = getDefaultParticleSystemConfig();\n * config.emission.rateOverTime = 100;\n * config.startColor.min = { r: 1, g: 0, b: 0 };\n *\n * const { instance } = createParticleSystem(config);\n * scene.add(instance);\n * ```\n */\nexport const getDefaultParticleSystemConfig = () =>\n JSON.parse(JSON.stringify(DEFAULT_PARTICLE_SYSTEM_CONFIG));\n\nconst DEFAULT_PARTICLE_SYSTEM_CONFIG: ParticleSystemConfig = {\n transform: {\n position: new THREE.Vector3(),\n rotation: new THREE.Vector3(),\n scale: new THREE.Vector3(1, 1, 1),\n },\n duration: 5.0,\n looping: true,\n startDelay: 0,\n startLifetime: 5.0,\n startSpeed: 1.0,\n startSize: 1.0,\n startOpacity: 1.0,\n startRotation: 0.0,\n startColor: {\n min: { r: 1.0, g: 1.0, b: 1.0 },\n max: { r: 1.0, g: 1.0, b: 1.0 },\n },\n gravity: 0.0,\n simulationSpace: SimulationSpace.LOCAL,\n simulationBackend: SimulationBackend.AUTO,\n maxParticles: 100.0,\n emission: {\n rateOverTime: 10.0,\n rateOverDistance: 0.0,\n bursts: [],\n },\n shape: {\n shape: Shape.SPHERE,\n sphere: {\n radius: 1.0,\n radiusThickness: 1.0,\n arc: 360.0,\n },\n cone: {\n angle: 25.0,\n radius: 1.0,\n radiusThickness: 1.0,\n arc: 360.0,\n },\n circle: {\n radius: 1.0,\n radiusThickness: 1.0,\n arc: 360.0,\n },\n rectangle: {\n rotation: { x: 0.0, y: 0.0 }, // TODO: add z rotation\n scale: { x: 1.0, y: 1.0 },\n },\n box: {\n scale: { x: 1.0, y: 1.0, z: 1.0 },\n emitFrom: EmitFrom.VOLUME,\n },\n },\n map: undefined,\n renderer: {\n blending: THREE.NormalBlending,\n discardBackgroundColor: false,\n backgroundColorTolerance: 1.0,\n backgroundColor: { r: 1.0, g: 1.0, b: 1.0 },\n transparent: true,\n depthTest: true,\n depthWrite: false,\n softParticles: {\n enabled: false,\n intensity: 1.0,\n },\n },\n velocityOverLifetime: {\n isActive: false,\n linear: {\n x: 0,\n y: 0,\n z: 0,\n },\n orbital: {\n x: 0,\n y: 0,\n z: 0,\n },\n },\n sizeOverLifetime: {\n isActive: false,\n lifetimeCurve: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 0, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n },\n colorOverLifetime: {\n isActive: false,\n r: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n g: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n b: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n },\n opacityOverLifetime: {\n isActive: false,\n lifetimeCurve: {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 0, percentage: 0 },\n { x: 1, y: 1, percentage: 1 },\n ],\n },\n },\n rotationOverLifetime: {\n isActive: false,\n min: 0.0,\n max: 0.0,\n },\n noise: {\n isActive: false,\n useRandomOffset: false,\n strength: 1.0,\n frequency: 0.5,\n octaves: 1,\n positionAmount: 1.0,\n rotationAmount: 0.0,\n sizeAmount: 0.0,\n },\n textureSheetAnimation: {\n tiles: new THREE.Vector2(1.0, 1.0),\n timeMode: TimeMode.LIFETIME,\n fps: 30.0,\n startFrame: 0,\n },\n forceFields: [],\n collisionPlanes: [],\n};\n\nconst calculatePositionAndVelocity = (\n generalData: GeneralData,\n { shape, sphere, cone, circle, rectangle, box }: ShapeConfig,\n startSpeed: Constant | RandomBetweenTwoConstants | LifetimeCurve,\n position: THREE.Vector3,\n velocity: THREE.Vector3\n) => {\n const calculatedStartSpeed = calculateValue(\n generalData.particleSystemId,\n startSpeed,\n generalData.normalizedLifetimePercentage\n );\n\n switch (shape) {\n case Shape.SPHERE:\n calculateRandomPositionAndVelocityOnSphere(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n sphere as Required<NonNullable<ShapeConfig['sphere']>>\n );\n break;\n\n case Shape.CONE:\n calculateRandomPositionAndVelocityOnCone(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n cone as Required<NonNullable<ShapeConfig['cone']>>\n );\n break;\n\n case Shape.CIRCLE:\n calculateRandomPositionAndVelocityOnCircle(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n circle as Required<NonNullable<ShapeConfig['circle']>>\n );\n break;\n\n case Shape.RECTANGLE:\n calculateRandomPositionAndVelocityOnRectangle(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n rectangle as Required<NonNullable<ShapeConfig['rectangle']>>\n );\n break;\n\n case Shape.BOX:\n calculateRandomPositionAndVelocityOnBox(\n position,\n generalData.wrapperQuaternion,\n velocity,\n calculatedStartSpeed,\n box as Required<NonNullable<ShapeConfig['box']>>\n );\n break;\n }\n};\n\nconst destroyParticleSystem = (particleSystem: THREE.Points | THREE.Mesh) => {\n createdParticleSystems = createdParticleSystems.filter(\n ({\n particleSystem: savedParticleSystem,\n trailMesh,\n generalData: { particleSystemId },\n }) => {\n if (savedParticleSystem !== particleSystem) {\n return true;\n }\n\n removeBezierCurveFunction(particleSystemId);\n\n // Dispose trail mesh if present\n if (trailMesh) {\n trailMesh.geometry.dispose();\n if (Array.isArray(trailMesh.material))\n trailMesh.material.forEach((m) => m.dispose());\n else trailMesh.material.dispose();\n if (trailMesh.parent) trailMesh.parent.remove(trailMesh);\n }\n\n savedParticleSystem.geometry.dispose();\n if (Array.isArray(savedParticleSystem.material))\n savedParticleSystem.material.forEach((material) => material.dispose());\n else savedParticleSystem.material.dispose();\n\n if (savedParticleSystem.parent)\n savedParticleSystem.parent.remove(savedParticleSystem);\n return false;\n }\n );\n};\n\n/**\n * Creates a new particle system with the specified configuration.\n *\n * This is the primary function for instantiating particle effects. It handles the complete\n * setup of a particle system including geometry creation, material configuration, shader setup,\n * and initialization of all particle properties.\n *\n * @param config - Configuration object for the particle system. If not provided, uses default settings.\n * See {@link ParticleSystemConfig} for all available options.\n * @param externalNow - Optional custom timestamp in milliseconds. If not provided, uses `Date.now()`.\n * Useful for synchronized particle systems or testing.\n *\n * @returns A {@link ParticleSystem} object containing:\n * - `instance`: The THREE.Object3D that should be added to your scene\n * - `resumeEmitter()`: Function to resume particle emission\n * - `pauseEmitter()`: Function to pause particle emission\n * - `dispose()`: Function to clean up resources and remove the particle system\n *\n * @example\n * ```typescript\n * import { createParticleSystem, updateParticleSystems } from '@newkrok/three-particles';\n *\n * // Create a basic particle system with default settings\n * const { instance, dispose } = createParticleSystem();\n * scene.add(instance);\n *\n * // Create a custom fire effect\n * const fireEffect = createParticleSystem({\n * duration: 2.0,\n * looping: true,\n * startLifetime: { min: 0.5, max: 1.5 },\n * startSpeed: { min: 2, max: 4 },\n * startSize: { min: 0.5, max: 1.5 },\n * startColor: {\n * min: { r: 1.0, g: 0.3, b: 0.0 },\n * max: { r: 1.0, g: 0.8, b: 0.0 }\n * },\n * emission: { rateOverTime: 50 },\n * shape: {\n * shape: Shape.CONE,\n * cone: { angle: 10, radius: 0.2 }\n * }\n * });\n * scene.add(fireEffect.instance);\n *\n * // In your animation loop\n * function animate(time) {\n * updateParticleSystems({ now: time, delta: deltaTime, elapsed: elapsedTime });\n * renderer.render(scene, camera);\n * }\n *\n * // Clean up when done\n * fireEffect.dispose();\n * ```\n *\n * @see {@link updateParticleSystems} - Required function to call in your animation loop\n * @see {@link ParticleSystemConfig} - Complete configuration options\n */\nexport const createParticleSystem = (\n config: ParticleSystemConfig = DEFAULT_PARTICLE_SYSTEM_CONFIG,\n externalNow?: number\n): ParticleSystem => {\n const now = externalNow || Date.now();\n const generalData: GeneralData = {\n particleSystemId: _particleSystemId++,\n normalizedLifetimePercentage: 0,\n distanceFromLastEmitByDistance: 0,\n lastWorldPosition: new THREE.Vector3(-99999),\n currentWorldPosition: new THREE.Vector3(-99999),\n worldPositionChange: new THREE.Vector3(),\n sourceWorldMatrix: new THREE.Matrix4(),\n worldQuaternion: new THREE.Quaternion(),\n wrapperQuaternion: new THREE.Quaternion(),\n worldScale: new THREE.Vector3(1, 1, 1),\n worldEuler: new THREE.Euler(),\n gravityVelocity: new THREE.Vector3(0, 0, 0),\n startValues: {},\n linearVelocityData: undefined,\n orbitalVelocityData: undefined,\n lifetimeValues: {},\n creationTimes: [],\n noise: {\n isActive: false,\n strength: 0,\n noisePower: 0,\n frequency: 0.5,\n positionAmount: 0,\n rotationAmount: 0,\n sizeAmount: 0,\n fbmMax: 1,\n },\n isEnabled: true,\n };\n const normalizedConfig = ObjectUtils.deepMerge(\n DEFAULT_PARTICLE_SYSTEM_CONFIG as NormalizedParticleSystemConfig,\n config,\n { applyToFirstObject: false, skippedProperties: [] }\n ) as NormalizedParticleSystemConfig;\n let particleMap: THREE.Texture | null =\n normalizedConfig.map ||\n (normalizedConfig.renderer.rendererType === RendererType.MESH\n ? createDefaultMeshTexture()\n : createDefaultParticleTexture());\n\n // Ensure ClampToEdgeWrapping for particle textures to prevent bleeding\n // at sprite-sheet tile boundaries (especially visible with WebGPU).\n if (particleMap) {\n particleMap.wrapS = THREE.ClampToEdgeWrapping;\n particleMap.wrapT = THREE.ClampToEdgeWrapping;\n }\n\n const {\n transform,\n duration,\n looping,\n startDelay,\n startLifetime,\n startSpeed,\n startSize,\n startRotation,\n startColor,\n startOpacity,\n gravity,\n simulationSpace,\n maxParticles,\n emission,\n shape,\n renderer,\n noise,\n velocityOverLifetime,\n onUpdate,\n onComplete,\n textureSheetAnimation,\n subEmitters,\n forceFields: rawForceFields,\n } = normalizedConfig;\n\n const normalizedForceFields: Array<NormalizedForceFieldConfig> =\n normalizeForceFields(rawForceFields);\n\n const normalizedCollisionPlanes: Array<NormalizedCollisionPlaneConfig> =\n normalizeCollisionPlanes(normalizedConfig.collisionPlanes);\n\n if (typeof renderer?.blending === 'string')\n renderer.blending = blendingMap[renderer.blending];\n\n const startPositions = Array.from(\n { length: maxParticles },\n () => new THREE.Vector3()\n );\n const velocities = Array.from(\n { length: maxParticles },\n () => new THREE.Vector3()\n );\n\n generalData.creationTimes = Array.from({ length: maxParticles }, () => 0);\n\n // Free list for O(1) inactive particle lookup (stack, top = end of array)\n const freeList: Array<number> = Array.from(\n { length: maxParticles },\n (_, i) => maxParticles - 1 - i\n );\n\n if (velocityOverLifetime.isActive) {\n generalData.linearVelocityData = Array.from(\n { length: maxParticles },\n () => ({\n speed: new THREE.Vector3(\n velocityOverLifetime.linear.x\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.linear.x,\n 0\n )\n : 0,\n velocityOverLifetime.linear.y\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.linear.y,\n 0\n )\n : 0,\n velocityOverLifetime.linear.z\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.linear.z,\n 0\n )\n : 0\n ),\n valueModifiers: {\n x: isLifeTimeCurve(velocityOverLifetime.linear.x || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.linear.x as LifetimeCurve\n )\n : undefined,\n y: isLifeTimeCurve(velocityOverLifetime.linear.y || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.linear.y as LifetimeCurve\n )\n : undefined,\n z: isLifeTimeCurve(velocityOverLifetime.linear.z || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.linear.z as LifetimeCurve\n )\n : undefined,\n },\n })\n );\n\n generalData.orbitalVelocityData = Array.from(\n { length: maxParticles },\n () => ({\n speed: new THREE.Vector3(\n velocityOverLifetime.orbital.x\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.x,\n 0\n )\n : 0,\n velocityOverLifetime.orbital.y\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.y,\n 0\n )\n : 0,\n velocityOverLifetime.orbital.z\n ? calculateValue(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.z,\n 0\n )\n : 0\n ),\n valueModifiers: {\n x: isLifeTimeCurve(velocityOverLifetime.orbital.x || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.x as LifetimeCurve\n )\n : undefined,\n y: isLifeTimeCurve(velocityOverLifetime.orbital.y || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.y as LifetimeCurve\n )\n : undefined,\n z: isLifeTimeCurve(velocityOverLifetime.orbital.z || 0)\n ? getCurveFunctionFromConfig(\n generalData.particleSystemId,\n velocityOverLifetime.orbital.z as LifetimeCurve\n )\n : undefined,\n },\n positionOffset: new THREE.Vector3(),\n })\n );\n }\n\n const startValueKeys: Array<keyof NormalizedParticleSystemConfig> = [\n 'startSize',\n 'startOpacity',\n ];\n startValueKeys.forEach((key) => {\n generalData.startValues[key] = Array.from({ length: maxParticles }, () =>\n calculateValue(\n generalData.particleSystemId,\n normalizedConfig[key] as\n | Constant\n | RandomBetweenTwoConstants\n | LifetimeCurve,\n 0\n )\n );\n });\n\n generalData.startValues.startColorR = Array.from(\n { length: maxParticles },\n () => 0\n );\n generalData.startValues.startColorG = Array.from(\n { length: maxParticles },\n () => 0\n );\n generalData.startValues.startColorB = Array.from(\n { length: maxParticles },\n () => 0\n );\n\n const lifetimeValueKeys: Array<keyof NormalizedParticleSystemConfig> = [\n 'rotationOverLifetime',\n ];\n lifetimeValueKeys.forEach((key) => {\n const value = normalizedConfig[key] as {\n isActive: boolean;\n } & RandomBetweenTwoConstants;\n if (value.isActive)\n generalData.lifetimeValues[key] = Array.from(\n { length: maxParticles },\n () => THREE.MathUtils.randFloat(value.min!, value.max!)\n );\n });\n\n // Pre-compute FBM normalisation divisor once (avoids recalculating every frame).\n // fbmMax = 1 + 0.5 + 0.25 + ... = 2 - 2^(-octaves)\n const fbmMax = 2 - Math.pow(2, -noise.octaves);\n\n generalData.noise = {\n isActive: noise.isActive,\n strength: noise.strength,\n noisePower: 0.15 * noise.strength,\n frequency: noise.frequency,\n positionAmount: noise.positionAmount,\n rotationAmount: noise.rotationAmount,\n sizeAmount: noise.sizeAmount,\n fbmMax,\n sampler: noise.isActive\n ? new FBM({\n seed: Math.random(),\n scale: noise.frequency,\n octaves: noise.octaves,\n })\n : undefined,\n offsets: noise.useRandomOffset\n ? Array.from({ length: maxParticles }, () => Math.random() * 100)\n : undefined,\n };\n\n // Initialize burst states if bursts are configured\n if (emission.bursts && emission.bursts.length > 0) {\n generalData.burstStates = emission.bursts.map(() => ({\n cyclesExecuted: 0,\n lastCycleTime: 0,\n probabilityPassed: false,\n }));\n }\n\n const useTrail = renderer.rendererType === RendererType.TRAIL;\n const useMesh = renderer.rendererType === RendererType.MESH;\n const useInstancing =\n !useTrail && !useMesh && renderer.rendererType === RendererType.INSTANCED;\n const useInstancedAttributes = useInstancing || useMesh;\n\n // Trail config defaults\n const defaultTrailCurve: LifetimeCurve = {\n type: LifeTimeCurve.BEZIER,\n scale: 1,\n bezierPoints: [\n { x: 0, y: 1, percentage: 0 },\n { x: 1, y: 0, percentage: 1 },\n ],\n };\n const trailConfig = useTrail\n ? {\n length: renderer.trail?.length ?? 20,\n width: renderer.trail?.width ?? 1.0,\n widthOverTrail: normalizeTrailCurve(\n renderer.trail?.widthOverTrail,\n defaultTrailCurve\n ),\n opacityOverTrail: normalizeTrailCurve(\n renderer.trail?.opacityOverTrail,\n defaultTrailCurve\n ),\n colorOverTrail: renderer.trail?.colorOverTrail,\n minVertexDistance: renderer.trail?.minVertexDistance ?? 0,\n maxTime: renderer.trail?.maxTime ?? 0,\n smoothing: renderer.trail?.smoothing ?? false,\n smoothingSubdivisions: renderer.trail?.smoothingSubdivisions ?? 3,\n twistPrevention: renderer.trail?.twistPrevention ?? false,\n ribbonId: renderer.trail?.ribbonId,\n }\n : undefined;\n\n // Initialize trail position history buffers\n if (useTrail && trailConfig) {\n const trailLength = trailConfig.length;\n generalData.trailLength = trailLength;\n generalData.positionHistory = new Float32Array(\n maxParticles * trailLength * 3\n );\n generalData.positionHistoryIndex = new Uint16Array(maxParticles);\n generalData.positionHistoryCount = new Uint16Array(maxParticles);\n\n // Adaptive sampling: track last sampled position per particle\n if (trailConfig.minVertexDistance > 0) {\n generalData.trailLastSampledPosition = new Float32Array(maxParticles * 3);\n }\n\n // Max time: track timestamp of each history sample\n if (trailConfig.maxTime > 0) {\n generalData.trailSampleTimes = new Float64Array(\n maxParticles * trailLength\n );\n }\n\n // Twist prevention: store previous ribbon normal per particle\n if (trailConfig.twistPrevention) {\n generalData.trailPrevNormal = new Float32Array(maxParticles * 3);\n }\n }\n\n // Attribute name prefix: instanced/mesh renderers use 'instance'-prefixed names\n // to avoid collision with the base geometry's own 'position' attribute.\n const attr = (name: string) =>\n useInstancedAttributes\n ? `instance${name.charAt(0).toUpperCase()}${name.slice(1)}`\n : name;\n\n // Position attribute is special: Points uses 'position', instanced/mesh uses 'instanceOffset'\n const posAttr = useInstancedAttributes ? 'instanceOffset' : 'position';\n\n const softParticlesEnabled = !!(\n renderer.softParticles?.enabled && renderer.softParticles?.depthTexture\n );\n\n const sharedUniforms: Record<string, { value: unknown }> = {\n elapsed: { value: 0.0 },\n map: { value: particleMap },\n tiles: {\n value: new THREE.Vector2(\n textureSheetAnimation.tiles?.x ?? 1,\n textureSheetAnimation.tiles?.y ?? 1\n ),\n },\n fps: { value: textureSheetAnimation.fps },\n useFPSForFrameIndex: {\n value: textureSheetAnimation.timeMode === TimeMode.FPS,\n },\n // backgroundColor is authored in sRGB; convert to linear so the\n // fragment comparison against the (now linear) texture sample is valid.\n backgroundColor: { value: rgbSRGBToLinear(renderer.backgroundColor) },\n discardBackgroundColor: { value: renderer.discardBackgroundColor },\n backgroundColorTolerance: { value: renderer.backgroundColorTolerance },\n ...(useInstancing ? { viewportHeight: { value: 1.0 } } : {}),\n softParticlesEnabled: { value: softParticlesEnabled },\n softParticlesIntensity: {\n value: Math.max(renderer.softParticles?.intensity ?? 1.0, 0.001),\n },\n sceneDepthTexture: {\n value: renderer.softParticles?.depthTexture ?? null,\n },\n cameraNearFar: { value: new THREE.Vector2(0.1, 1000.0) },\n };\n\n const getVertexShader = () => {\n if (useMesh) return MeshParticleVertexShader;\n if (useInstancing) return InstancedParticleVertexShader;\n return ParticleSystemVertexShader;\n };\n\n const getFragmentShader = () => {\n if (useMesh) return MeshParticleFragmentShader;\n if (useInstancing) return InstancedParticleFragmentShader;\n return ParticleSystemFragmentShader;\n };\n\n // Determine whether to use TSL materials (WebGPU path).\n // TSL is used whenever the factory is registered — regardless of simulationBackend.\n // This ensures WebGPURenderer always gets NodeMaterial (not GLSL ShaderMaterial).\n const useTSL = _tslMaterialFactory !== null;\n\n // Determine whether to use GPU compute for simulation.\n // GPU compute requires: TSL active + not trail + backend != CPU + compute factory registered.\n const useGPUCompute =\n useTSL &&\n !useTrail &&\n normalizedConfig.simulationBackend !== SimulationBackend.CPU &&\n !!_tslMaterialFactory?.createComputePipeline &&\n !!_tslMaterialFactory.writeParticleToModifierBuffers &&\n !!_tslMaterialFactory.deactivateParticleInModifierBuffers &&\n !!_tslMaterialFactory.flushEmitQueue;\n\n // Create GPU compute pipeline when active\n type GPUComputePipeline =\n import('./webgpu/compute-modifiers.js').ModifierComputePipeline;\n let gpuPipeline: GPUComputePipeline | null = null;\n\n if (useGPUCompute) {\n gpuPipeline = _tslMaterialFactory!.createComputePipeline!(\n maxParticles,\n useInstancedAttributes,\n normalizedConfig,\n generalData.particleSystemId,\n normalizedForceFields.length,\n normalizedCollisionPlanes.length\n );\n // Register the curveDataLength so the init data helpers know the offset.\n if (gpuPipeline && _tslMaterialFactory!.registerCurveDataLength) {\n _tslMaterialFactory!.registerCurveDataLength(\n gpuPipeline.buffers,\n gpuPipeline.curveDataLength\n );\n }\n }\n\n const rendererConfig = {\n transparent: renderer.transparent,\n blending: renderer.blending,\n depthTest: renderer.depthTest,\n depthWrite: renderer.depthWrite,\n };\n\n const material: THREE.Material = useTSL\n ? _tslMaterialFactory!.createTSLParticleMaterial(\n renderer.rendererType ?? RendererType.POINTS,\n sharedUniforms,\n rendererConfig,\n useGPUCompute\n )\n : new THREE.ShaderMaterial({\n uniforms: sharedUniforms,\n vertexShader: getVertexShader(),\n fragmentShader: getFragmentShader(),\n ...rendererConfig,\n });\n\n let geometry: THREE.BufferGeometry | THREE.InstancedBufferGeometry;\n\n if (useMesh) {\n const meshConfig = renderer.mesh;\n if (!meshConfig?.geometry) {\n throw new Error(\n 'RendererType.MESH requires a mesh configuration with a geometry. ' +\n 'Set renderer.mesh.geometry to a THREE.BufferGeometry instance.'\n );\n }\n const instancedGeometry = new THREE.InstancedBufferGeometry();\n // Copy base mesh geometry attributes (position, normal, uv, index)\n const sourceGeom = meshConfig.geometry;\n const srcPos = sourceGeom.getAttribute('position');\n if (srcPos) instancedGeometry.setAttribute('position', srcPos);\n const srcNormal = sourceGeom.getAttribute('normal');\n if (srcNormal) instancedGeometry.setAttribute('normal', srcNormal);\n const srcUv = sourceGeom.getAttribute('uv');\n if (srcUv) instancedGeometry.setAttribute('uv', srcUv);\n const srcIndex = sourceGeom.getIndex();\n if (srcIndex) instancedGeometry.setIndex(srcIndex);\n instancedGeometry.instanceCount = maxParticles;\n geometry = instancedGeometry;\n } else if (useInstancing) {\n const instancedGeometry = new THREE.InstancedBufferGeometry();\n // Base quad: 1x1 plane centred at origin (vertices from -0.5 to 0.5)\n const quadPositions = new Float32Array([\n -0.5, -0.5, 0, 0.5, -0.5, 0, 0.5, 0.5, 0, -0.5, 0.5, 0,\n ]);\n const quadIndices = new Uint16Array([0, 1, 2, 0, 2, 3]);\n instancedGeometry.setAttribute(\n 'position',\n new THREE.BufferAttribute(quadPositions, 3)\n );\n instancedGeometry.setIndex(new THREE.BufferAttribute(quadIndices, 1));\n instancedGeometry.instanceCount = maxParticles;\n geometry = instancedGeometry;\n } else {\n geometry = new THREE.BufferGeometry();\n }\n\n for (let i = 0; i < maxParticles; i++)\n calculatePositionAndVelocity(\n generalData,\n shape,\n startSpeed,\n startPositions[i],\n velocities[i]\n );\n\n // Create interleaved buffer for all scalar per-particle attributes.\n // In GPU compute mode this is kept for CPU death detection reads only\n // (not set as geometry attributes — storage buffers are used instead).\n const scalarArray = new Float32Array(maxParticles * SCALAR_STRIDE);\n\n // Pre-fill initial values\n for (let i = 0; i < maxParticles; i++) {\n const base = i * SCALAR_STRIDE;\n scalarArray[base + S_IS_ACTIVE] = 0;\n scalarArray[base + S_LIFETIME] = 0;\n scalarArray[base + S_START_LIFETIME] =\n calculateValue(generalData.particleSystemId, startLifetime, 0) * 1000;\n scalarArray[base + S_START_FRAME] = textureSheetAnimation.startFrame\n ? calculateValue(\n generalData.particleSystemId,\n textureSheetAnimation.startFrame,\n 0\n )\n : 0;\n scalarArray[base + S_SIZE] = generalData.startValues.startSize[i];\n scalarArray[base + S_ROTATION] = 0;\n // User color inputs are sRGB; the buffer stores linear so that shader\n // math, texture modulation, and the renderer's linear→sRGB output pass\n // all agree. See docs/color-pipeline-standardization-plan.md.\n const colorRandomRatio = Math.random();\n scalarArray[base + S_COLOR_R] = sRGBToLinear(\n startColor.min!.r! +\n colorRandomRatio * (startColor.max!.r! - startColor.min!.r!)\n );\n scalarArray[base + S_COLOR_G] = sRGBToLinear(\n startColor.min!.g! +\n colorRandomRatio * (startColor.max!.g! - startColor.min!.g!)\n );\n scalarArray[base + S_COLOR_B] = sRGBToLinear(\n startColor.min!.b! +\n colorRandomRatio * (startColor.max!.b! - startColor.min!.b!)\n );\n scalarArray[base + S_COLOR_A] = 0;\n }\n\n // Always create the interleaved buffer (needed for CPU death detection\n // and the CPU rendering path)\n const scalarInterleavedBuffer = useInstancedAttributes\n ? new THREE.InstancedInterleavedBuffer(scalarArray, SCALAR_STRIDE)\n : new THREE.InterleavedBuffer(scalarArray, SCALAR_STRIDE);\n\n if (useGPUCompute && gpuPipeline) {\n // ── GPU Compute Path: use storage buffers as geometry attributes ──\n // StorageBufferAttribute extends BufferAttribute, so these work as\n // geometry attributes read by the TSL material.\n // GPU path: 5 geometry attributes total (under 8 vertex buffer limit)\n // 1. base quad position (for instanced/mesh)\n // 2. particle position (vec3)\n // 3. color (vec4: R,G,B,A)\n // 4. particleState (vec4: lifetime, size, rotation, startFrame)\n // 5. startValues (vec4: startLifetime, startSize, startOpacity, startColorR)\n const gpuBuf = gpuPipeline.buffers;\n geometry.setAttribute(posAttr, gpuBuf.position);\n geometry.setAttribute(attr('color'), gpuBuf.color);\n geometry.setAttribute(attr('particleState'), gpuBuf.particleState);\n geometry.setAttribute(attr('startValues'), gpuBuf.startValues);\n } else {\n // ── CPU Path: position + interleaved scalar attributes ──\n const positionArray = new Float32Array(maxParticles * 3);\n for (let i = 0; i < maxParticles; i++) {\n positionArray[i * 3] = startPositions[i].x;\n positionArray[i * 3 + 1] = startPositions[i].y;\n positionArray[i * 3 + 2] = startPositions[i].z;\n }\n const positionAttribute = useInstancedAttributes\n ? new THREE.InstancedBufferAttribute(positionArray, 3)\n : new THREE.BufferAttribute(positionArray, 3);\n geometry.setAttribute(posAttr, positionAttribute);\n\n geometry.setAttribute(\n attr('isActive'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_IS_ACTIVE\n )\n );\n geometry.setAttribute(\n attr('lifetime'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_LIFETIME\n )\n );\n geometry.setAttribute(\n attr('startLifetime'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_START_LIFETIME\n )\n );\n geometry.setAttribute(\n attr('startFrame'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_START_FRAME\n )\n );\n geometry.setAttribute(\n attr('size'),\n new THREE.InterleavedBufferAttribute(scalarInterleavedBuffer, 1, S_SIZE)\n );\n geometry.setAttribute(\n attr('rotation'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 1,\n S_ROTATION\n )\n );\n // Packed RGBA color as single vec4 (R/G/B/A are contiguous in the\n // interleaved buffer at offsets 6,7,8,9 — read as a vec4 from offset 6)\n geometry.setAttribute(\n attr('color'),\n new THREE.InterleavedBufferAttribute(\n scalarInterleavedBuffer,\n 4,\n S_COLOR_R\n )\n );\n }\n\n // Packed quaternion vec4 attribute for 3D mesh rotation (only for MESH renderer,\n // CPU path only — GPU compute derives quaternion from particleState.z in the shader)\n if (useMesh && !useGPUCompute) {\n const quatArray = new Float32Array(maxParticles * 4);\n // Initialize to identity quaternion (0, 0, 0, 1)\n for (let i = 0; i < maxParticles; i++) {\n quatArray[i * 4 + 3] = 1; // w = 1\n }\n geometry.setAttribute(\n attr('quat'),\n new THREE.InstancedBufferAttribute(quatArray, 4)\n );\n }\n\n // Resolve per-particle attribute accessors (instanced/mesh uses prefixed names)\n const a = geometry.attributes;\n const aIsActive = a[attr('isActive')];\n const aColor = a[attr('color')];\n const aStartFrame = a[attr('startFrame')];\n const aStartLifetime = a[attr('startLifetime')];\n const aSize = a[attr('size')];\n const aRotation = a[attr('rotation')];\n const aLifetime = a[attr('lifetime')];\n const aPosition = a[posAttr];\n const aQuat = useMesh && !useGPUCompute ? a[attr('quat')] : undefined;\n\n const deactivateParticle = (particleIndex: number) => {\n const base = particleIndex * SCALAR_STRIDE;\n scalarArray[base + S_IS_ACTIVE] = 0;\n scalarArray[base + S_COLOR_A] = 0;\n if (useGPUCompute && gpuPipeline) {\n _tslMaterialFactory!.deactivateParticleInModifierBuffers!(\n gpuPipeline.buffers,\n particleIndex\n );\n } else {\n scalarInterleavedBuffer.needsUpdate = true;\n }\n freeList.push(particleIndex);\n };\n\n const activateParticle = ({\n particleIndex,\n activationTime,\n position,\n }: {\n particleIndex: number;\n activationTime: number;\n position: Required<Point3D>;\n }) => {\n const base = particleIndex * SCALAR_STRIDE;\n scalarArray[base + S_IS_ACTIVE] = 1;\n generalData.creationTimes[particleIndex] = activationTime;\n\n // Reset trail history so a recycled particle doesn't inherit old trail\n if (generalData.positionHistoryCount) {\n generalData.positionHistoryCount[particleIndex] = 0;\n generalData.positionHistoryIndex![particleIndex] = 0;\n\n // Reset adaptive sampling last position\n if (generalData.trailLastSampledPosition) {\n const lsIdx = particleIndex * 3;\n generalData.trailLastSampledPosition[lsIdx] = 0;\n generalData.trailLastSampledPosition[lsIdx + 1] = 0;\n generalData.trailLastSampledPosition[lsIdx + 2] = 0;\n }\n\n // Reset twist prevention normal\n if (generalData.trailPrevNormal) {\n const nIdx = particleIndex * 3;\n generalData.trailPrevNormal[nIdx] = 0;\n generalData.trailPrevNormal[nIdx + 1] = 0;\n generalData.trailPrevNormal[nIdx + 2] = 0;\n }\n }\n\n if (generalData.noise.offsets)\n generalData.noise.offsets[particleIndex] = Math.random() * 100;\n\n // sRGB → linear on emit; buffer + startValues mirrors both store linear.\n // See docs/color-pipeline-standardization-plan.md.\n const colorRandomRatio = Math.random();\n const cfgStartColor = normalizedConfig.startColor;\n\n scalarArray[base + S_COLOR_R] = sRGBToLinear(\n cfgStartColor.min!.r! +\n colorRandomRatio * (cfgStartColor.max!.r! - cfgStartColor.min!.r!)\n );\n\n scalarArray[base + S_COLOR_G] = sRGBToLinear(\n cfgStartColor.min!.g! +\n colorRandomRatio * (cfgStartColor.max!.g! - cfgStartColor.min!.g!)\n );\n\n scalarArray[base + S_COLOR_B] = sRGBToLinear(\n cfgStartColor.min!.b! +\n colorRandomRatio * (cfgStartColor.max!.b! - cfgStartColor.min!.b!)\n );\n\n generalData.startValues.startColorR[particleIndex] =\n scalarArray[base + S_COLOR_R];\n generalData.startValues.startColorG[particleIndex] =\n scalarArray[base + S_COLOR_G];\n generalData.startValues.startColorB[particleIndex] =\n scalarArray[base + S_COLOR_B];\n\n scalarArray[base + S_START_FRAME] = normalizedConfig.textureSheetAnimation\n .startFrame\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.textureSheetAnimation.startFrame,\n 0\n )\n : 0;\n\n scalarArray[base + S_START_LIFETIME] =\n calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startLifetime,\n generalData.normalizedLifetimePercentage\n ) * 1000;\n\n generalData.startValues.startSize[particleIndex] = calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startSize,\n generalData.normalizedLifetimePercentage\n );\n scalarArray[base + S_SIZE] =\n generalData.startValues.startSize[particleIndex];\n\n generalData.startValues.startOpacity[particleIndex] = calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startOpacity,\n generalData.normalizedLifetimePercentage\n );\n scalarArray[base + S_COLOR_A] =\n generalData.startValues.startOpacity[particleIndex];\n\n scalarArray[base + S_ROTATION] = calculateValue(\n generalData.particleSystemId,\n normalizedConfig.startRotation,\n generalData.normalizedLifetimePercentage\n );\n\n // Initialize mesh particle quaternion from the Z-rotation startRotation\n if (aQuat) {\n const rotZ = scalarArray[base + S_ROTATION];\n const halfZ = rotZ * 0.5;\n const qi = particleIndex * 4;\n aQuat.array[qi] = 0;\n aQuat.array[qi + 1] = 0;\n aQuat.array[qi + 2] = Math.sin(halfZ);\n aQuat.array[qi + 3] = Math.cos(halfZ);\n aQuat.needsUpdate = true;\n }\n\n if (normalizedConfig.rotationOverLifetime.isActive)\n generalData.lifetimeValues.rotationOverLifetime[particleIndex] =\n THREE.MathUtils.randFloat(\n normalizedConfig.rotationOverLifetime.min!,\n normalizedConfig.rotationOverLifetime.max!\n );\n\n calculatePositionAndVelocity(\n generalData,\n normalizedConfig.shape,\n normalizedConfig.startSpeed,\n startPositions[particleIndex],\n velocities[particleIndex]\n );\n // GPU compute: position is set via the emit scatter in the compute shader\n // (writeParticleToModifierBuffers queues it). Do NOT set needsUpdate —\n // that triggers a full CPU→GPU upload that overwrites GPU-computed\n // positions for all particles.\n // However, we still write the CPU-side array so death sub-emitters can\n // read the particle's approximate position without GPU readback.\n {\n const positionIndex = particleIndex * 3;\n // WORLD simulation space: the buffer stores world coordinates. The\n // shape-emission offset (startPositions) is rotated by the emitter's\n // world rotation AND scaled by the emitter's world scale, matching\n // Unity's Shape module when Scaling Mode is Local/Hierarchy. The\n // emitter's world translation is then added so the particle starts\n // at the correct world-space location.\n //\n // LOCAL simulation space: the buffer is in the emitter's local\n // frame; the shape offset is added as-is (parent scale affects the\n // rendered size via particleSystem.matrixWorld at draw time).\n const isWorld =\n normalizedConfig.simulationSpace === SimulationSpace.WORLD;\n const ox = startPositions[particleIndex].x;\n const oy = startPositions[particleIndex].y;\n const oz = startPositions[particleIndex].z;\n if (isWorld) {\n const m = generalData.sourceWorldMatrix.elements;\n const s = generalData.worldScale;\n aPosition.array[positionIndex] = position.x + ox * s.x + m[12];\n aPosition.array[positionIndex + 1] = position.y + oy * s.y + m[13];\n aPosition.array[positionIndex + 2] = position.z + oz * s.z + m[14];\n } else {\n aPosition.array[positionIndex] = position.x + ox;\n aPosition.array[positionIndex + 1] = position.y + oy;\n aPosition.array[positionIndex + 2] = position.z + oz;\n }\n if (!useGPUCompute) {\n aPosition.needsUpdate = true;\n }\n }\n\n if (generalData.linearVelocityData) {\n generalData.linearVelocityData[particleIndex].speed.set(\n normalizedConfig.velocityOverLifetime.linear.x\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.linear.x,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.linear.y\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.linear.y,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.linear.z\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.linear.z,\n 0\n )\n : 0\n );\n }\n\n if (generalData.orbitalVelocityData) {\n generalData.orbitalVelocityData[particleIndex].speed.set(\n normalizedConfig.velocityOverLifetime.orbital.x\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.orbital.x,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.orbital.y\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.orbital.y,\n 0\n )\n : 0,\n normalizedConfig.velocityOverLifetime.orbital.z\n ? calculateValue(\n generalData.particleSystemId,\n normalizedConfig.velocityOverLifetime.orbital.z,\n 0\n )\n : 0\n );\n generalData.orbitalVelocityData[particleIndex].positionOffset.set(\n startPositions[particleIndex].x,\n startPositions[particleIndex].y,\n startPositions[particleIndex].z\n );\n }\n\n scalarArray[base + S_LIFETIME] = 0;\n\n if (useGPUCompute && gpuPipeline) {\n // Write all particle data to GPU storage buffers.\n //\n // WORLD simulation space: the GPU buffer stores world coordinates.\n // The shape offset (startPositions) is scaled by the emitter's\n // world scale (Unity Shape-module parity) and then offset by the\n // emitter's world translation. LOCAL space uses the shape offset\n // as-is since the buffer is in the emitter's local frame.\n const isWorld =\n normalizedConfig.simulationSpace === SimulationSpace.WORLD;\n const m = generalData.sourceWorldMatrix.elements;\n const s = generalData.worldScale;\n const ox = startPositions[particleIndex].x;\n const oy = startPositions[particleIndex].y;\n const oz = startPositions[particleIndex].z;\n _tslMaterialFactory!.writeParticleToModifierBuffers!(\n gpuPipeline.buffers,\n particleIndex,\n {\n position: {\n x: position.x + (isWorld ? ox * s.x + m[12] : ox),\n y: position.y + (isWorld ? oy * s.y + m[13] : oy),\n z: position.z + (isWorld ? oz * s.z + m[14] : oz),\n },\n velocity: {\n x: velocities[particleIndex].x,\n y: velocities[particleIndex].y,\n z: velocities[particleIndex].z,\n },\n startLifetime: scalarArray[base + S_START_LIFETIME],\n colorA: scalarArray[base + S_COLOR_A],\n size: scalarArray[base + S_SIZE],\n rotation: scalarArray[base + S_ROTATION],\n colorR: scalarArray[base + S_COLOR_R],\n colorG: scalarArray[base + S_COLOR_G],\n colorB: scalarArray[base + S_COLOR_B],\n startSize: generalData.startValues.startSize[particleIndex],\n startOpacity: generalData.startValues.startOpacity[particleIndex],\n startColorR: generalData.startValues.startColorR[particleIndex],\n startColorG: generalData.startValues.startColorG[particleIndex],\n startColorB: generalData.startValues.startColorB[particleIndex],\n rotationSpeed: generalData.lifetimeValues.rotationOverLifetime\n ? generalData.lifetimeValues.rotationOverLifetime[particleIndex]\n : 0,\n noiseOffset: generalData.noise.offsets\n ? generalData.noise.offsets[particleIndex]\n : 0,\n startFrame: scalarArray[base + S_START_FRAME],\n orbitalOffset: {\n x: startPositions[particleIndex].x,\n y: startPositions[particleIndex].y,\n z: startPositions[particleIndex].z,\n },\n }\n );\n // Modifiers run on GPU — no CPU applyModifiers needed\n } else {\n scalarInterleavedBuffer.needsUpdate = true;\n\n applyModifiers({\n delta: 0,\n generalData,\n normalizedConfig,\n attributes: mappedAttributes,\n scalarArray,\n particleLifetimePercentage: 0,\n particleIndex,\n });\n }\n };\n\n // Sub-emitter setup\n const subEmitterArr: Array<SubEmitterConfig> = subEmitters ?? [];\n const deathSubEmitters = subEmitterArr.filter(\n (s) => (s.trigger ?? SubEmitterTrigger.DEATH) === SubEmitterTrigger.DEATH\n );\n const birthSubEmitters = subEmitterArr.filter(\n (s) => s.trigger === SubEmitterTrigger.BIRTH\n );\n // Track sub-emitter instances per config for per-config maxInstances enforcement\n const subEmitterInstancesMap = new Map<\n SubEmitterConfig,\n Array<ParticleSystem>\n >();\n for (const cfg of subEmitterArr) {\n subEmitterInstancesMap.set(cfg, []);\n }\n\n const cleanupCompletedInstances = (instances: Array<ParticleSystem>) => {\n for (let i = instances.length - 1; i >= 0; i--) {\n const sub = instances[i];\n const geomAttrs = sub.instance.geometry?.attributes;\n const isActiveAttr = geomAttrs\n ? (geomAttrs.isActive ?? geomAttrs.instanceIsActive)\n : undefined;\n if (!isActiveAttr) {\n sub.dispose();\n instances.splice(i, 1);\n continue;\n }\n let hasActive = false;\n for (let j = 0; j < isActiveAttr.count; j++) {\n if (isActiveAttr.getX(j)) {\n hasActive = true;\n break;\n }\n }\n if (!hasActive) {\n sub.dispose();\n instances.splice(i, 1);\n }\n }\n };\n\n const spawnSubEmitters = (\n configs: Array<SubEmitterConfig>,\n position: THREE.Vector3,\n velocity: THREE.Vector3,\n spawnNow: number\n ) => {\n // The death/birth callbacks pass `position` in world coordinates. The\n // sub-emitter becomes a child of particleSystem.parent, so its\n // transform.position must be expressed in that parent's local frame.\n const parentObj = particleSystem.parent;\n _subLocalPosition.copy(position);\n if (parentObj) {\n parentObj.updateMatrixWorld();\n parentObj.worldToLocal(_subLocalPosition);\n }\n\n for (const subConfig of configs) {\n const instances = subEmitterInstancesMap.get(subConfig)!;\n const maxInst = subConfig.maxInstances ?? 32;\n if (instances.length >= maxInst) {\n cleanupCompletedInstances(instances);\n if (instances.length >= maxInst) continue;\n }\n\n const inheritVelocity = subConfig.inheritVelocity ?? 0;\n const subSystem = createParticleSystem(\n {\n ...subConfig.config,\n looping: false,\n // Sub-emitters must always use CPU simulation because their compute\n // nodes cannot be dispatched independently by the parent system.\n simulationBackend: SimulationBackend.CPU,\n transform: {\n ...subConfig.config.transform,\n position: new THREE.Vector3(\n _subLocalPosition.x,\n _subLocalPosition.y,\n _subLocalPosition.z\n ),\n },\n renderer: {\n ...(subConfig.config.renderer ?? {}),\n ...(subConfig.config.renderer?.rendererType\n ? {}\n : renderer.rendererType === RendererType.MESH ||\n renderer.rendererType === RendererType.TRAIL\n ? {}\n : { rendererType: renderer.rendererType }),\n } as typeof subConfig.config.renderer,\n ...(inheritVelocity > 0\n ? {\n startSpeed:\n (typeof subConfig.config.startSpeed === 'number'\n ? subConfig.config.startSpeed\n : typeof subConfig.config.startSpeed === 'object' &&\n subConfig.config.startSpeed !== null &&\n 'min' in subConfig.config.startSpeed\n ? ((\n subConfig.config\n .startSpeed as RandomBetweenTwoConstants\n ).min ?? 0)\n : 0) +\n velocity.length() * inheritVelocity,\n }\n : {}),\n },\n spawnNow\n );\n\n if (parentObj) parentObj.add(subSystem.instance);\n\n instances.push(subSystem);\n }\n };\n\n // Trail mesh setup: ribbon geometry + material (created only for TRAIL mode)\n let trailMesh: THREE.Mesh | undefined;\n let trailGeometry: THREE.BufferGeometry | undefined;\n let trailPositionAttr: THREE.BufferAttribute | undefined;\n let trailAlphaAttr: THREE.BufferAttribute | undefined;\n let trailColorAttr: THREE.BufferAttribute | undefined;\n let trailNextAttr: THREE.BufferAttribute | undefined;\n let trailHalfWidthAttr: THREE.BufferAttribute | undefined;\n let trailUVAttr: THREE.BufferAttribute | undefined;\n let trailIndexAttr: THREE.BufferAttribute | undefined;\n let trailWidthCurveFn: CurveFunction | undefined;\n let trailOpacityCurveFn: CurveFunction | undefined;\n let trailColorOverTrailFns:\n | { r: CurveFunction; g: CurveFunction; b: CurveFunction }\n | undefined;\n\n if (useTrail && trailConfig) {\n const trailLength = trailConfig.length;\n // Each particle contributes (trailLength) vertices (2 per segment joint: left+right)\n // Segments = trailLength - 1, so 2 * trailLength vertices per particle\n const verticesPerParticle = trailLength * 2;\n const totalVertices = maxParticles * verticesPerParticle;\n // Each segment (between 2 consecutive history points) = 2 triangles = 6 indices\n const indicesPerParticle = (trailLength - 1) * 6;\n const totalIndices = maxParticles * indicesPerParticle;\n\n trailGeometry = new THREE.BufferGeometry();\n const trailPositions = new Float32Array(totalVertices * 3);\n const trailNextPositions = new Float32Array(totalVertices * 3);\n const trailAlphas = new Float32Array(totalVertices);\n const trailColors = new Float32Array(totalVertices * 4);\n const trailOffsets = new Float32Array(totalVertices);\n const trailHalfWidths = new Float32Array(totalVertices);\n const trailUVs = new Float32Array(totalVertices * 2);\n const trailIndices = new Uint32Array(totalIndices);\n\n // Pre-build index buffer and static offset attribute (-1/+1 per side)\n for (let p = 0; p < maxParticles; p++) {\n const vertBase = p * verticesPerParticle;\n const idxBase = p * indicesPerParticle;\n for (let s = 0; s < trailLength; s++) {\n trailOffsets[vertBase + s * 2] = -1.0; // left\n trailOffsets[vertBase + s * 2 + 1] = 1.0; // right\n }\n for (let s = 0; s < trailLength - 1; s++) {\n const i = idxBase + s * 6;\n const v = vertBase + s * 2;\n trailIndices[i] = v;\n trailIndices[i + 1] = v + 1;\n trailIndices[i + 2] = v + 2;\n trailIndices[i + 3] = v + 1;\n trailIndices[i + 4] = v + 3;\n trailIndices[i + 5] = v + 2;\n }\n }\n\n trailPositionAttr = new THREE.BufferAttribute(trailPositions, 3);\n trailPositionAttr.setUsage(THREE.DynamicDrawUsage);\n trailNextAttr = new THREE.BufferAttribute(trailNextPositions, 3);\n trailNextAttr.setUsage(THREE.DynamicDrawUsage);\n trailAlphaAttr = new THREE.BufferAttribute(trailAlphas, 1);\n trailAlphaAttr.setUsage(THREE.DynamicDrawUsage);\n trailColorAttr = new THREE.BufferAttribute(trailColors, 4);\n trailColorAttr.setUsage(THREE.DynamicDrawUsage);\n trailHalfWidthAttr = new THREE.BufferAttribute(trailHalfWidths, 1);\n trailHalfWidthAttr.setUsage(THREE.DynamicDrawUsage);\n trailUVAttr = new THREE.BufferAttribute(trailUVs, 2);\n trailUVAttr.setUsage(THREE.DynamicDrawUsage);\n trailIndexAttr = new THREE.BufferAttribute(trailIndices, 1);\n\n trailGeometry.setAttribute('position', trailPositionAttr);\n trailGeometry.setAttribute('trailNext', trailNextAttr);\n trailGeometry.setAttribute('trailAlpha', trailAlphaAttr);\n trailGeometry.setAttribute('trailColor', trailColorAttr);\n trailGeometry.setAttribute(\n 'trailOffset',\n new THREE.BufferAttribute(trailOffsets, 1)\n );\n trailGeometry.setAttribute('trailHalfWidth', trailHalfWidthAttr);\n trailGeometry.setAttribute('trailUV', trailUVAttr);\n trailGeometry.setIndex(trailIndexAttr);\n\n const trailUniformValues = {\n map: { value: particleMap },\n useMap: { value: !!particleMap },\n discardBackgroundColor: { value: renderer.discardBackgroundColor },\n // sRGB → linear so the trail fragment comparison matches the\n // (now linear) texture sample and vertex color.\n backgroundColor: { value: rgbSRGBToLinear(renderer.backgroundColor) },\n backgroundColorTolerance: { value: renderer.backgroundColorTolerance },\n softParticlesEnabled: { value: softParticlesEnabled },\n softParticlesIntensity: {\n value: Math.max(renderer.softParticles?.intensity ?? 1.0, 0.001),\n },\n sceneDepthTexture: {\n value: renderer.softParticles?.depthTexture ?? null,\n },\n cameraNearFar: { value: new THREE.Vector2(0.1, 1000.0) },\n };\n\n const trailMaterial: THREE.Material = useTSL\n ? _tslMaterialFactory!.createTSLTrailMaterial(\n trailUniformValues,\n rendererConfig\n )\n : new THREE.ShaderMaterial({\n uniforms: trailUniformValues,\n vertexShader: TrailVertexShader,\n fragmentShader: TrailFragmentShader,\n ...rendererConfig,\n side: THREE.DoubleSide,\n });\n\n trailMesh = new THREE.Mesh(trailGeometry, trailMaterial);\n trailMesh.frustumCulled = false;\n\n // Capture camera world position each frame for billboard trail ribbons\n const trailCameraPos = new THREE.Vector3();\n trailMesh.onBeforeRender = (\n _renderer: THREE.WebGLRenderer,\n _scene: THREE.Scene,\n camera: THREE.Camera\n ) => {\n camera.getWorldPosition(trailCameraPos);\n if (\n softParticlesEnabled &&\n (camera as THREE.PerspectiveCamera).isPerspectiveCamera\n ) {\n const perspCam = camera as THREE.PerspectiveCamera;\n (trailUniformValues.cameraNearFar.value as THREE.Vector2).set(\n perspCam.near,\n perspCam.far\n );\n }\n };\n generalData.trailCameraPosition = trailCameraPos;\n\n // Pre-compute curve functions for trail width/opacity\n trailWidthCurveFn = getCurveFunctionFromConfig(\n generalData.particleSystemId,\n trailConfig.widthOverTrail\n );\n trailOpacityCurveFn = getCurveFunctionFromConfig(\n generalData.particleSystemId,\n trailConfig.opacityOverTrail\n );\n\n if (trailConfig.colorOverTrail?.isActive) {\n trailColorOverTrailFns = {\n r: getCurveFunctionFromConfig(\n generalData.particleSystemId,\n normalizeTrailCurve(trailConfig.colorOverTrail.r, defaultTrailCurve)\n ),\n g: getCurveFunctionFromConfig(\n generalData.particleSystemId,\n normalizeTrailCurve(trailConfig.colorOverTrail.g, defaultTrailCurve)\n ),\n b: getCurveFunctionFromConfig(\n generalData.particleSystemId,\n normalizeTrailCurve(trailConfig.colorOverTrail.b, defaultTrailCurve)\n ),\n };\n }\n }\n\n let particleSystem: THREE.Points | THREE.Mesh =\n useInstancing || useMesh\n ? new THREE.Mesh(geometry, material)\n : new THREE.Points(geometry, material);\n\n // Late-bound ref so onBeforeRender can access instanceData (assigned later).\n const _instanceRef: { current: ParticleSystemInstance | null } = {\n current: null,\n };\n\n if (useInstancing || softParticlesEnabled || useGPUCompute) {\n particleSystem.onBeforeRender = (\n glRenderer: THREE.WebGLRenderer,\n _scene: THREE.Scene,\n camera: THREE.Camera\n ) => {\n if (useInstancing) {\n const size = glRenderer.getSize(new THREE.Vector2());\n sharedUniforms.viewportHeight.value =\n size.y * glRenderer.getPixelRatio();\n }\n if (\n softParticlesEnabled &&\n (camera as THREE.PerspectiveCamera).isPerspectiveCamera\n ) {\n const perspCam = camera as THREE.PerspectiveCamera;\n (sharedUniforms.cameraNearFar.value as THREE.Vector2).set(\n perspCam.near,\n perspCam.far\n );\n }\n // Note: GPU compute dispatch is done by the caller via\n // renderer.compute(system.computeNode) before renderer.render().\n };\n }\n\n // In trail mode, hide the particle points (but keep the parent visible so\n // the trail mesh child can render) and attach the visible trail mesh\n if (useTrail && trailMesh) {\n material.visible = false;\n particleSystem.add(trailMesh);\n }\n\n particleSystem.position.copy(transform!.position!);\n particleSystem.rotation.x = THREE.MathUtils.degToRad(transform.rotation!.x);\n particleSystem.rotation.y = THREE.MathUtils.degToRad(transform.rotation!.y);\n particleSystem.rotation.z = THREE.MathUtils.degToRad(transform.rotation!.z);\n particleSystem.scale.copy(transform.scale!);\n\n // Create a mapped view of attributes so the update loop and modifiers can\n // use standard names regardless of the renderer type.\n const mappedAttributes = {\n position: aPosition,\n isActive: aIsActive,\n lifetime: aLifetime,\n startLifetime: aStartLifetime,\n startFrame: aStartFrame,\n size: aSize,\n rotation: aRotation,\n color: aColor,\n ...(useMesh ? { quat: aQuat } : {}),\n };\n\n const calculatedCreationTime =\n now + calculateValue(generalData.particleSystemId, startDelay) * 1000;\n\n // WORLD simulation space: decouple rendering transform from the emitter.\n // The particle buffer stores world-space coordinates, so matrixWorld is\n // forced to identity each frame. The emitter's actual world transform is\n // captured in generalData.sourceWorldMatrix for positioning new particles\n // and orienting the emission shape.\n if (normalizedConfig.simulationSpace === SimulationSpace.WORLD) {\n particleSystem.matrixWorldAutoUpdate = false;\n particleSystem.matrixWorld.identity();\n }\n\n const hasDeathSubEmitters = deathSubEmitters.length > 0;\n const hasBirthSubEmitters = birthSubEmitters.length > 0;\n\n const onParticleDeath = hasDeathSubEmitters\n ? (\n particleIndex: number,\n positionArr: THREE.TypedArray,\n velocity: THREE.Vector3,\n deathNow: number\n ) => {\n const posIdx = particleIndex * 3;\n _subEmitterPosition.set(\n positionArr[posIdx],\n positionArr[posIdx + 1],\n positionArr[posIdx + 2]\n );\n // Convert local particle position to world space so the sub-emitter\n // spawns at the correct scene position regardless of transform offset.\n // updateMatrixWorld() guarantees the transform is fresh — otherwise a\n // parent moved after the last scene traversal would place the spawn\n // at a stale position.\n if (simulationSpace === SimulationSpace.LOCAL) {\n particleSystem.updateMatrixWorld();\n particleSystem.localToWorld(_subEmitterPosition);\n }\n spawnSubEmitters(\n deathSubEmitters,\n _subEmitterPosition,\n velocity,\n deathNow\n );\n }\n : undefined;\n\n const onParticleBirth = hasBirthSubEmitters\n ? (\n particleIndex: number,\n positionArr: THREE.TypedArray,\n velocity: THREE.Vector3,\n birthNow: number\n ) => {\n const posIdx = particleIndex * 3;\n _subEmitterPosition.set(\n positionArr[posIdx],\n positionArr[posIdx + 1],\n positionArr[posIdx + 2]\n );\n // Convert local particle position to world space so the sub-emitter\n // spawns at the correct scene position regardless of transform offset.\n // updateMatrixWorld() guarantees the transform is fresh — otherwise a\n // parent moved after the last scene traversal would place the spawn\n // at a stale position.\n if (simulationSpace === SimulationSpace.LOCAL) {\n particleSystem.updateMatrixWorld();\n particleSystem.localToWorld(_subEmitterPosition);\n }\n spawnSubEmitters(\n birthSubEmitters,\n _subEmitterPosition,\n velocity,\n birthNow\n );\n }\n : undefined;\n\n const instanceData: ParticleSystemInstance = {\n particleSystem,\n mappedAttributes,\n scalarArray,\n scalarInterleavedBuffer,\n elapsedUniform: sharedUniforms.elapsed as { value: number },\n generalData,\n onUpdate,\n onComplete,\n creationTime: calculatedCreationTime,\n lastEmissionTime: calculatedCreationTime,\n duration,\n looping,\n simulationSpace,\n gravity,\n normalizedForceFields,\n normalizedCollisionPlanes,\n emission,\n normalizedConfig,\n iterationCount: 0,\n velocities,\n freeList,\n deactivateParticle,\n activateParticle,\n onParticleDeath,\n onParticleBirth,\n useGPUCompute: useGPUCompute && gpuPipeline !== null,\n computePipeline: gpuPipeline ?? undefined,\n computeDispatchReady: false,\n ...(useTrail\n ? {\n trailMesh,\n trailPositionAttr,\n trailAlphaAttr,\n trailColorAttr,\n trailNextAttr: trailNextAttr as THREE.BufferAttribute,\n trailHalfWidthAttr: trailHalfWidthAttr as THREE.BufferAttribute,\n trailUVAttr: trailUVAttr as THREE.BufferAttribute,\n trailWidthCurveFn,\n trailOpacityCurveFn,\n trailColorOverTrailFns,\n trailConfig: {\n length: trailConfig!.length,\n width: trailConfig!.width,\n minVertexDistance: trailConfig!.minVertexDistance,\n maxTime: trailConfig!.maxTime,\n smoothing: trailConfig!.smoothing,\n smoothingSubdivisions: trailConfig!.smoothingSubdivisions,\n twistPrevention: trailConfig!.twistPrevention,\n ribbonId: trailConfig!.ribbonId,\n },\n }\n : {}),\n };\n\n createdParticleSystems.push(instanceData);\n _instanceRef.current = instanceData;\n\n const resumeEmitter = () => (generalData.isEnabled = true);\n const pauseEmitter = () => (generalData.isEnabled = false);\n const dispose = () => {\n for (const instances of subEmitterInstancesMap.values()) {\n for (const sub of instances) sub.dispose();\n instances.length = 0;\n }\n destroyParticleSystem(particleSystem);\n };\n const update = (cycleData: CycleData) => {\n updateParticleSystemInstance(instanceData, cycleData);\n for (const instances of subEmitterInstancesMap.values()) {\n for (const sub of instances) sub.update(cycleData);\n }\n };\n\n const updateConfig = (partialConfig: Partial<ParticleSystemConfig>) => {\n // Deep-merge partial config into the live normalizedConfig\n ObjectUtils.deepMerge(instanceData.normalizedConfig, partialConfig, {\n applyToFirstObject: true,\n skippedProperties: [],\n });\n\n const cfg = instanceData.normalizedConfig;\n\n // Update instance-level cached scalars\n if (partialConfig.gravity !== undefined) {\n instanceData.gravity = cfg.gravity;\n }\n if (partialConfig.duration !== undefined)\n instanceData.duration = cfg.duration;\n if (partialConfig.looping !== undefined) instanceData.looping = cfg.looping;\n if (\n partialConfig.simulationSpace !== undefined &&\n instanceData.simulationSpace !== cfg.simulationSpace\n ) {\n // Switching simulation space live. The existing buffer of active\n // particles is in the _old_ frame — rather than walk the buffer and\n // convert every position (which still wouldn't reproduce the visual\n // continuity the old frame had), we deactivate the live particles\n // so the system re-emits from the new frame's origin cleanly. New\n // emissions use the right frame because `simulationSpace` is also\n // synced below.\n //\n // We also flip `matrixWorldAutoUpdate` + reset `lastWorldPosition`\n // to match the state createParticleSystem would have set. Without\n // this, particles rendered in the first few frames after the switch\n // inherit the wrong world matrix and appear to jump between origins.\n for (let i = 0; i < maxParticles; i++) {\n if (scalarArray[i * SCALAR_STRIDE + S_IS_ACTIVE]) {\n deactivateParticle(i);\n }\n }\n generalData.lastWorldPosition.set(-99999, -99999, -99999);\n if (cfg.simulationSpace === SimulationSpace.WORLD) {\n particleSystem.matrixWorldAutoUpdate = false;\n particleSystem.matrixWorld.identity();\n } else {\n particleSystem.matrixWorldAutoUpdate = true;\n }\n instanceData.simulationSpace = cfg.simulationSpace;\n }\n if (partialConfig.emission !== undefined)\n instanceData.emission = cfg.emission;\n\n // Re-normalize force fields when changed\n if (partialConfig.forceFields !== undefined) {\n instanceData.normalizedForceFields = normalizeForceFields(\n cfg.forceFields\n );\n }\n\n // Re-normalize collision planes when changed\n if (partialConfig.collisionPlanes !== undefined) {\n instanceData.normalizedCollisionPlanes = normalizeCollisionPlanes(\n cfg.collisionPlanes\n );\n }\n\n // Re-initialize noise when changed\n if (partialConfig.noise !== undefined) {\n const n = cfg.noise;\n generalData.noise = {\n isActive: n.isActive,\n strength: n.strength,\n noisePower: 0.15 * n.strength,\n frequency: n.frequency,\n positionAmount: n.positionAmount,\n rotationAmount: n.rotationAmount,\n sizeAmount: n.sizeAmount,\n fbmMax: 2 - Math.pow(2, -n.octaves),\n sampler: n.isActive\n ? new FBM({\n seed: Math.random(),\n scale: n.frequency,\n octaves: n.octaves,\n })\n : undefined,\n offsets: n.useRandomOffset\n ? (generalData.noise.offsets ??\n Array.from({ length: maxParticles }, () => Math.random() * 100))\n : undefined,\n };\n }\n };\n\n return {\n instance: particleSystem,\n resumeEmitter,\n pauseEmitter,\n dispose,\n update,\n updateConfig,\n computeNode: gpuPipeline?.computeNode ?? null,\n };\n};\n\n/**\n * Updates all active particle systems created with {@link createParticleSystem}.\n *\n * This function must be called once per frame in your animation loop to animate all particles.\n * It handles particle emission, movement, lifetime tracking, modifier application, and cleanup\n * of expired particle systems.\n *\n * @param cycleData - Object containing timing information for the current frame:\n * - `now`: Current timestamp in milliseconds (typically from `performance.now()` or `Date.now()`)\n * - `delta`: Time elapsed since the last frame in seconds\n * - `elapsed`: Total time elapsed since the animation started in seconds\n *\n * @example\n * ```typescript\n * import { createParticleSystem, updateParticleSystems } from '@newkrok/three-particles';\n *\n * const { instance } = createParticleSystem({\n * // your config\n * });\n * scene.add(instance);\n *\n * // Animation loop\n * let lastTime = 0;\n * let elapsedTime = 0;\n *\n * function animate(currentTime) {\n * requestAnimationFrame(animate);\n *\n * const delta = (currentTime - lastTime) / 1000; // Convert to seconds\n * elapsedTime += delta;\n * lastTime = currentTime;\n *\n * // Update all particle systems\n * updateParticleSystems({\n * now: currentTime,\n * delta: delta,\n * elapsed: elapsedTime\n * });\n *\n * renderer.render(scene, camera);\n * }\n *\n * animate(0);\n * ```\n *\n * @example\n * ```typescript\n * // Using Three.js Clock for timing\n * import * as THREE from 'three';\n * import { updateParticleSystems } from '@newkrok/three-particles';\n *\n * const clock = new THREE.Clock();\n *\n * function animate() {\n * requestAnimationFrame(animate);\n *\n * const delta = clock.getDelta();\n * const elapsed = clock.getElapsedTime();\n *\n * updateParticleSystems({\n * now: performance.now(),\n * delta: delta,\n * elapsed: elapsed\n * });\n *\n * renderer.render(scene, camera);\n * }\n * ```\n *\n * @see {@link createParticleSystem} - Creates particle systems to be updated\n * @see {@link CycleData} - Timing data structure\n */\nconst updateParticleSystemInstance = (\n props: ParticleSystemInstance,\n { now, delta, elapsed }: CycleData\n) => {\n const {\n onUpdate,\n generalData,\n onComplete,\n particleSystem,\n elapsedUniform,\n creationTime,\n lastEmissionTime,\n duration,\n looping,\n emission,\n normalizedConfig,\n iterationCount,\n velocities,\n freeList,\n deactivateParticle,\n activateParticle,\n simulationSpace,\n gravity,\n normalizedForceFields,\n normalizedCollisionPlanes,\n onParticleDeath,\n onParticleBirth,\n mappedAttributes: ma,\n useGPUCompute,\n computePipeline,\n } = props;\n\n const hasForceFields = normalizedForceFields.length > 0;\n const hasCollisionPlanes = normalizedCollisionPlanes.length > 0;\n\n const lifetime = now - creationTime;\n const normalizedLifetime = lifetime % (duration * 1000);\n\n generalData.normalizedLifetimePercentage = Math.max(\n Math.min(normalizedLifetime / (duration * 1000), 1),\n 0\n );\n\n const {\n lastWorldPosition,\n currentWorldPosition,\n worldPositionChange,\n worldQuaternion,\n worldEuler,\n gravityVelocity,\n sourceWorldMatrix,\n isEnabled,\n } = generalData;\n\n _lastWorldPositionSnapshot.copy(lastWorldPosition);\n\n elapsedUniform.value = elapsed;\n\n // Emitter pose for this frame.\n //\n // WORLD: build sourceWorldMatrix explicitly (parent.matrixWorld × local).\n // The particle buffer stores world coordinates, so particleSystem's own\n // matrixWorld is held at identity (see matrixWorldAutoUpdate=false in\n // createParticleSystem). sourceWorldMatrix is used to place new\n // particles and orient the emission shape.\n //\n // LOCAL: standard Three.js — matrixWorld is fully parent-composed at\n // render time, particles live in the local frame, and emissions use\n // the identity quaternion (no rotation of the shape offset).\n if (simulationSpace === SimulationSpace.WORLD) {\n particleSystem.updateMatrix();\n if (particleSystem.parent) {\n particleSystem.parent.updateMatrixWorld();\n sourceWorldMatrix.multiplyMatrices(\n particleSystem.parent.matrixWorld,\n particleSystem.matrix\n );\n } else {\n sourceWorldMatrix.copy(particleSystem.matrix);\n }\n sourceWorldMatrix.decompose(\n currentWorldPosition,\n worldQuaternion,\n generalData.worldScale\n );\n generalData.wrapperQuaternion.copy(worldQuaternion);\n particleSystem.matrixWorld.identity();\n } else {\n particleSystem.updateMatrixWorld();\n particleSystem.getWorldPosition(currentWorldPosition);\n particleSystem.getWorldQuaternion(worldQuaternion);\n particleSystem.getWorldScale(generalData.worldScale);\n generalData.wrapperQuaternion.identity();\n }\n\n if (lastWorldPosition.x !== -99999) {\n worldPositionChange.set(\n currentWorldPosition.x - lastWorldPosition.x,\n currentWorldPosition.y - lastWorldPosition.y,\n currentWorldPosition.z - lastWorldPosition.z\n );\n } else {\n worldPositionChange.set(0, 0, 0);\n }\n if (isEnabled) {\n generalData.distanceFromLastEmitByDistance += worldPositionChange.length();\n }\n lastWorldPosition.copy(currentWorldPosition);\n worldEuler.setFromQuaternion(worldQuaternion);\n\n // Gravity is always -Y in world space (Unity semantics). In WORLD\n // simulation the buffer is world-space, so gravity is used directly.\n //\n // In LOCAL simulation the buffer is in the emitter's local frame, so\n // gravity is rotated by the inverse of the emitter's world rotation AND\n // divided by the emitter's world scale — this way the rendered fall\n // matches -g m/s² in world units, independent of how the emitter is\n // rotated or scaled by its parent chain.\n if (simulationSpace === SimulationSpace.WORLD) {\n gravityVelocity.set(0, gravity, 0);\n } else {\n gravityVelocity.set(0, gravity, 0);\n _inverseQuat.copy(worldQuaternion).invert();\n gravityVelocity.applyQuaternion(_inverseQuat);\n const sx = generalData.worldScale.x || 1;\n const sy = generalData.worldScale.y || 1;\n const sz = generalData.worldScale.z || 1;\n gravityVelocity.x /= sx;\n gravityVelocity.y /= sy;\n gravityVelocity.z /= sz;\n }\n\n // Force field positions/directions are user-authored in world space.\n //\n // WORLD simulation: buffer is already in world space — copy through.\n // LOCAL simulation: transform into the emitter's local frame so field\n // positions and directions match the particle buffer's frame.\n if (hasForceFields) {\n if (simulationSpace === SimulationSpace.LOCAL) {\n _inverseQuat.copy(worldQuaternion).invert();\n }\n\n _localForceFields.length = normalizedForceFields.length;\n\n for (let i = 0; i < normalizedForceFields.length; i++) {\n const src = normalizedForceFields[i];\n let dst = _localForceFields[i];\n if (!dst) {\n dst = {\n isActive: true,\n type: ForceFieldType.POINT,\n position: new THREE.Vector3(),\n direction: new THREE.Vector3(),\n strength: 0,\n range: 0,\n falloff: ForceFieldFalloff.LINEAR,\n };\n _localForceFields[i] = dst;\n }\n dst.isActive = src.isActive;\n dst.type = src.type;\n dst.strength = src.strength;\n dst.range = src.range;\n dst.falloff = src.falloff;\n\n if (simulationSpace === SimulationSpace.WORLD) {\n dst.position.copy(src.position);\n dst.direction.copy(src.direction);\n } else {\n _localForceFieldPos.copy(src.position);\n particleSystem.worldToLocal(_localForceFieldPos);\n dst.position.copy(_localForceFieldPos);\n\n _localForceFieldDir.copy(src.direction);\n _localForceFieldDir.applyQuaternion(_inverseQuat);\n dst.direction.copy(_localForceFieldDir);\n }\n }\n }\n\n // Collision plane positions/normals — same policy as force fields.\n if (hasCollisionPlanes) {\n if (simulationSpace === SimulationSpace.LOCAL && !hasForceFields) {\n _inverseQuat.copy(worldQuaternion).invert();\n }\n\n _localCollisionPlanes.length = normalizedCollisionPlanes.length;\n\n for (let i = 0; i < normalizedCollisionPlanes.length; i++) {\n const src = normalizedCollisionPlanes[i];\n let dst = _localCollisionPlanes[i];\n if (!dst) {\n dst = {\n isActive: true,\n position: new THREE.Vector3(),\n normal: new THREE.Vector3(),\n mode: CollisionPlaneMode.KILL,\n dampen: 0.5,\n lifetimeLoss: 0,\n };\n _localCollisionPlanes[i] = dst;\n }\n dst.isActive = src.isActive;\n dst.mode = src.mode;\n dst.dampen = src.dampen;\n dst.lifetimeLoss = src.lifetimeLoss;\n\n if (simulationSpace === SimulationSpace.WORLD) {\n dst.position.copy(src.position);\n dst.normal.copy(src.normal);\n } else {\n _localCollisionPlanePos.copy(src.position);\n particleSystem.worldToLocal(_localCollisionPlanePos);\n dst.position.copy(_localCollisionPlanePos);\n\n _localCollisionPlaneNormal.copy(src.normal);\n _localCollisionPlaneNormal.applyQuaternion(_inverseQuat);\n dst.normal.copy(_localCollisionPlaneNormal);\n }\n }\n }\n\n const creationTimes = generalData.creationTimes;\n const scalarArr = props.scalarArray;\n const positionArr = ma.position.array;\n const creationTimesLength = creationTimes.length;\n\n // ── GPU Compute Path ──────────────────────────────────────────────────\n // When GPU compute is active, all per-particle physics AND modifiers\n // (gravity, velocity, position, lifetime, size/opacity/color/rotation\n // over lifetime, noise, orbital velocity, force fields) run on the GPU\n // in a single compute dispatch. CPU still handles:\n // - Death detection for sub-emitter callbacks + freeList management\n // - Emission (particle activation, writing initial data to GPU buffers)\n if (useGPUCompute && computePipeline) {\n type ModifierComputePipeline =\n import('./webgpu/compute-modifiers.js').ModifierComputePipeline;\n const cp = computePipeline as ModifierComputePipeline;\n\n // Core physics uniforms\n setUniformFloat(cp.uniforms.delta, delta);\n setUniformFloat(cp.uniforms.deltaMs, delta * 1000);\n setUniformVec3(\n cp.uniforms.gravityVelocity,\n gravityVelocity.x,\n gravityVelocity.y,\n gravityVelocity.z\n );\n\n // Noise uniforms\n // GPU simplex noise output is not normalised by FBM's octave accumulator,\n // so we scale noisePower by the pre-computed divisor (fbmMax).\n const noiseData = generalData.noise;\n setUniformFloat(cp.uniforms.noiseStrength, noiseData.strength);\n setUniformFloat(\n cp.uniforms.noisePower,\n noiseData.noisePower / noiseData.fbmMax\n );\n setUniformFloat(cp.uniforms.noiseFrequency, noiseData.frequency);\n setUniformFloat(cp.uniforms.noisePositionAmount, noiseData.positionAmount);\n setUniformFloat(cp.uniforms.noiseRotationAmount, noiseData.rotationAmount);\n setUniformFloat(cp.uniforms.noiseSizeAmount, noiseData.sizeAmount);\n\n // Force-field and collision-plane uploads share the `curveData` storage\n // buffer with the per-particle init slots. A blanket `needsUpdate = true`\n // re-uploads the whole Float32Array, which stomps on init flags the\n // compute shader already cleared on the GPU side but are still `1` in\n // the CPU mirror (the `flushEmitQueue` logic only clears them a frame\n // later). We therefore use `addUpdateRange()` so the WebGPU backend\n // uploads just the force-field / collision-plane tail region, leaving\n // the init-slot region intact on the GPU. `flushEmitQueue` does the\n // same for its own region below.\n if (\n cp.forceFieldInfo &&\n hasForceFields &&\n _tslMaterialFactory?.encodeForceFieldsForGPU\n ) {\n const encodedFF = _tslMaterialFactory.encodeForceFieldsForGPU(\n _localForceFields,\n generalData.particleSystemId,\n generalData.normalizedLifetimePercentage\n );\n const curveArr = cp.buffers.curveData.array as Float32Array;\n const offset = cp.forceFieldInfo.offset;\n curveArr.set(encodedFF, offset);\n cp.buffers.curveData.addUpdateRange(offset, encodedFF.length);\n cp.buffers.curveData.needsUpdate = true;\n setUniformFloat(\n cp.forceFieldInfo.countUniform,\n normalizedForceFields.length\n );\n }\n\n if (\n cp.collisionPlaneInfo &&\n hasCollisionPlanes &&\n _tslMaterialFactory?.encodeCollisionPlanesForGPU\n ) {\n const encodedCP = _tslMaterialFactory.encodeCollisionPlanesForGPU(\n _localCollisionPlanes\n );\n const curveArr = cp.buffers.curveData.array as Float32Array;\n const offset = cp.collisionPlaneInfo.offset;\n curveArr.set(encodedCP, offset);\n cp.buffers.curveData.addUpdateRange(offset, encodedCP.length);\n cp.buffers.curveData.needsUpdate = true;\n setUniformFloat(\n cp.collisionPlaneInfo.countUniform,\n normalizedCollisionPlanes.length\n );\n }\n\n // Flush emit queue — uploads queued particle data to GPU and sets the\n // emit count uniform so the compute shader's scatter pass can initialise\n // newly emitted particles without overwriting existing GPU state.\n if (_tslMaterialFactory?.flushEmitQueue) {\n _tslMaterialFactory.flushEmitQueue(cp.buffers);\n }\n\n // Signal onBeforeRender to dispatch compute\n props.computeDispatchReady = true;\n\n // CPU-side death detection (for sub-emitter callbacks + freeList).\n // When death sub-emitters exist we also run a lightweight CPU shadow\n // simulation (velocity integration, gravity, orbital velocity, force\n // fields) so that positionArr contains an approximate current position\n // instead of the stale emission-time value — the GPU buffer is not\n // readable from the CPU without an async readback.\n for (let index = 0; index < creationTimesLength; index++) {\n const base = index * SCALAR_STRIDE;\n if (scalarArr[base + S_IS_ACTIVE]) {\n const particleLifetime = now - creationTimes[index];\n if (particleLifetime > scalarArr[base + S_START_LIFETIME]) {\n if (onParticleDeath)\n onParticleDeath(index, positionArr, velocities[index], now);\n deactivateParticle(index);\n } else if (onParticleDeath) {\n // Shadow simulation: keep CPU-side position in sync for sub-emitters.\n // We intentionally avoid calling applyModifiers() here because it\n // sets attributes.position.needsUpdate = true, which triggers a full\n // CPU→GPU upload that overwrites GPU-computed positions for ALL\n // particles. Instead we do the minimal physics inline without\n // touching needsUpdate.\n const velocity = velocities[index];\n velocity.x -= gravityVelocity.x * delta;\n velocity.y -= gravityVelocity.y * delta;\n velocity.z -= gravityVelocity.z * delta;\n\n if (hasForceFields) {\n applyForceFields({\n particleSystemId: generalData.particleSystemId,\n forceFields: _localForceFields,\n velocity,\n positionArr,\n positionIndex: index * 3,\n delta,\n systemLifetimePercentage:\n generalData.normalizedLifetimePercentage,\n });\n }\n\n const positionIndex = index * 3;\n positionArr[positionIndex] += velocity.x * delta;\n positionArr[positionIndex + 1] += velocity.y * delta;\n positionArr[positionIndex + 2] += velocity.z * delta;\n\n // Orbital velocity (mirrors CPU applyModifiers orbital logic)\n if (generalData.orbitalVelocityData) {\n const orbData = generalData.orbitalVelocityData[index];\n const { speed, positionOffset, valueModifiers } = orbData;\n const pctLife =\n particleLifetime / scalarArr[base + S_START_LIFETIME];\n\n positionArr[positionIndex] -= positionOffset.x;\n positionArr[positionIndex + 1] -= positionOffset.y;\n positionArr[positionIndex + 2] -= positionOffset.z;\n\n const sx = valueModifiers.x ? valueModifiers.x(pctLife) : speed.x;\n const sy = valueModifiers.y ? valueModifiers.y(pctLife) : speed.y;\n const sz = valueModifiers.z ? valueModifiers.z(pctLife) : speed.z;\n\n _shadowOrbitalEuler.set(sx * delta, sz * delta, sy * delta);\n positionOffset.applyEuler(_shadowOrbitalEuler);\n\n positionArr[positionIndex] += positionOffset.x;\n positionArr[positionIndex + 1] += positionOffset.y;\n positionArr[positionIndex + 2] += positionOffset.z;\n }\n\n // Collision planes (shadow sim — for KILL death detection only)\n if (hasCollisionPlanes) {\n applyCollisionPlanes({\n collisionPlanes: _localCollisionPlanes,\n velocity,\n positionArr,\n positionIndex,\n scalarArr,\n scalarBase: base,\n deactivateParticle: (pi: number) => {\n if (onParticleDeath)\n onParticleDeath(pi, positionArr, velocities[pi], now);\n deactivateParticle(pi);\n },\n particleIndex: index,\n });\n }\n }\n }\n }\n } else {\n // ── CPU Path ────────────────────────────────────────────────────────\n\n let positionNeedsUpdate = false;\n let scalarNeedsUpdate = false;\n\n _modifierParams.delta = delta;\n _modifierParams.generalData = generalData;\n _modifierParams.normalizedConfig = normalizedConfig;\n _modifierParams.attributes = ma;\n _modifierParams.scalarArray = scalarArr;\n\n for (let index = 0; index < creationTimesLength; index++) {\n const base = index * SCALAR_STRIDE;\n if (scalarArr[base + S_IS_ACTIVE]) {\n const particleLifetime = now - creationTimes[index];\n if (particleLifetime > scalarArr[base + S_START_LIFETIME]) {\n if (onParticleDeath)\n onParticleDeath(index, positionArr, velocities[index], now);\n deactivateParticle(index);\n } else {\n const velocity = velocities[index];\n velocity.x -= gravityVelocity.x * delta;\n velocity.y -= gravityVelocity.y * delta;\n velocity.z -= gravityVelocity.z * delta;\n\n if (hasForceFields) {\n applyForceFields({\n particleSystemId: generalData.particleSystemId,\n forceFields: _localForceFields,\n velocity,\n positionArr,\n positionIndex: index * 3,\n delta,\n systemLifetimePercentage:\n generalData.normalizedLifetimePercentage,\n });\n }\n\n if (\n gravity !== 0 ||\n velocity.x !== 0 ||\n velocity.y !== 0 ||\n velocity.z !== 0\n ) {\n const positionIndex = index * 3;\n\n positionArr[positionIndex] += velocity.x * delta;\n positionArr[positionIndex + 1] += velocity.y * delta;\n positionArr[positionIndex + 2] += velocity.z * delta;\n positionNeedsUpdate = true;\n }\n\n // Collision planes — after position update, before modifiers\n if (hasCollisionPlanes) {\n const killed = applyCollisionPlanes({\n collisionPlanes: _localCollisionPlanes,\n velocity,\n positionArr,\n positionIndex: index * 3,\n scalarArr,\n scalarBase: base,\n deactivateParticle: (pi: number) => {\n if (onParticleDeath)\n onParticleDeath(pi, positionArr, velocities[pi], now);\n deactivateParticle(pi);\n },\n particleIndex: index,\n });\n if (killed) {\n positionNeedsUpdate = true;\n continue;\n }\n }\n\n scalarArr[base + S_LIFETIME] = particleLifetime;\n scalarNeedsUpdate = true;\n\n _modifierParams.particleLifetimePercentage =\n particleLifetime / scalarArr[base + S_START_LIFETIME];\n _modifierParams.particleIndex = index;\n applyModifiers(_modifierParams);\n }\n }\n }\n\n if (positionNeedsUpdate) ma.position.needsUpdate = true;\n if (scalarNeedsUpdate) props.scalarInterleavedBuffer.needsUpdate = true;\n } // end of CPU/GPU compute branch\n\n if (isEnabled && (looping || lifetime < duration * 1000)) {\n const emissionDelta = now - lastEmissionTime;\n const neededParticlesByTime = emission.rateOverTime\n ? Math.floor(\n calculateValue(\n generalData.particleSystemId,\n emission.rateOverTime,\n generalData.normalizedLifetimePercentage\n ) *\n (emissionDelta / 1000)\n )\n : 0;\n\n const rateOverDistance = emission.rateOverDistance\n ? calculateValue(\n generalData.particleSystemId,\n emission.rateOverDistance,\n generalData.normalizedLifetimePercentage\n )\n : 0;\n const neededParticlesByDistance =\n rateOverDistance > 0 && generalData.distanceFromLastEmitByDistance > 0\n ? Math.floor(\n generalData.distanceFromLastEmitByDistance / (1 / rateOverDistance!)\n )\n : 0;\n const useDistanceStep = neededParticlesByDistance > 0;\n if (useDistanceStep) {\n _distanceStep.x =\n (currentWorldPosition.x - _lastWorldPositionSnapshot.x) /\n neededParticlesByDistance;\n _distanceStep.y =\n (currentWorldPosition.y - _lastWorldPositionSnapshot.y) /\n neededParticlesByDistance;\n _distanceStep.z =\n (currentWorldPosition.z - _lastWorldPositionSnapshot.z) /\n neededParticlesByDistance;\n }\n let neededParticles = neededParticlesByTime + neededParticlesByDistance;\n\n if (rateOverDistance > 0 && neededParticlesByDistance >= 1) {\n generalData.distanceFromLastEmitByDistance = 0;\n }\n\n // Process burst emissions\n if (emission.bursts && generalData.burstStates) {\n const bursts = emission.bursts;\n const burstStates = generalData.burstStates;\n const currentIterationTime = normalizedLifetime;\n\n for (let i = 0; i < bursts.length; i++) {\n const burst = bursts[i];\n const state = burstStates[i];\n const burstTimeMs = burst.time * 1000;\n const cycles = burst.cycles ?? 1;\n const intervalMs = (burst.interval ?? 0) * 1000;\n const probability = burst.probability ?? 1;\n\n // Check if we've looped and need to reset burst states\n if (\n looping &&\n currentIterationTime < burstTimeMs &&\n state.cyclesExecuted > 0\n ) {\n state.cyclesExecuted = 0;\n state.lastCycleTime = 0;\n state.probabilityPassed = false;\n }\n\n // Check if all cycles for this burst have been executed\n if (state.cyclesExecuted >= cycles) continue;\n\n // Calculate the time for the next cycle\n const nextCycleTime = burstTimeMs + state.cyclesExecuted * intervalMs;\n\n // Check if it's time for the next cycle\n if (currentIterationTime >= nextCycleTime) {\n // On first cycle, determine if probability check passes\n if (state.cyclesExecuted === 0) {\n state.probabilityPassed = Math.random() < probability;\n }\n\n // Only emit if probability check passed\n if (state.probabilityPassed) {\n const burstCount = Math.floor(\n calculateValue(\n generalData.particleSystemId,\n burst.count,\n generalData.normalizedLifetimePercentage\n )\n );\n neededParticles += burstCount;\n }\n\n state.cyclesExecuted++;\n state.lastCycleTime = currentIterationTime;\n }\n }\n }\n\n if (neededParticles > 0) {\n let generatedParticlesByDistanceNeeds = 0;\n\n for (let i = 0; i < neededParticles; i++) {\n if (freeList.length === 0) break;\n const particleIndex = freeList.pop()!;\n\n _tempPosition.x = 0;\n _tempPosition.y = 0;\n _tempPosition.z = 0;\n if (\n useDistanceStep &&\n generatedParticlesByDistanceNeeds < neededParticlesByDistance\n ) {\n _tempPosition.x = _distanceStep.x * generatedParticlesByDistanceNeeds;\n _tempPosition.y = _distanceStep.y * generatedParticlesByDistanceNeeds;\n _tempPosition.z = _distanceStep.z * generatedParticlesByDistanceNeeds;\n generatedParticlesByDistanceNeeds++;\n }\n activateParticle({\n particleIndex,\n activationTime: now,\n position: _tempPosition,\n });\n if (onParticleBirth)\n onParticleBirth(\n particleIndex,\n ma.position.array,\n velocities[particleIndex],\n now\n );\n props.lastEmissionTime = now;\n }\n }\n\n if (onUpdate)\n onUpdate({\n particleSystem,\n delta,\n elapsed,\n lifetime,\n normalizedLifetime,\n iterationCount: iterationCount + 1,\n });\n } else if (onComplete)\n onComplete({\n particleSystem,\n });\n\n // Trail geometry update: record position history and rebuild ribbon\n if (props.trailMesh) {\n updateTrailGeometry(props, now);\n }\n};\n\n/**\n * Evaluates a Catmull-Rom spline at parameter `t` (0..1) between points p1 and p2,\n * using p0 and p3 as control points. Writes result into `out`.\n */\nconst catmullRom = (\n out: Float32Array,\n outIdx: number,\n p0x: number,\n p0y: number,\n p0z: number,\n p1x: number,\n p1y: number,\n p1z: number,\n p2x: number,\n p2y: number,\n p2z: number,\n p3x: number,\n p3y: number,\n p3z: number,\n t: number\n) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[outIdx] =\n 0.5 *\n (2 * p1x +\n (-p0x + p2x) * t +\n (2 * p0x - 5 * p1x + 4 * p2x - p3x) * t2 +\n (-p0x + 3 * p1x - 3 * p2x + p3x) * t3);\n out[outIdx + 1] =\n 0.5 *\n (2 * p1y +\n (-p0y + p2y) * t +\n (2 * p0y - 5 * p1y + 4 * p2y - p3y) * t2 +\n (-p0y + 3 * p1y - 3 * p2y + p3y) * t3);\n out[outIdx + 2] =\n 0.5 *\n (2 * p1z +\n (-p0z + p2z) * t +\n (2 * p0z - 5 * p1z + 4 * p2z - p3z) * t2 +\n (-p0z + 3 * p1z - 3 * p2z + p3z) * t3);\n};\n\n/** Zeroes out a single trail vertex (both left+right sides). */\nconst clearTrailVertex = (\n vIdx: number,\n cIdx: number,\n aIdx: number,\n uvIdx: number,\n trailPosArr: Float32Array,\n trailNextArr: Float32Array,\n trailHalfWidthArr: Float32Array,\n trailUVArr: Float32Array,\n trailAlphaArr: Float32Array,\n trailColorArr: Float32Array,\n fallbackX: number,\n fallbackY: number,\n fallbackZ: number\n) => {\n trailPosArr[vIdx] = fallbackX;\n trailPosArr[vIdx + 1] = fallbackY;\n trailPosArr[vIdx + 2] = fallbackZ;\n trailPosArr[vIdx + 3] = fallbackX;\n trailPosArr[vIdx + 4] = fallbackY;\n trailPosArr[vIdx + 5] = fallbackZ;\n trailNextArr[vIdx] = fallbackX;\n trailNextArr[vIdx + 1] = fallbackY;\n trailNextArr[vIdx + 2] = fallbackZ;\n trailNextArr[vIdx + 3] = fallbackX;\n trailNextArr[vIdx + 4] = fallbackY;\n trailNextArr[vIdx + 5] = fallbackZ;\n trailHalfWidthArr[aIdx] = 0;\n trailHalfWidthArr[aIdx + 1] = 0;\n trailUVArr[uvIdx] = 0;\n trailUVArr[uvIdx + 1] = 0;\n trailUVArr[uvIdx + 2] = 0;\n trailUVArr[uvIdx + 3] = 0;\n trailAlphaArr[aIdx] = 0;\n trailAlphaArr[aIdx + 1] = 0;\n trailColorArr[cIdx] = 0;\n trailColorArr[cIdx + 1] = 0;\n trailColorArr[cIdx + 2] = 0;\n trailColorArr[cIdx + 3] = 0;\n trailColorArr[cIdx + 4] = 0;\n trailColorArr[cIdx + 5] = 0;\n trailColorArr[cIdx + 6] = 0;\n trailColorArr[cIdx + 7] = 0;\n};\n\n/**\n * Writes a single trail ribbon vertex pair (left+right) into the typed arrays.\n */\nconst writeTrailVertex = (\n vIdx: number,\n cIdx: number,\n aIdx: number,\n uvIdx: number,\n hx: number,\n hy: number,\n hz: number,\n nx: number,\n ny: number,\n nz: number,\n halfWidth: number,\n t: number,\n alpha: number,\n fr: number,\n fg: number,\n fb: number,\n ca: number,\n trailPosArr: Float32Array,\n trailNextArr: Float32Array,\n trailHalfWidthArr: Float32Array,\n trailUVArr: Float32Array,\n trailAlphaArr: Float32Array,\n trailColorArr: Float32Array\n) => {\n trailPosArr[vIdx] = hx;\n trailPosArr[vIdx + 1] = hy;\n trailPosArr[vIdx + 2] = hz;\n trailPosArr[vIdx + 3] = hx;\n trailPosArr[vIdx + 4] = hy;\n trailPosArr[vIdx + 5] = hz;\n trailNextArr[vIdx] = nx;\n trailNextArr[vIdx + 1] = ny;\n trailNextArr[vIdx + 2] = nz;\n trailNextArr[vIdx + 3] = nx;\n trailNextArr[vIdx + 4] = ny;\n trailNextArr[vIdx + 5] = nz;\n trailHalfWidthArr[aIdx] = halfWidth;\n trailHalfWidthArr[aIdx + 1] = halfWidth;\n trailUVArr[uvIdx] = 0;\n trailUVArr[uvIdx + 1] = t;\n trailUVArr[uvIdx + 2] = 1;\n trailUVArr[uvIdx + 3] = t;\n trailAlphaArr[aIdx] = alpha;\n trailAlphaArr[aIdx + 1] = alpha;\n trailColorArr[cIdx] = fr;\n trailColorArr[cIdx + 1] = fg;\n trailColorArr[cIdx + 2] = fb;\n trailColorArr[cIdx + 3] = ca;\n trailColorArr[cIdx + 4] = fr;\n trailColorArr[cIdx + 5] = fg;\n trailColorArr[cIdx + 6] = fb;\n trailColorArr[cIdx + 7] = ca;\n};\n\n// Scratch buffers reused each frame to avoid per-particle allocations\nlet _rawPoints: Float32Array | null = null;\nlet _rawPointsSize = 0;\nlet _smoothedPoints: Float32Array | null = null;\nlet _smoothedPointsSize = 0;\n// Scratch buffer for connected ribbon particle indices (reused each frame)\nlet _ribbonIndices: Uint16Array | null = null;\nlet _ribbonIndicesSize = 0;\nlet _ribbonCount = 0;\n\n/**\n * Records current particle positions into the history ring buffer,\n * then rebuilds the triangle-strip ribbon geometry for all active particles.\n *\n * Supports:\n * - Adaptive sampling (minVertexDistance): frame-rate independent trail density\n * - Max time (maxTime): time-based trail expiry\n * - Catmull-Rom smoothing: eliminates sharp kinks between samples\n * - Twist prevention: consistent ribbon orientation during rapid direction changes\n * - Connected ribbons (ribbonId): multiple particles forming a single ribbon\n */\nconst updateTrailGeometry = (props: ParticleSystemInstance, now: number) => {\n const {\n generalData,\n trailPositionAttr,\n trailAlphaAttr,\n trailColorAttr,\n trailNextAttr: trailNextAttrCached,\n trailHalfWidthAttr: trailHalfWidthAttrCached,\n trailUVAttr: trailUVAttrCached,\n trailWidthCurveFn,\n trailOpacityCurveFn,\n trailColorOverTrailFns,\n trailConfig,\n mappedAttributes: ma,\n } = props;\n\n if (\n !trailPositionAttr ||\n !trailAlphaAttr ||\n !trailColorAttr ||\n !trailNextAttrCached ||\n !trailHalfWidthAttrCached ||\n !trailUVAttrCached ||\n !trailWidthCurveFn ||\n !trailOpacityCurveFn ||\n !trailConfig ||\n !generalData.positionHistory ||\n !generalData.positionHistoryIndex ||\n !generalData.positionHistoryCount\n )\n return;\n\n const trailLength = trailConfig.length;\n const positionHistory = generalData.positionHistory;\n const historyIndex = generalData.positionHistoryIndex;\n const historyCount = generalData.positionHistoryCount;\n const sampleTimes = generalData.trailSampleTimes;\n const lastSampledPos = generalData.trailLastSampledPosition;\n const prevNormal = generalData.trailPrevNormal;\n const minVertexDist = trailConfig.minVertexDistance;\n const minVertexDistSq = minVertexDist * minVertexDist;\n const maxTime = trailConfig.maxTime;\n const maxTimeMs = maxTime * 1000;\n const useSmoothing = trailConfig.smoothing;\n const subdivisions = trailConfig.smoothingSubdivisions;\n const useTwistPrevention = trailConfig.twistPrevention;\n const ribbonId = trailConfig.ribbonId;\n\n const trailScalarArr = props.scalarArray;\n const positionArr = ma.position.array;\n\n const trailPosArr = trailPositionAttr.array as Float32Array;\n const trailAlphaArr = trailAlphaAttr.array as Float32Array;\n const trailColorArr = trailColorAttr.array as Float32Array;\n const trailNextArr = trailNextAttrCached.array as Float32Array;\n const trailUVArr = trailUVAttrCached.array as Float32Array;\n const trailHalfWidthArr = trailHalfWidthAttrCached.array as Float32Array;\n const verticesPerParticle = trailLength * 2;\n const creationTimesLength = generalData.creationTimes.length;\n let hasUpdates = false;\n\n // --- Connected Ribbons: collect particles sharing the same ribbonId ---\n const useRibbon = ribbonId !== undefined;\n let ribbonLeader = -1;\n if (useRibbon) {\n // Pre-allocate scratch buffer for ribbon indices\n if (!_ribbonIndices || _ribbonIndicesSize < creationTimesLength) {\n _ribbonIndices = new Uint16Array(creationTimesLength);\n _ribbonIndicesSize = creationTimesLength;\n }\n _ribbonCount = 0;\n for (let i = 0; i < creationTimesLength; i++) {\n if (trailScalarArr[i * SCALAR_STRIDE + S_IS_ACTIVE])\n _ribbonIndices[_ribbonCount++] = i;\n }\n // Insertion sort by creation time (typically nearly-sorted, O(n) best case)\n for (let i = 1; i < _ribbonCount; i++) {\n const key = _ribbonIndices[i];\n const keyTime = generalData.creationTimes[key];\n let j = i - 1;\n while (j >= 0 && generalData.creationTimes[_ribbonIndices[j]] > keyTime) {\n _ribbonIndices[j + 1] = _ribbonIndices[j];\n j--;\n }\n _ribbonIndices[j + 1] = key;\n }\n if (_ribbonCount > 0) ribbonLeader = _ribbonIndices[0];\n }\n\n for (let index = 0; index < creationTimesLength; index++) {\n const vertBase = index * verticesPerParticle;\n\n if (trailScalarArr[index * SCALAR_STRIDE + S_IS_ACTIVE]) {\n // Skip individual trail build for non-leader ribbon particles\n // (the leader's trail will be built by the connected ribbon section)\n if (useRibbon && _ribbonCount >= 2 && index !== ribbonLeader) {\n // Still record position history for this particle (needed for sampling)\n const posIdx = index * 3;\n const px = positionArr[posIdx];\n const py = positionArr[posIdx + 1];\n const pz = positionArr[posIdx + 2];\n const histBase = (index * trailLength + historyIndex[index]) * 3;\n positionHistory[histBase] = px;\n positionHistory[histBase + 1] = py;\n positionHistory[histBase + 2] = pz;\n if (sampleTimes) {\n sampleTimes[index * trailLength + historyIndex[index]] = now;\n }\n historyIndex[index] = (historyIndex[index] + 1) % trailLength;\n if (historyCount[index] < trailLength) historyCount[index]++;\n continue;\n }\n hasUpdates = true;\n const posIdx = index * 3;\n const px = positionArr[posIdx];\n const py = positionArr[posIdx + 1];\n const pz = positionArr[posIdx + 2];\n\n // --- Adaptive Sampling: only push a new sample if distance threshold met ---\n let shouldSample = true;\n if (minVertexDist > 0 && lastSampledPos && historyCount[index] > 0) {\n const lsIdx = index * 3;\n const dx = px - lastSampledPos[lsIdx];\n const dy = py - lastSampledPos[lsIdx + 1];\n const dz = pz - lastSampledPos[lsIdx + 2];\n if (dx * dx + dy * dy + dz * dz < minVertexDistSq) {\n shouldSample = false;\n }\n }\n\n if (shouldSample) {\n // Record the sample\n const histBase = (index * trailLength + historyIndex[index]) * 3;\n positionHistory[histBase] = px;\n positionHistory[histBase + 1] = py;\n positionHistory[histBase + 2] = pz;\n\n // Record timestamp for maxTime\n if (sampleTimes) {\n sampleTimes[index * trailLength + historyIndex[index]] = now;\n }\n\n historyIndex[index] = (historyIndex[index] + 1) % trailLength;\n if (historyCount[index] < trailLength) historyCount[index]++;\n\n // Update last sampled position\n if (lastSampledPos) {\n const lsIdx = index * 3;\n lastSampledPos[lsIdx] = px;\n lastSampledPos[lsIdx + 1] = py;\n lastSampledPos[lsIdx + 2] = pz;\n }\n }\n\n // --- MaxTime: determine effective count (expire old segments) ---\n let rawCount = historyCount[index];\n let effectiveCount = rawCount;\n if (maxTime > 0 && sampleTimes && rawCount > 0) {\n const sampleBase = index * trailLength;\n effectiveCount = 0;\n for (let s = 0; s < rawCount; s++) {\n const sampleSlot =\n (historyIndex[index] - 1 - s + trailLength * 2) % trailLength;\n const age = now - sampleTimes[sampleBase + sampleSlot];\n if (age <= maxTimeMs) {\n effectiveCount++;\n } else {\n break; // older samples are even older, stop\n }\n }\n }\n\n const count = effectiveCount;\n const ribbonWidth = trailConfig.width;\n\n // Get particle color from interleaved scalar buffer\n const trailBase = index * SCALAR_STRIDE;\n const cr = trailScalarArr[trailBase + S_COLOR_R];\n const cg = trailScalarArr[trailBase + S_COLOR_G];\n const cb = trailScalarArr[trailBase + S_COLOR_B];\n const ca = trailScalarArr[trailBase + S_COLOR_A];\n\n const ringOff = index * trailLength * 3;\n\n // --- Collect raw history points for this particle ---\n // We need them for both smoothing and the ribbon build.\n // rawPts: flat array of [x, y, z, x, y, z, ...] for count entries\n // rawPts[0..2] = head (most recent), rawPts[(count-1)*3..(count-1)*3+2] = tail\n const rawPtsSize = count * 3;\n // Reuse a scratch float array for raw points\n if (!_rawPoints || _rawPointsSize < rawPtsSize) {\n _rawPoints = new Float32Array(rawPtsSize);\n _rawPointsSize = rawPtsSize;\n }\n const rawPts = _rawPoints;\n for (let s = 0; s < count; s++) {\n const histSlot =\n ((historyIndex[index] - 1 - s + trailLength * 2) % trailLength) * 3 +\n ringOff;\n rawPts[s * 3] = positionHistory[histSlot];\n rawPts[s * 3 + 1] = positionHistory[histSlot + 1];\n rawPts[s * 3 + 2] = positionHistory[histSlot + 2];\n }\n\n // --- Catmull-Rom Smoothing ---\n let finalPts: Float32Array;\n let finalCount: number;\n\n if (useSmoothing && count >= 3) {\n // Interpolate between each pair of raw points with subdivisions\n const segmentCount = count - 1;\n finalCount = segmentCount * subdivisions + 1;\n const neededSize = finalCount * 3;\n\n // Resize global scratch buffer if needed\n if (!_smoothedPoints || _smoothedPointsSize < neededSize) {\n _smoothedPoints = new Float32Array(neededSize);\n _smoothedPointsSize = neededSize;\n }\n finalPts = _smoothedPoints;\n\n for (let seg = 0; seg < segmentCount; seg++) {\n // Control points: p0, p1, p2, p3\n const i0 = Math.max(0, seg - 1);\n const i1 = seg;\n const i2 = Math.min(count - 1, seg + 1);\n const i3 = Math.min(count - 1, seg + 2);\n\n const p0x = rawPts[i0 * 3],\n p0y = rawPts[i0 * 3 + 1],\n p0z = rawPts[i0 * 3 + 2];\n const p1x = rawPts[i1 * 3],\n p1y = rawPts[i1 * 3 + 1],\n p1z = rawPts[i1 * 3 + 2];\n const p2x = rawPts[i2 * 3],\n p2y = rawPts[i2 * 3 + 1],\n p2z = rawPts[i2 * 3 + 2];\n const p3x = rawPts[i3 * 3],\n p3y = rawPts[i3 * 3 + 1],\n p3z = rawPts[i3 * 3 + 2];\n\n for (let sub = 0; sub < subdivisions; sub++) {\n const t = sub / subdivisions;\n const outIdx = (seg * subdivisions + sub) * 3;\n catmullRom(\n finalPts,\n outIdx,\n p0x,\n p0y,\n p0z,\n p1x,\n p1y,\n p1z,\n p2x,\n p2y,\n p2z,\n p3x,\n p3y,\n p3z,\n t\n );\n }\n }\n // Last point = last raw point\n const lastOutIdx = (finalCount - 1) * 3;\n finalPts[lastOutIdx] = rawPts[(count - 1) * 3];\n finalPts[lastOutIdx + 1] = rawPts[(count - 1) * 3 + 1];\n finalPts[lastOutIdx + 2] = rawPts[(count - 1) * 3 + 2];\n } else {\n finalPts = rawPts;\n finalCount = count;\n }\n\n // Limit final count to the number of slots we can fill\n if (finalCount > trailLength) finalCount = trailLength;\n\n // Collapse degenerate segments: when two consecutive smoothed points are\n // nearly identical the shader tangent becomes zero, producing distorted\n // \"squished\" ribbon quads. Shift such points to the next distinct neighbor.\n if (useSmoothing && finalCount >= 2) {\n const MIN_SEG_DIST_SQ = 0.0001 * 0.0001;\n for (let d = 1; d < finalCount; d++) {\n const pi = (d - 1) * 3;\n const ci = d * 3;\n const dx = finalPts[ci] - finalPts[pi];\n const dy = finalPts[ci + 1] - finalPts[pi + 1];\n const dz = finalPts[ci + 2] - finalPts[pi + 2];\n if (dx * dx + dy * dy + dz * dz < MIN_SEG_DIST_SQ) {\n // Snap to previous point — the shader will get a near-zero tangent\n // but the vertex pair collapses to the same position, hiding it\n finalPts[ci] = finalPts[pi];\n finalPts[ci + 1] = finalPts[pi + 1];\n finalPts[ci + 2] = finalPts[pi + 2];\n }\n }\n }\n\n // --- Build ribbon vertices ---\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (vertBase + s * 2) * 3;\n const cIdx = (vertBase + s * 2) * 4;\n const aIdx = vertBase + s * 2;\n const uvIdxBase = (vertBase + s * 2) * 2;\n\n if (s >= finalCount) {\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n px,\n py,\n pz\n );\n continue;\n }\n\n const hx = finalPts[s * 3];\n const hy = finalPts[s * 3 + 1];\n const hz = finalPts[s * 3 + 2];\n\n // Compute an averaged tangent direction for the shader.\n // At interior points we average the forward and backward segment\n // directions so the billboard plane transitions smoothly through\n // bends instead of snapping per-segment.\n let nx: number, ny: number, nz: number;\n if (s > 0 && s < finalCount - 1) {\n // Interior: average of (prev→current) and (current→next)\n const px2 = finalPts[(s - 1) * 3];\n const py2 = finalPts[(s - 1) * 3 + 1];\n const pz2 = finalPts[(s - 1) * 3 + 2];\n const nx2 = finalPts[(s + 1) * 3];\n const ny2 = finalPts[(s + 1) * 3 + 1];\n const nz2 = finalPts[(s + 1) * 3 + 2];\n // Averaged tangent = (current - prev) + (next - current) = next - prev\n const atx = nx2 - px2;\n const aty = ny2 - py2;\n const atz = nz2 - pz2;\n const atLen = Math.sqrt(atx * atx + aty * aty + atz * atz);\n if (atLen > 0.0001) {\n // trailNext = current + normalized averaged tangent (shader computes tangent as trailNext - position)\n nx = hx + atx / atLen;\n ny = hy + aty / atLen;\n nz = hz + atz / atLen;\n } else {\n nx = finalPts[(s + 1) * 3];\n ny = finalPts[(s + 1) * 3 + 1];\n nz = finalPts[(s + 1) * 3 + 2];\n }\n } else if (s < finalCount - 1) {\n // Head: use forward direction\n nx = finalPts[(s + 1) * 3];\n ny = finalPts[(s + 1) * 3 + 1];\n nz = finalPts[(s + 1) * 3 + 2];\n } else if (finalCount >= 2) {\n // Tail: reuse the direction from the previous segment so the\n // ribbon end keeps the same orientation as the last real segment\n // instead of collapsing when the tangent aligns with the Y axis.\n const prevX = finalPts[(s - 1) * 3];\n const prevY = finalPts[(s - 1) * 3 + 1];\n const prevZ = finalPts[(s - 1) * 3 + 2];\n nx = hx + (hx - prevX);\n ny = hy + (hy - prevY);\n nz = hz + (hz - prevZ);\n } else {\n // Single point: nudge to avoid zero tangent\n nx = hx;\n ny = hy + 0.001;\n nz = hz;\n }\n\n // Trail percentage (0=head, 1=tail)\n const t = finalCount > 1 ? s / (finalCount - 1) : 0;\n\n // --- MaxTime: apply additional age-based fade ---\n let timeFade = 1.0;\n if (maxTime > 0 && sampleTimes && effectiveCount > 0) {\n // Map the current smoothed vertex back to the raw sample timeline.\n // When smoothing is active we interpolate between the two bracketing\n // raw samples' timestamps so the fade is smooth instead of stepping.\n const sampleBase = index * trailLength;\n if (useSmoothing && rawCount >= 2) {\n const rawF = (s / Math.max(finalCount - 1, 1)) * (rawCount - 1);\n const rawLo = Math.min(Math.floor(rawF), rawCount - 1);\n const rawHi = Math.min(rawLo + 1, rawCount - 1);\n const frac = rawF - rawLo;\n const slotLo =\n (historyIndex[index] - 1 - rawLo + trailLength * 2) % trailLength;\n const slotHi =\n (historyIndex[index] - 1 - rawHi + trailLength * 2) % trailLength;\n const ageLo = now - sampleTimes[sampleBase + slotLo];\n const ageHi = now - sampleTimes[sampleBase + slotHi];\n const age = ageLo + (ageHi - ageLo) * frac;\n timeFade = 1.0 - Math.min(age / maxTimeMs, 1.0);\n } else {\n const rawS = Math.min(s, rawCount - 1);\n const sampleSlot =\n (historyIndex[index] - 1 - rawS + trailLength * 2) % trailLength;\n const age = now - sampleTimes[sampleBase + sampleSlot];\n timeFade = 1.0 - Math.min(age / maxTimeMs, 1.0);\n }\n }\n\n const widthScale = trailWidthCurveFn(t);\n const opacityScale = trailOpacityCurveFn(t);\n const halfWidth = ribbonWidth * widthScale * 0.5;\n const alpha = ca * opacityScale * timeFade;\n\n const fr = trailColorOverTrailFns\n ? cr * trailColorOverTrailFns.r(t)\n : cr;\n const fg = trailColorOverTrailFns\n ? cg * trailColorOverTrailFns.g(t)\n : cg;\n const fb = trailColorOverTrailFns\n ? cb * trailColorOverTrailFns.b(t)\n : cb;\n\n writeTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n hx,\n hy,\n hz,\n nx,\n ny,\n nz,\n halfWidth,\n t,\n alpha,\n fr,\n fg,\n fb,\n ca,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr\n );\n }\n\n // --- Twist Prevention ---\n // After building the ribbon, ensure ribbon normals are consistent.\n // We compare the implied normal direction of consecutive segments and\n // flip if the dot product with the previous frame's normal is negative.\n if (useTwistPrevention && prevNormal && finalCount >= 2) {\n const nIdx = index * 3;\n // Compute current head tangent\n const tx = finalPts[3] - finalPts[0];\n const ty = finalPts[4] - finalPts[1];\n const tz = finalPts[5] - finalPts[2];\n const tLen = Math.sqrt(tx * tx + ty * ty + tz * tz);\n if (tLen > 0.0001) {\n const ntx = tx / tLen;\n const nty = ty / tLen;\n const ntz = tz / tLen;\n // Use a consistent up vector to compute a reference normal\n let upx = 0,\n upy = 1,\n upz = 0;\n const dot = ntx * upx + nty * upy + ntz * upz;\n if (Math.abs(dot) > 0.999) {\n upx = 1;\n upy = 0;\n upz = 0;\n }\n // cross(tangent, up) = normal\n let cnx = nty * upz - ntz * upy;\n let cny = ntz * upx - ntx * upz;\n let cnz = ntx * upy - nty * upx;\n const cnLen = Math.sqrt(cnx * cnx + cny * cny + cnz * cnz);\n if (cnLen > 0.0001) {\n cnx /= cnLen;\n cny /= cnLen;\n cnz /= cnLen;\n }\n\n // Check dot product with previous normal — if negative, flip\n const prevNx = prevNormal[nIdx];\n const prevNy = prevNormal[nIdx + 1];\n const prevNz = prevNormal[nIdx + 2];\n const hasPrev = prevNx !== 0 || prevNy !== 0 || prevNz !== 0;\n if (hasPrev) {\n const normalDot = cnx * prevNx + cny * prevNy + cnz * prevNz;\n if (normalDot < 0) {\n // Flip all ribbon offsets for this particle by swapping left/right half-widths\n for (let s = 0; s < Math.min(finalCount, trailLength); s++) {\n const aIdx = vertBase + s * 2;\n const hw = trailHalfWidthArr[aIdx];\n trailHalfWidthArr[aIdx] = -hw;\n trailHalfWidthArr[aIdx + 1] = -hw;\n }\n // Also flip the stored normal for next frame\n cnx = -cnx;\n cny = -cny;\n cnz = -cnz;\n }\n }\n\n // Store current normal for next frame\n prevNormal[nIdx] = cnx;\n prevNormal[nIdx + 1] = cny;\n prevNormal[nIdx + 2] = cnz;\n }\n }\n } else if (historyCount[index] > 0) {\n // Particle just became inactive — collapse ribbon and clear history once\n hasUpdates = true;\n historyCount[index] = 0;\n historyIndex[index] = 0;\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (vertBase + s * 2) * 3;\n const cIdx = (vertBase + s * 2) * 4;\n const aIdx = vertBase + s * 2;\n const uvIdxBase = (vertBase + s * 2) * 2;\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n 0,\n 0,\n 0\n );\n }\n }\n }\n\n // --- Connected Ribbons: chain particle positions with Catmull-Rom interpolation ---\n if (useRibbon && _ribbonCount >= 2 && _ribbonIndices) {\n hasUpdates = true;\n const leader = _ribbonIndices[0];\n const leaderVertBase = leader * verticesPerParticle;\n\n // The ribbon uses each particle's current position as a control point,\n // then fills `trailLength` vertices by Catmull-Rom interpolation between them.\n // This produces a smooth, continuous ribbon through all particle positions.\n const controlCount = _ribbonCount;\n const filledCount = Math.min(\n trailLength,\n Math.max(controlCount * 4, controlCount)\n );\n const chainSize = filledCount * 3;\n if (!_rawPoints || _rawPointsSize < chainSize) {\n _rawPoints = new Float32Array(chainSize);\n _rawPointsSize = chainSize;\n }\n\n if (controlCount === 2) {\n // Only 2 particles: linearly interpolate between them\n const p0Idx = _ribbonIndices[0] * 3;\n const p1Idx = _ribbonIndices[1] * 3;\n for (let i = 0; i < filledCount; i++) {\n const t = i / (filledCount - 1);\n _rawPoints[i * 3] =\n positionArr[p0Idx] + t * (positionArr[p1Idx] - positionArr[p0Idx]);\n _rawPoints[i * 3 + 1] =\n positionArr[p0Idx + 1] +\n t * (positionArr[p1Idx + 1] - positionArr[p0Idx + 1]);\n _rawPoints[i * 3 + 2] =\n positionArr[p0Idx + 2] +\n t * (positionArr[p1Idx + 2] - positionArr[p0Idx + 2]);\n }\n } else {\n // 3+ particles: Catmull-Rom interpolation through all control points\n const segments = controlCount - 1;\n const ptsPerSeg = Math.max(1, Math.floor((filledCount - 1) / segments));\n let wi = 0;\n for (let seg = 0; seg < segments && wi < filledCount; seg++) {\n const i0 = Math.max(0, seg - 1);\n const i1 = seg;\n const i2 = Math.min(controlCount - 1, seg + 1);\n const i3 = Math.min(controlCount - 1, seg + 2);\n const p0i = _ribbonIndices[i0] * 3;\n const p1i = _ribbonIndices[i1] * 3;\n const p2i = _ribbonIndices[i2] * 3;\n const p3i = _ribbonIndices[i3] * 3;\n const subCount = seg === segments - 1 ? filledCount - wi : ptsPerSeg;\n for (let sub = 0; sub < subCount && wi < filledCount; sub++) {\n const t = sub / subCount;\n catmullRom(\n _rawPoints,\n wi * 3,\n positionArr[p0i],\n positionArr[p0i + 1],\n positionArr[p0i + 2],\n positionArr[p1i],\n positionArr[p1i + 1],\n positionArr[p1i + 2],\n positionArr[p2i],\n positionArr[p2i + 1],\n positionArr[p2i + 2],\n positionArr[p3i],\n positionArr[p3i + 1],\n positionArr[p3i + 2],\n t\n );\n wi++;\n }\n }\n // Ensure last point is the last particle's position\n if (wi > 0) {\n const lastPIdx = _ribbonIndices[controlCount - 1] * 3;\n _rawPoints[(wi - 1) * 3] = positionArr[lastPIdx];\n _rawPoints[(wi - 1) * 3 + 1] = positionArr[lastPIdx + 1];\n _rawPoints[(wi - 1) * 3 + 2] = positionArr[lastPIdx + 2];\n }\n }\n\n const leaderBase = leader * SCALAR_STRIDE;\n const leaderCr = trailScalarArr[leaderBase + S_COLOR_R];\n const leaderCg = trailScalarArr[leaderBase + S_COLOR_G];\n const leaderCb = trailScalarArr[leaderBase + S_COLOR_B];\n const leaderCa = trailScalarArr[leaderBase + S_COLOR_A];\n\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (leaderVertBase + s * 2) * 3;\n const cIdx = (leaderVertBase + s * 2) * 4;\n const aIdx = leaderVertBase + s * 2;\n const uvIdxBase = (leaderVertBase + s * 2) * 2;\n\n if (s >= filledCount) {\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n 0,\n 0,\n 0\n );\n continue;\n }\n\n const ptIdx = s * 3;\n const ptx = _rawPoints[ptIdx];\n const pty = _rawPoints[ptIdx + 1];\n const ptz = _rawPoints[ptIdx + 2];\n\n // Averaged tangent for interior points\n let nx: number, ny: number, nz: number;\n if (s > 0 && s < filledCount - 1) {\n const px2 = _rawPoints[(s - 1) * 3];\n const py2 = _rawPoints[(s - 1) * 3 + 1];\n const pz2 = _rawPoints[(s - 1) * 3 + 2];\n const nx2 = _rawPoints[(s + 1) * 3];\n const ny2 = _rawPoints[(s + 1) * 3 + 1];\n const nz2 = _rawPoints[(s + 1) * 3 + 2];\n const atx = nx2 - px2;\n const aty = ny2 - py2;\n const atz = nz2 - pz2;\n const atLen = Math.sqrt(atx * atx + aty * aty + atz * atz);\n if (atLen > 0.0001) {\n nx = ptx + atx / atLen;\n ny = pty + aty / atLen;\n nz = ptz + atz / atLen;\n } else {\n nx = _rawPoints[(s + 1) * 3];\n ny = _rawPoints[(s + 1) * 3 + 1];\n nz = _rawPoints[(s + 1) * 3 + 2];\n }\n } else if (s < filledCount - 1) {\n nx = _rawPoints[(s + 1) * 3];\n ny = _rawPoints[(s + 1) * 3 + 1];\n nz = _rawPoints[(s + 1) * 3 + 2];\n } else if (filledCount >= 2) {\n // Tail: reuse previous segment direction\n const prevX = _rawPoints[(s - 1) * 3];\n const prevY = _rawPoints[(s - 1) * 3 + 1];\n const prevZ = _rawPoints[(s - 1) * 3 + 2];\n nx = ptx + (ptx - prevX);\n ny = pty + (pty - prevY);\n nz = ptz + (ptz - prevZ);\n } else {\n nx = ptx;\n ny = pty + 0.001;\n nz = ptz;\n }\n\n const t = filledCount > 1 ? s / (filledCount - 1) : 0;\n\n // --- MaxTime: apply age-based fade to connected ribbon ---\n let ribbonTimeFade = 1.0;\n if (maxTime > 0 && controlCount >= 2) {\n // Map the vertex to the nearest control point(s) and use\n // their creation times to compute an interpolated age.\n const ctrlF = t * (controlCount - 1);\n const ctrlLo = Math.min(Math.floor(ctrlF), controlCount - 1);\n const ctrlHi = Math.min(ctrlLo + 1, controlCount - 1);\n const frac = ctrlF - ctrlLo;\n const ageLo = now - generalData.creationTimes[_ribbonIndices[ctrlLo]];\n const ageHi = now - generalData.creationTimes[_ribbonIndices[ctrlHi]];\n const age = ageLo + (ageHi - ageLo) * frac;\n ribbonTimeFade = 1.0 - Math.min(age / maxTimeMs, 1.0);\n }\n\n const widthScale = trailWidthCurveFn(t);\n const opacityScale = trailOpacityCurveFn(t);\n const halfWidth = trailConfig.width * widthScale * 0.5;\n const alpha = leaderCa * opacityScale * ribbonTimeFade;\n const fr = trailColorOverTrailFns\n ? leaderCr * trailColorOverTrailFns.r(t)\n : leaderCr;\n const fg = trailColorOverTrailFns\n ? leaderCg * trailColorOverTrailFns.g(t)\n : leaderCg;\n const fb = trailColorOverTrailFns\n ? leaderCb * trailColorOverTrailFns.b(t)\n : leaderCb;\n\n writeTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n ptx,\n pty,\n ptz,\n nx,\n ny,\n nz,\n halfWidth,\n t,\n alpha,\n fr,\n fg,\n fb,\n leaderCa,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr\n );\n }\n\n // --- Twist Prevention for connected ribbon (applied to leader) ---\n if (useTwistPrevention && prevNormal && filledCount >= 2) {\n const nIdx = leader * 3;\n const tx = _rawPoints[3] - _rawPoints[0];\n const ty = _rawPoints[4] - _rawPoints[1];\n const tz = _rawPoints[5] - _rawPoints[2];\n const tLen = Math.sqrt(tx * tx + ty * ty + tz * tz);\n if (tLen > 0.0001) {\n const ntx = tx / tLen;\n const nty = ty / tLen;\n const ntz = tz / tLen;\n let upx = 0,\n upy = 1,\n upz = 0;\n const dot = ntx * upx + nty * upy + ntz * upz;\n if (Math.abs(dot) > 0.999) {\n upx = 1;\n upy = 0;\n upz = 0;\n }\n let cnx = nty * upz - ntz * upy;\n let cny = ntz * upx - ntx * upz;\n let cnz = ntx * upy - nty * upx;\n const cnLen = Math.sqrt(cnx * cnx + cny * cny + cnz * cnz);\n if (cnLen > 0.0001) {\n cnx /= cnLen;\n cny /= cnLen;\n cnz /= cnLen;\n }\n const prevNx = prevNormal[nIdx];\n const prevNy = prevNormal[nIdx + 1];\n const prevNz = prevNormal[nIdx + 2];\n const hasPrev = prevNx !== 0 || prevNy !== 0 || prevNz !== 0;\n if (hasPrev) {\n const normalDot = cnx * prevNx + cny * prevNy + cnz * prevNz;\n if (normalDot < 0) {\n for (let s = 0; s < Math.min(filledCount, trailLength); s++) {\n const aIdx = leaderVertBase + s * 2;\n const hw = trailHalfWidthArr[aIdx];\n trailHalfWidthArr[aIdx] = -hw;\n trailHalfWidthArr[aIdx + 1] = -hw;\n }\n cnx = -cnx;\n cny = -cny;\n cnz = -cnz;\n }\n }\n prevNormal[nIdx] = cnx;\n prevNormal[nIdx + 1] = cny;\n prevNormal[nIdx + 2] = cnz;\n }\n }\n\n // Clear non-leader ribbon particles' trail vertices\n for (let ri = 1; ri < _ribbonCount; ri++) {\n const pIdx = _ribbonIndices[ri];\n const pVertBase = pIdx * verticesPerParticle;\n for (let s = 0; s < trailLength; s++) {\n const vIdx = (pVertBase + s * 2) * 3;\n const cIdx = (pVertBase + s * 2) * 4;\n const aIdx = pVertBase + s * 2;\n const uvIdxBase = (pVertBase + s * 2) * 2;\n clearTrailVertex(\n vIdx,\n cIdx,\n aIdx,\n uvIdxBase,\n trailPosArr,\n trailNextArr,\n trailHalfWidthArr,\n trailUVArr,\n trailAlphaArr,\n trailColorArr,\n 0,\n 0,\n 0\n );\n }\n }\n }\n\n if (hasUpdates) {\n trailPositionAttr.needsUpdate = true;\n trailAlphaAttr.needsUpdate = true;\n trailColorAttr.needsUpdate = true;\n trailNextAttrCached.needsUpdate = true;\n trailHalfWidthAttrCached.needsUpdate = true;\n trailUVAttrCached.needsUpdate = true;\n }\n};\n\nexport const updateParticleSystems = (cycleData: CycleData) => {\n createdParticleSystems.forEach((props) =>\n updateParticleSystemInstance(props, cycleData)\n );\n};\n","import * as THREE from 'three';\nimport {\n CurveFunctionId,\n curveFunctionIdMap,\n getCurveFunction,\n} from './three-particles-curves.js';\nimport {\n CollisionPlaneMode,\n ForceFieldFalloff,\n ForceFieldType,\n LifeTimeCurve,\n} from './three-particles-enums.js';\nimport { blendingMap } from './three-particles.js';\nimport type {\n BezierCurve,\n CollisionPlaneConfig,\n CurveFunction,\n EasingCurve,\n ForceFieldConfig,\n LifetimeCurve,\n ParticleSystemConfig,\n} from './types.js';\n\n/** Current serialization format version */\nconst SERIALIZATION_VERSION = 1;\n\ntype BlendingKey = keyof typeof blendingMap;\ntype RawObject = Record<string, unknown>;\n\n// Reverse blending map: THREE.Blending number → string key\nconst reverseBlendingMap = new Map<number, BlendingKey>(\n (Object.entries(blendingMap) as [BlendingKey, number][]).map(([k, v]) => [\n v,\n k,\n ])\n);\n\n// Reverse curve function map: function reference → CurveFunctionId string\nconst reverseCurveFunctionMap = new Map<CurveFunction, string>();\nfor (const [id, fn] of Object.entries(curveFunctionIdMap) as [\n string,\n CurveFunction,\n][]) {\n if (fn) reverseCurveFunctionMap.set(fn, id);\n}\n\n// ─── SERIALIZATION ───────────────────────────────────────────────────────────\n\nfunction serializeAny(value: unknown, key?: string): unknown {\n if (value === null || value === undefined) return value;\n if (value instanceof THREE.Vector3)\n return { x: value.x, y: value.y, z: value.z };\n if (value instanceof THREE.Vector2) return { x: value.x, y: value.y };\n if (value instanceof THREE.Texture) return undefined;\n if (typeof value === 'function') return undefined;\n if (Array.isArray(value)) return value.map((item) => serializeAny(item));\n if (typeof value === 'object') {\n const obj = value as RawObject;\n\n // EasingCurve: replace curveFunction with curveFunctionId\n if (\n obj['type'] === LifeTimeCurve.EASING &&\n typeof obj['curveFunction'] === 'function'\n ) {\n const id = reverseCurveFunctionMap.get(\n obj['curveFunction'] as CurveFunction\n );\n if (!id) {\n throw new Error(\n 'Cannot serialize a custom curveFunction. Use a predefined CurveFunctionId instead.'\n );\n }\n return {\n type: LifeTimeCurve.EASING,\n curveFunctionId: id,\n ...(obj['scale'] !== undefined ? { scale: obj['scale'] } : {}),\n };\n }\n\n const result: RawObject = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k === 'onUpdate' || k === 'onComplete') continue;\n if (k === 'blending' && typeof v === 'number') {\n result[k] = reverseBlendingMap.get(v as THREE.Blending) ?? v;\n continue;\n }\n const serialized = serializeAny(v, k);\n if (serialized !== undefined) result[k] = serialized;\n }\n return result;\n }\n return value;\n}\n\n/**\n * Serializes a `ParticleSystemConfig` to a JSON string.\n *\n * - `THREE.Vector3` / `THREE.Vector2` are converted to plain `{x, y, z}` / `{x, y}` objects.\n * - `renderer.blending` is converted to its string identifier (e.g. `\"THREE.AdditiveBlending\"`).\n * - `EasingCurve.curveFunction` is replaced by a `curveFunctionId` string.\n * Only predefined `CurveFunctionId` functions can be serialized; custom functions throw.\n * - `THREE.Texture` (`map`), callback fields (`onUpdate`, `onComplete`) are omitted.\n * - An `_editorData` field and other unknown fields are preserved as-is.\n * - A `_version` field is added for forward-compatibility.\n *\n * @param config - The particle system configuration to serialize.\n * @returns A JSON string representation of the config.\n * @throws If the config contains a custom (non-predefined) `curveFunction`.\n *\n * @example\n * ```typescript\n * import { serializeParticleSystem } from '@newkrok/three-particles';\n *\n * const json = serializeParticleSystem(config);\n * localStorage.setItem('myEffect', json);\n * ```\n */\nexport function serializeParticleSystem(config: ParticleSystemConfig): string {\n const serialized = serializeAny(config) as RawObject;\n return JSON.stringify({ _version: SERIALIZATION_VERSION, ...serialized });\n}\n\n// ─── DESERIALIZATION ──────────────────────────────────────────────────────────\n\n/**\n * Reconstructs a `LifetimeCurve` from its serialized form.\n * Handles:\n * - Legacy editor format: `{ bezierPoints: [...] }` (no `type` field → treated as BEZIER)\n * - Normal BEZIER: `{ type: \"BEZIER\", bezierPoints: [...] }`\n * - Serialized EASING: `{ type: \"EASING\", curveFunctionId: \"...\" }`\n */\nfunction deserializeCurve(raw: unknown): LifetimeCurve {\n const obj = raw as RawObject;\n\n // Legacy format from editor: bezierPoints present but no type\n if (Array.isArray(obj['bezierPoints']) && !obj['type']) {\n return { type: LifeTimeCurve.BEZIER, ...obj } as BezierCurve;\n }\n\n if (obj['type'] === LifeTimeCurve.EASING) {\n const id = obj['curveFunctionId'] as CurveFunctionId;\n const fn = getCurveFunction(id);\n if (!fn) {\n throw new Error(\n `Unknown curveFunctionId: \"${id}\". Use a value from CurveFunctionId.`\n );\n }\n const curve: EasingCurve = {\n type: LifeTimeCurve.EASING,\n curveFunction: fn,\n };\n if (obj['scale'] !== undefined) curve.scale = obj['scale'] as number;\n return curve;\n }\n\n // BEZIER (explicit type) or passthrough\n return obj as BezierCurve;\n}\n\n/**\n * Deserializes a value that can be `Constant | RandomBetweenTwoConstants | LifetimeCurve`.\n * Numbers pass through; objects are inspected for curve shape.\n */\nfunction deserializeCurveOrValue(\n value: unknown\n): number | Record<string, unknown> | LifetimeCurve | undefined {\n if (typeof value === 'number') return value;\n if (!value || typeof value !== 'object') return value as undefined;\n const obj = value as RawObject;\n const looksLikeCurve =\n Array.isArray(obj['bezierPoints']) ||\n obj['type'] === LifeTimeCurve.BEZIER ||\n obj['type'] === LifeTimeCurve.EASING ||\n typeof obj['curveFunctionId'] === 'string';\n if (looksLikeCurve) return deserializeCurve(obj);\n return obj; // RandomBetweenTwoConstants or other plain object\n}\n\nfunction deserializeVector3(raw: unknown): THREE.Vector3 | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const { x = 0, y = 0, z = 0 } = raw as { x?: number; y?: number; z?: number };\n return new THREE.Vector3(x, y, z);\n}\n\nfunction deserializeVector2(raw: unknown): THREE.Vector2 | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const { x = 1, y = 1 } = raw as { x?: number; y?: number };\n return new THREE.Vector2(x, y);\n}\n\nfunction deserializeConfig(raw: RawObject): ParticleSystemConfig {\n const config: ParticleSystemConfig = {};\n\n // transform\n if (raw['transform'] && typeof raw['transform'] === 'object') {\n const t = raw['transform'] as RawObject;\n config.transform = {\n position: deserializeVector3(t['position']),\n rotation: deserializeVector3(t['rotation']),\n scale: deserializeVector3(t['scale']),\n };\n }\n\n // scalar / enum fields (pass through)\n for (const field of [\n 'duration',\n 'looping',\n 'gravity',\n 'simulationSpace',\n 'simulationBackend',\n 'maxParticles',\n ] as const) {\n if (field in raw) (config as RawObject)[field] = raw[field];\n }\n\n // start value fields (Constant | RandomBetweenTwoConstants | LifetimeCurve)\n for (const field of [\n 'startDelay',\n 'startLifetime',\n 'startSpeed',\n 'startSize',\n 'startOpacity',\n 'startRotation',\n ] as const) {\n if (field in raw)\n (config as RawObject)[field] = deserializeCurveOrValue(raw[field]);\n }\n\n // startColor (plain MinMaxColor — no reconstruction needed)\n if ('startColor' in raw)\n config.startColor = raw['startColor'] as ParticleSystemConfig['startColor'];\n\n // emission\n if (raw['emission'] && typeof raw['emission'] === 'object') {\n const e = raw['emission'] as RawObject;\n config.emission = {\n rateOverTime: deserializeCurveOrValue(e['rateOverTime']) as NonNullable<\n ParticleSystemConfig['emission']\n >['rateOverTime'],\n rateOverDistance: deserializeCurveOrValue(\n e['rateOverDistance']\n ) as NonNullable<ParticleSystemConfig['emission']>['rateOverDistance'],\n bursts: Array.isArray(e['bursts'])\n ? (e['bursts'] as NonNullable<\n ParticleSystemConfig['emission']\n >['bursts'])\n : [],\n };\n }\n\n // shape (plain object with enum string values — no reconstruction needed)\n if ('shape' in raw)\n config.shape = raw['shape'] as ParticleSystemConfig['shape'];\n\n // renderer: convert blending string → THREE.Blending number\n if (raw['renderer'] && typeof raw['renderer'] === 'object') {\n const r = raw['renderer'] as RawObject;\n const blending =\n typeof r['blending'] === 'string'\n ? (blendingMap[r['blending'] as BlendingKey] ?? THREE.NormalBlending)\n : ((r['blending'] as number | undefined) ?? THREE.NormalBlending);\n config.renderer = { ...r, blending } as ParticleSystemConfig['renderer'];\n }\n\n // velocityOverLifetime\n if (\n raw['velocityOverLifetime'] &&\n typeof raw['velocityOverLifetime'] === 'object'\n ) {\n const vol = raw['velocityOverLifetime'] as RawObject;\n const deserializeAxis = (\n axis: unknown\n ): { x?: unknown; y?: unknown; z?: unknown } => {\n if (!axis || typeof axis !== 'object') return {};\n const a = axis as RawObject;\n return {\n ...(a['x'] !== undefined ? { x: deserializeCurveOrValue(a['x']) } : {}),\n ...(a['y'] !== undefined ? { y: deserializeCurveOrValue(a['y']) } : {}),\n ...(a['z'] !== undefined ? { z: deserializeCurveOrValue(a['z']) } : {}),\n };\n };\n config.velocityOverLifetime = {\n isActive: (vol['isActive'] as boolean) ?? false,\n linear: deserializeAxis(vol['linear']) as NonNullable<\n ParticleSystemConfig['velocityOverLifetime']\n >['linear'],\n orbital: deserializeAxis(vol['orbital']) as NonNullable<\n ParticleSystemConfig['velocityOverLifetime']\n >['orbital'],\n };\n }\n\n // sizeOverLifetime / opacityOverLifetime — both have isActive + lifetimeCurve\n for (const field of ['sizeOverLifetime', 'opacityOverLifetime'] as const) {\n if (raw[field] && typeof raw[field] === 'object') {\n const m = raw[field] as RawObject;\n (config as RawObject)[field] = {\n isActive: (m['isActive'] as boolean) ?? false,\n lifetimeCurve: deserializeCurve(m['lifetimeCurve']),\n };\n }\n }\n\n // colorOverLifetime — r/g/b are LifetimeCurves; isActive defaults to true when present\n if (\n raw['colorOverLifetime'] &&\n typeof raw['colorOverLifetime'] === 'object'\n ) {\n const col = raw['colorOverLifetime'] as RawObject;\n config.colorOverLifetime = {\n isActive: (col['isActive'] as boolean) ?? true,\n r: deserializeCurve(col['r']),\n g: deserializeCurve(col['g']),\n b: deserializeCurve(col['b']),\n };\n }\n\n // rotationOverLifetime (isActive + RandomBetweenTwoConstants — no curves)\n if (\n raw['rotationOverLifetime'] &&\n typeof raw['rotationOverLifetime'] === 'object'\n ) {\n config.rotationOverLifetime = raw[\n 'rotationOverLifetime'\n ] as ParticleSystemConfig['rotationOverLifetime'];\n }\n\n // noise (NoiseConfig is plain data — no reconstruction needed)\n if (raw['noise'] && typeof raw['noise'] === 'object') {\n config.noise = raw['noise'] as ParticleSystemConfig['noise'];\n }\n\n // textureSheetAnimation — reconstruct tiles Vector2, deserialize startFrame\n if (\n raw['textureSheetAnimation'] &&\n typeof raw['textureSheetAnimation'] === 'object'\n ) {\n const tsa = raw['textureSheetAnimation'] as RawObject;\n config.textureSheetAnimation = {\n ...(tsa as ParticleSystemConfig['textureSheetAnimation']),\n tiles: deserializeVector2(tsa['tiles']),\n startFrame: deserializeCurveOrValue(tsa['startFrame']) as NonNullable<\n ParticleSystemConfig['textureSheetAnimation']\n >['startFrame'],\n };\n }\n\n // subEmitters — recursively deserialize nested configs\n if (Array.isArray(raw['subEmitters'])) {\n config.subEmitters = (raw['subEmitters'] as RawObject[]).map((se) => ({\n ...(se as NonNullable<ParticleSystemConfig['subEmitters']>[number]),\n config: deserializeConfig(se['config'] as RawObject),\n }));\n }\n\n // forceFields — array of ForceFieldConfig objects\n if (Array.isArray(raw['forceFields'])) {\n config.forceFields = (raw['forceFields'] as RawObject[]).map((ff) => {\n const result: ForceFieldConfig = {};\n if ('isActive' in ff) result.isActive = ff['isActive'] as boolean;\n if ('type' in ff) result.type = ff['type'] as ForceFieldType;\n if (ff['position']) result.position = deserializeVector3(ff['position']);\n if (ff['direction'])\n result.direction = deserializeVector3(ff['direction']);\n if ('strength' in ff)\n result.strength = deserializeCurveOrValue(\n ff['strength']\n ) as ForceFieldConfig['strength'];\n if ('range' in ff)\n result.range =\n ff['range'] === null ? Infinity : (ff['range'] as number);\n if ('falloff' in ff) result.falloff = ff['falloff'] as ForceFieldFalloff;\n return result;\n });\n }\n\n // collisionPlanes — array of CollisionPlaneConfig objects\n if (Array.isArray(raw['collisionPlanes'])) {\n config.collisionPlanes = (raw['collisionPlanes'] as RawObject[]).map(\n (cp) => {\n const result: CollisionPlaneConfig = {};\n if ('isActive' in cp) result.isActive = cp['isActive'] as boolean;\n if ('mode' in cp) result.mode = cp['mode'] as CollisionPlaneMode;\n if (cp['position'])\n result.position = deserializeVector3(cp['position']);\n if (cp['normal']) result.normal = deserializeVector3(cp['normal']);\n if ('dampen' in cp) result.dampen = cp['dampen'] as number;\n if ('lifetimeLoss' in cp)\n result.lifetimeLoss = cp['lifetimeLoss'] as number;\n return result;\n }\n );\n }\n\n // _editorData and any other unknown fields — preserve as-is\n for (const key of Object.keys(raw)) {\n if (!(key in config) && key !== '_version' && raw[key] !== null) {\n (config as RawObject)[key] = raw[key];\n }\n }\n\n return config;\n}\n\n/**\n * Deserializes a JSON string produced by `serializeParticleSystem` (or by the\n * three-particles-editor) into a `ParticleSystemConfig` object.\n *\n * - Blending strings (e.g. `\"THREE.AdditiveBlending\"`) are converted back to\n * `THREE.Blending` constants.\n * - `{x, y, z}` objects under `transform` are reconstructed as `THREE.Vector3`.\n * - `{x, y}` objects under `textureSheetAnimation.tiles` are reconstructed as `THREE.Vector2`.\n * - Legacy Bézier curves without a `type` field (editor format) are normalized.\n * - Easing curves stored as `{ type: \"EASING\", curveFunctionId }` have their\n * `curveFunction` resolved from the predefined map.\n * - `_editorData` and other unknown fields are preserved.\n *\n * @param json - A JSON string produced by `serializeParticleSystem` or the editor.\n * @returns A fully reconstructed `ParticleSystemConfig`.\n *\n * @example\n * ```typescript\n * import { deserializeParticleSystem } from '@newkrok/three-particles';\n *\n * const config = deserializeParticleSystem(localStorage.getItem('myEffect')!);\n * createParticleSystem(config);\n * ```\n */\nexport function deserializeParticleSystem(json: string): ParticleSystemConfig {\n const parsed = JSON.parse(json) as RawObject & { _version?: number };\n\n const { _version: _, ...raw } = parsed;\n return deserializeConfig(raw);\n}\n"]}