@newkrok/three-particles 2.15.2 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/dist/index.d.ts +362 -7
- package/dist/index.js +1041 -395
- package/dist/index.js.map +1 -1
- package/dist/three-particles.min.js +1 -1
- package/dist/three-particles.min.js.map +1 -1
- package/dist/webgpu.js +1664 -0
- package/dist/webgpu.js.map +1 -0
- package/llms-full.txt +189 -0
- package/llms.txt +89 -0
- package/package.json +15 -10
- package/webgpu.d.ts +88 -0
package/README.md
CHANGED
|
@@ -19,12 +19,14 @@ Particle system for ThreeJS.
|
|
|
19
19
|
* Highly customizable particle properties (position, velocity, size, color, alpha, rotation, etc.).
|
|
20
20
|
* Support for various emitter shapes and parameters.
|
|
21
21
|
* Force fields and attractors for dynamic particle behavior (point attraction/repulsion, directional wind).
|
|
22
|
+
* Collision planes — kill, clamp, or bounce particles off infinite planes (e.g., water surfaces, floors, walls). Works on both CPU and GPU compute paths.
|
|
22
23
|
* Sub-emitters triggered on particle birth or death events.
|
|
23
24
|
* Serialization support for saving and loading particle system configs.
|
|
24
25
|
* GPU instancing renderer (`RendererType.INSTANCED`) — removes `gl_PointSize` hardware limit, ideal for large particles or high particle counts.
|
|
25
26
|
* Trail / Ribbon renderer (`RendererType.TRAIL`) — continuous ribbon trails behind particles with configurable width, opacity, and color tapering.
|
|
26
27
|
* Mesh particle renderer (`RendererType.MESH`) — render each particle as a 3D mesh (debris, gems, coins) using GPU instancing with full 3D rotation and simple directional lighting.
|
|
27
28
|
* Soft particles — depth-based alpha fade near opaque geometry, eliminating hard intersection lines.
|
|
29
|
+
* **WebGPU compute support** — GPU compute shaders for particle simulation (gravity, velocity, modifiers, force fields, noise) via Three.js TSL. Enables 50K-350K+ particles at full framerate. Automatic fallback to CPU when WebGPU is unavailable.
|
|
28
30
|
* TypeDoc API documentation available.
|
|
29
31
|
|
|
30
32
|
# Live Demo & Examples
|
|
@@ -75,6 +77,10 @@ updateParticleSystems({now, delta, elapsed});
|
|
|
75
77
|
system.updateConfig({
|
|
76
78
|
gravity: -9.8,
|
|
77
79
|
forceFields: [{ type: 'DIRECTIONAL', direction: { x: 1, y: 0, z: 0 }, strength: 5 }],
|
|
80
|
+
// Collision planes — kill, clamp, or bounce particles off surfaces
|
|
81
|
+
collisionPlanes: [
|
|
82
|
+
{ position: { x: 0, y: 5, z: 0 }, normal: { x: 0, y: -1, z: 0 }, mode: 'KILL' },
|
|
83
|
+
],
|
|
78
84
|
});
|
|
79
85
|
```
|
|
80
86
|
|
|
@@ -150,6 +156,80 @@ function FireEffect({ config }: { config?: Record<string, unknown> }) {
|
|
|
150
156
|
- Add the `system.instance` to a `<group>` ref so R3F manages the scene graph
|
|
151
157
|
- Return a cleanup function from `useEffect` that calls `system.dispose()`
|
|
152
158
|
|
|
159
|
+
# WebGPU Compute Support
|
|
160
|
+
|
|
161
|
+
Optional GPU-accelerated particle simulation via Three.js WebGPU renderer and TSL (Three Shading Language). Offloads all per-particle physics and modifiers to GPU compute shaders, enabling **50K-350K+ particles** at interactive frame rates.
|
|
162
|
+
|
|
163
|
+
## Requirements
|
|
164
|
+
|
|
165
|
+
- Three.js **r182+** with the WebGPU build (`three/webgpu`)
|
|
166
|
+
- A browser with [WebGPU support](https://caniuse.com/webgpu) (Chrome 113+, Edge 113+, Firefox Nightly)
|
|
167
|
+
- No breaking changes — all existing WebGL code works unchanged
|
|
168
|
+
|
|
169
|
+
## Setup
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// 1. Enable WebGPU support (once, before creating any particle system)
|
|
173
|
+
import { enableWebGPU } from "@newkrok/three-particles/webgpu";
|
|
174
|
+
enableWebGPU();
|
|
175
|
+
|
|
176
|
+
// 2. Create a WebGPU renderer
|
|
177
|
+
import * as THREE from "three/webgpu";
|
|
178
|
+
const renderer = new THREE.WebGPURenderer({ antialias: true });
|
|
179
|
+
await renderer.init();
|
|
180
|
+
|
|
181
|
+
// 3. Create a GPU-accelerated particle system
|
|
182
|
+
import { createParticleSystem, SimulationBackend } from "@newkrok/three-particles";
|
|
183
|
+
const system = createParticleSystem({
|
|
184
|
+
simulationBackend: SimulationBackend.AUTO, // GPU if WebGPU available, else CPU
|
|
185
|
+
maxParticles: 100000,
|
|
186
|
+
// ... rest of your config (same API as CPU)
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
scene.add(system.instance);
|
|
190
|
+
|
|
191
|
+
// 4. In your render loop — dispatch compute before rendering
|
|
192
|
+
function animate() {
|
|
193
|
+
system.update({ now: performance.now(), delta, elapsed });
|
|
194
|
+
|
|
195
|
+
if (system.computeNode) {
|
|
196
|
+
renderer.compute(system.computeNode);
|
|
197
|
+
}
|
|
198
|
+
renderer.render(scene, camera);
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
For fine-grained control, you can also use `registerTSLMaterialFactory()` to selectively register individual WebGPU functions — see the full API reference.
|
|
203
|
+
|
|
204
|
+
## SimulationBackend
|
|
205
|
+
|
|
206
|
+
| Value | Behavior |
|
|
207
|
+
|-------|----------|
|
|
208
|
+
| `AUTO` (default) | GPU compute if WebGPU renderer detected, else CPU |
|
|
209
|
+
| `CPU` | Always JavaScript update loop (works with any renderer) |
|
|
210
|
+
| `GPU` | Request GPU compute; falls back to CPU if renderer lacks compute support |
|
|
211
|
+
|
|
212
|
+
## What Runs on GPU
|
|
213
|
+
|
|
214
|
+
- **Core physics:** gravity, velocity integration, position update, lifetime tracking
|
|
215
|
+
- **All 7 modifiers:** size/opacity/color over lifetime, rotation, linear velocity, orbital velocity, noise (3D simplex FBM)
|
|
216
|
+
- **Force fields:** point attractors/repulsors and directional forces with falloff (up to 16 per system)
|
|
217
|
+
- **Curves:** baked into 256-sample lookup arrays for fast GPU evaluation (<0.4% error)
|
|
218
|
+
|
|
219
|
+
## What Stays on CPU
|
|
220
|
+
|
|
221
|
+
- **Emission** — particle activation, burst scheduling, rate-over-distance
|
|
222
|
+
- **Sub-emitters** — birth/death trigger spawning
|
|
223
|
+
- **Configuration changes** — `updateConfig()` applies on the next frame
|
|
224
|
+
- **Trail renderer** — TRAIL type always uses CPU simulation (other renderer types work with GPU)
|
|
225
|
+
|
|
226
|
+
## Fallback Behavior
|
|
227
|
+
|
|
228
|
+
WebGPU is fully opt-in and non-breaking:
|
|
229
|
+
- If `enableWebGPU()` not called (or no TSL factory registered), the library uses GLSL shaders (WebGL path)
|
|
230
|
+
- If `simulationBackend: 'GPU'` but WebGPU is unavailable, it silently falls back to CPU
|
|
231
|
+
- The same particle config works identically on both backends
|
|
232
|
+
|
|
153
233
|
# Documentation
|
|
154
234
|
|
|
155
235
|
Automatically generated TypeDoc: [https://newkrok.github.io/three-particles/api/](https://newkrok.github.io/three-particles/api/)
|
package/dist/index.d.ts
CHANGED
|
@@ -215,10 +215,58 @@ declare const enum ForceFieldFalloff {
|
|
|
215
215
|
LINEAR = "LINEAR",
|
|
216
216
|
/**
|
|
217
217
|
* Force decreases with the square of distance: `1 - (d/range)²`.
|
|
218
|
-
* More physically realistic than linear
|
|
218
|
+
* More physically realistic than linear fallback.
|
|
219
219
|
*/
|
|
220
220
|
QUADRATIC = "QUADRATIC"
|
|
221
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Defines the behavior when a particle crosses a collision plane.
|
|
224
|
+
*
|
|
225
|
+
* @enum {string}
|
|
226
|
+
*/
|
|
227
|
+
declare const enum CollisionPlaneMode {
|
|
228
|
+
/**
|
|
229
|
+
* Kill the particle immediately when it crosses the plane.
|
|
230
|
+
* The particle is deactivated and returned to the free list.
|
|
231
|
+
* Ideal for boundaries like water surfaces where bubbles pop.
|
|
232
|
+
*/
|
|
233
|
+
KILL = "KILL",
|
|
234
|
+
/**
|
|
235
|
+
* Clamp the particle's position to the plane surface.
|
|
236
|
+
* The velocity component along the plane normal is zeroed.
|
|
237
|
+
* The particle stays alive and slides along the plane.
|
|
238
|
+
*/
|
|
239
|
+
CLAMP = "CLAMP",
|
|
240
|
+
/**
|
|
241
|
+
* Bounce the particle off the plane.
|
|
242
|
+
* The velocity is reflected across the plane normal and dampened.
|
|
243
|
+
* Use `dampen` to control energy loss on bounce.
|
|
244
|
+
*/
|
|
245
|
+
BOUNCE = "BOUNCE"
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Defines the simulation backend used for particle updates.
|
|
249
|
+
*
|
|
250
|
+
* @enum {string}
|
|
251
|
+
*/
|
|
252
|
+
declare const enum SimulationBackend {
|
|
253
|
+
/**
|
|
254
|
+
* Automatically select the best backend based on the renderer type.
|
|
255
|
+
* Uses GPU compute when a WebGPU-capable renderer is detected, otherwise falls back to CPU.
|
|
256
|
+
*/
|
|
257
|
+
AUTO = "AUTO",
|
|
258
|
+
/**
|
|
259
|
+
* Force CPU-based simulation (JavaScript update loop).
|
|
260
|
+
* Always available regardless of renderer type.
|
|
261
|
+
*/
|
|
262
|
+
CPU = "CPU",
|
|
263
|
+
/**
|
|
264
|
+
* Force GPU compute shader simulation.
|
|
265
|
+
* Requires a WebGPU-capable renderer (e.g. `THREE.WebGPURenderer`).
|
|
266
|
+
* Falls back to CPU if the renderer does not support compute.
|
|
267
|
+
*/
|
|
268
|
+
GPU = "GPU"
|
|
269
|
+
}
|
|
222
270
|
|
|
223
271
|
/**
|
|
224
272
|
* A fixed numerical value.
|
|
@@ -931,9 +979,12 @@ type Noise = {
|
|
|
931
979
|
isActive: boolean;
|
|
932
980
|
strength: number;
|
|
933
981
|
noisePower: number;
|
|
982
|
+
frequency: number;
|
|
934
983
|
positionAmount: number;
|
|
935
984
|
rotationAmount: number;
|
|
936
985
|
sizeAmount: number;
|
|
986
|
+
/** Pre-computed FBM normalisation divisor: `2 - 2^(-octaves)`. */
|
|
987
|
+
fbmMax: number;
|
|
937
988
|
sampler?: FBM;
|
|
938
989
|
offsets?: Array<number>;
|
|
939
990
|
};
|
|
@@ -1111,6 +1162,76 @@ type NormalizedForceFieldConfig = {
|
|
|
1111
1162
|
range: number;
|
|
1112
1163
|
falloff: ForceFieldFalloff;
|
|
1113
1164
|
};
|
|
1165
|
+
/**
|
|
1166
|
+
* Configuration for a collision plane that constrains particle positions.
|
|
1167
|
+
* Collision planes define infinite planes in 3D space. When a particle crosses
|
|
1168
|
+
* from the front side (positive normal direction) to the back side, the
|
|
1169
|
+
* configured response mode is triggered.
|
|
1170
|
+
*
|
|
1171
|
+
* @example
|
|
1172
|
+
* ```typescript
|
|
1173
|
+
* // Water surface — kill bubbles when they reach y=5
|
|
1174
|
+
* const waterSurface: CollisionPlaneConfig = {
|
|
1175
|
+
* position: { x: 0, y: 5, z: 0 },
|
|
1176
|
+
* normal: { x: 0, y: -1, z: 0 },
|
|
1177
|
+
* mode: CollisionPlaneMode.KILL,
|
|
1178
|
+
* };
|
|
1179
|
+
*
|
|
1180
|
+
* // Bouncy floor
|
|
1181
|
+
* const floor: CollisionPlaneConfig = {
|
|
1182
|
+
* position: { x: 0, y: 0, z: 0 },
|
|
1183
|
+
* normal: { x: 0, y: 1, z: 0 },
|
|
1184
|
+
* mode: CollisionPlaneMode.BOUNCE,
|
|
1185
|
+
* dampen: 0.6,
|
|
1186
|
+
* };
|
|
1187
|
+
*
|
|
1188
|
+
* // Invisible wall clamp
|
|
1189
|
+
* const wall: CollisionPlaneConfig = {
|
|
1190
|
+
* position: { x: 5, y: 0, z: 0 },
|
|
1191
|
+
* normal: { x: -1, y: 0, z: 0 },
|
|
1192
|
+
* mode: CollisionPlaneMode.CLAMP,
|
|
1193
|
+
* };
|
|
1194
|
+
* ```
|
|
1195
|
+
*/
|
|
1196
|
+
type CollisionPlaneConfig = {
|
|
1197
|
+
/** Whether this collision plane is active. @default true */
|
|
1198
|
+
isActive?: boolean;
|
|
1199
|
+
/** A point on the plane surface. @default (0,0,0) */
|
|
1200
|
+
position?: Point3D;
|
|
1201
|
+
/**
|
|
1202
|
+
* The plane normal vector (will be normalized internally).
|
|
1203
|
+
* Defines the "front" side of the plane. Particles crossing from front
|
|
1204
|
+
* to back trigger the collision response.
|
|
1205
|
+
* @default (0,1,0)
|
|
1206
|
+
*/
|
|
1207
|
+
normal?: Point3D;
|
|
1208
|
+
/** The collision response mode. @default CollisionPlaneMode.KILL */
|
|
1209
|
+
mode?: CollisionPlaneMode;
|
|
1210
|
+
/**
|
|
1211
|
+
* Energy retention factor for BOUNCE mode (0–1).
|
|
1212
|
+
* 0 = no bounce (all energy absorbed), 1 = perfect bounce (no energy loss).
|
|
1213
|
+
* @default 0.5
|
|
1214
|
+
*/
|
|
1215
|
+
dampen?: number;
|
|
1216
|
+
/**
|
|
1217
|
+
* Fraction of the particle's start lifetime to subtract on collision (0–1).
|
|
1218
|
+
* Applied on each collision for BOUNCE mode; ignored for KILL and CLAMP.
|
|
1219
|
+
* @default 0
|
|
1220
|
+
*/
|
|
1221
|
+
lifetimeLoss?: number;
|
|
1222
|
+
};
|
|
1223
|
+
/**
|
|
1224
|
+
* Internal normalized collision plane configuration where all properties are required.
|
|
1225
|
+
* Created during particle system initialization from user-provided {@link CollisionPlaneConfig}.
|
|
1226
|
+
*/
|
|
1227
|
+
type NormalizedCollisionPlaneConfig = {
|
|
1228
|
+
isActive: boolean;
|
|
1229
|
+
position: THREE.Vector3;
|
|
1230
|
+
normal: THREE.Vector3;
|
|
1231
|
+
mode: CollisionPlaneMode;
|
|
1232
|
+
dampen: number;
|
|
1233
|
+
lifetimeLoss: number;
|
|
1234
|
+
};
|
|
1114
1235
|
/**
|
|
1115
1236
|
* Configuration object for the particle system.
|
|
1116
1237
|
* Defines all aspects of the particle system, including its appearance, behavior, and runtime events.
|
|
@@ -1344,6 +1465,18 @@ type ParticleSystemConfig = {
|
|
|
1344
1465
|
* simulationSpace: SimulationSpace.WORLD;
|
|
1345
1466
|
*/
|
|
1346
1467
|
simulationSpace?: SimulationSpace;
|
|
1468
|
+
/**
|
|
1469
|
+
* Selects the simulation backend for particle updates.
|
|
1470
|
+
*
|
|
1471
|
+
* - `AUTO` (default): Uses GPU compute when a WebGPU-capable renderer is
|
|
1472
|
+
* detected, otherwise falls back to CPU.
|
|
1473
|
+
* - `CPU`: Always uses the JavaScript update loop (works with any renderer).
|
|
1474
|
+
* - `GPU`: Requests GPU compute simulation. Falls back to CPU if the renderer
|
|
1475
|
+
* does not support compute shaders.
|
|
1476
|
+
*
|
|
1477
|
+
* @default SimulationBackend.AUTO
|
|
1478
|
+
*/
|
|
1479
|
+
simulationBackend?: SimulationBackend;
|
|
1347
1480
|
/**
|
|
1348
1481
|
* Defines the maximum number of particles allowed in the system.
|
|
1349
1482
|
* This value limits the total number of active particles at any given time.
|
|
@@ -1635,6 +1768,31 @@ type ParticleSystemConfig = {
|
|
|
1635
1768
|
* ```
|
|
1636
1769
|
*/
|
|
1637
1770
|
forceFields?: Array<ForceFieldConfig>;
|
|
1771
|
+
/**
|
|
1772
|
+
* Collision planes that constrain particle positions.
|
|
1773
|
+
*
|
|
1774
|
+
* Each plane defines an infinite surface in 3D space. When a particle crosses
|
|
1775
|
+
* from the front side (positive normal direction) to the back side, the
|
|
1776
|
+
* configured response mode is triggered: KILL (remove), CLAMP (stop at surface),
|
|
1777
|
+
* or BOUNCE (reflect with energy loss).
|
|
1778
|
+
*
|
|
1779
|
+
* Plane positions and normals are in world space. Multiple planes are checked
|
|
1780
|
+
* in order; for KILL mode, the first collision deactivates the particle.
|
|
1781
|
+
*
|
|
1782
|
+
* @default []
|
|
1783
|
+
*
|
|
1784
|
+
* @example
|
|
1785
|
+
* ```typescript
|
|
1786
|
+
* collisionPlanes: [
|
|
1787
|
+
* {
|
|
1788
|
+
* position: { x: 0, y: 5, z: 0 },
|
|
1789
|
+
* normal: { x: 0, y: -1, z: 0 },
|
|
1790
|
+
* mode: CollisionPlaneMode.KILL,
|
|
1791
|
+
* },
|
|
1792
|
+
* ]
|
|
1793
|
+
* ```
|
|
1794
|
+
*/
|
|
1795
|
+
collisionPlanes?: Array<CollisionPlaneConfig>;
|
|
1638
1796
|
/**
|
|
1639
1797
|
* Called on every update frame with particle system data.
|
|
1640
1798
|
*/
|
|
@@ -1745,10 +1903,8 @@ type MappedAttributes = {
|
|
|
1745
1903
|
startFrame: AnyBufferAttribute;
|
|
1746
1904
|
size: AnyBufferAttribute;
|
|
1747
1905
|
rotation: AnyBufferAttribute;
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
colorB: AnyBufferAttribute;
|
|
1751
|
-
colorA: AnyBufferAttribute;
|
|
1906
|
+
/** Packed RGBA color (vec4). */
|
|
1907
|
+
color: AnyBufferAttribute;
|
|
1752
1908
|
/** Packed quaternion vec4 for 3D mesh rotation (only present for RendererType.MESH). */
|
|
1753
1909
|
quat?: AnyBufferAttribute;
|
|
1754
1910
|
};
|
|
@@ -1756,6 +1912,10 @@ type ParticleSystemInstance = {
|
|
|
1756
1912
|
particleSystem: THREE.Points | THREE.Mesh;
|
|
1757
1913
|
wrapper?: Gyroscope;
|
|
1758
1914
|
mappedAttributes: MappedAttributes;
|
|
1915
|
+
/** Shared interleaved Float32Array backing all scalar per-particle attributes. */
|
|
1916
|
+
scalarArray: Float32Array;
|
|
1917
|
+
/** The InterleavedBuffer (or InstancedInterleavedBuffer) for scalar attributes. */
|
|
1918
|
+
scalarInterleavedBuffer: THREE.InterleavedBuffer;
|
|
1759
1919
|
elapsedUniform: {
|
|
1760
1920
|
value: number;
|
|
1761
1921
|
};
|
|
@@ -1778,6 +1938,7 @@ type ParticleSystemInstance = {
|
|
|
1778
1938
|
simulationSpace: SimulationSpace;
|
|
1779
1939
|
gravity: number;
|
|
1780
1940
|
normalizedForceFields: Array<NormalizedForceFieldConfig>;
|
|
1941
|
+
normalizedCollisionPlanes: Array<NormalizedCollisionPlaneConfig>;
|
|
1781
1942
|
emission: Emission;
|
|
1782
1943
|
normalizedConfig: NormalizedParticleSystemConfig;
|
|
1783
1944
|
iterationCount: number;
|
|
@@ -1828,6 +1989,20 @@ type ParticleSystemInstance = {
|
|
|
1828
1989
|
twistPrevention: boolean;
|
|
1829
1990
|
ribbonId?: number;
|
|
1830
1991
|
};
|
|
1992
|
+
/** GPU compute pipeline for WebGPU simulation. Opaque type to avoid pulling TSL types into DTS. */
|
|
1993
|
+
computePipeline?: {
|
|
1994
|
+
computeNode: unknown;
|
|
1995
|
+
uniforms: Record<string, unknown>;
|
|
1996
|
+
buffers: Record<string, unknown>;
|
|
1997
|
+
forceFieldInfo: {
|
|
1998
|
+
offset: number;
|
|
1999
|
+
countUniform: unknown;
|
|
2000
|
+
} | null;
|
|
2001
|
+
};
|
|
2002
|
+
/** Whether this system uses GPU compute for simulation. */
|
|
2003
|
+
useGPUCompute?: boolean;
|
|
2004
|
+
/** Flag set by update loop, consumed by onBeforeRender to dispatch compute. */
|
|
2005
|
+
computeDispatchReady?: boolean;
|
|
1831
2006
|
};
|
|
1832
2007
|
/**
|
|
1833
2008
|
* Represents a particle system instance, providing methods to control and manage its lifecycle.
|
|
@@ -1855,6 +2030,8 @@ type ParticleSystem = {
|
|
|
1855
2030
|
pauseEmitter: () => void;
|
|
1856
2031
|
dispose: () => void;
|
|
1857
2032
|
update: (cycleData: CycleData) => void;
|
|
2033
|
+
/** GPU compute node for WebGPU dispatch. Call `renderer.compute(computeNode)` before `renderer.render()`. Null when CPU simulation. */
|
|
2034
|
+
computeNode: unknown | null;
|
|
1858
2035
|
/**
|
|
1859
2036
|
* Updates the particle system configuration at runtime without recreating the system.
|
|
1860
2037
|
*
|
|
@@ -2083,15 +2260,93 @@ declare const getCurveFunction: (curveFunctionId: CurveFunctionId | CurveFunctio
|
|
|
2083
2260
|
* @see {@link VelocityOverLifetime} - Configuration for velocity modifiers
|
|
2084
2261
|
* @see {@link NoiseConfig} - Configuration for noise-based effects
|
|
2085
2262
|
*/
|
|
2086
|
-
declare const applyModifiers: ({ delta, generalData, normalizedConfig, attributes, particleLifetimePercentage, particleIndex, }: {
|
|
2263
|
+
declare const applyModifiers: ({ delta, generalData, normalizedConfig, attributes, scalarArray, particleLifetimePercentage, particleIndex, }: {
|
|
2087
2264
|
delta: number;
|
|
2088
2265
|
generalData: GeneralData;
|
|
2089
2266
|
normalizedConfig: NormalizedParticleSystemConfig;
|
|
2090
2267
|
attributes: MappedAttributes;
|
|
2268
|
+
scalarArray: Float32Array;
|
|
2091
2269
|
particleLifetimePercentage: number;
|
|
2092
2270
|
particleIndex: number;
|
|
2093
2271
|
}) => void;
|
|
2094
2272
|
|
|
2273
|
+
/**
|
|
2274
|
+
* Checks whether the given renderer supports GPU compute dispatches.
|
|
2275
|
+
*
|
|
2276
|
+
* Uses duck-typing: a renderer is considered WebGPU-capable when it exposes
|
|
2277
|
+
* a `.compute()` method and a `.hasFeature()` method (both present on
|
|
2278
|
+
* `THREE.WebGPURenderer` but absent from `THREE.WebGLRenderer`).
|
|
2279
|
+
*
|
|
2280
|
+
* @param renderer - Any Three.js renderer instance.
|
|
2281
|
+
* @returns `true` when the renderer supports compute shaders.
|
|
2282
|
+
*/
|
|
2283
|
+
declare function isComputeCapableRenderer(renderer: unknown): boolean;
|
|
2284
|
+
/**
|
|
2285
|
+
* Resolves the effective simulation backend based on the user's preference
|
|
2286
|
+
* and the capabilities of the provided renderer.
|
|
2287
|
+
*
|
|
2288
|
+
* | Preference | WebGPURenderer | WebGLRenderer |
|
|
2289
|
+
* |------------|---------------|---------------|
|
|
2290
|
+
* | `AUTO` | `GPU` | `CPU` |
|
|
2291
|
+
* | `CPU` | `CPU` | `CPU` |
|
|
2292
|
+
* | `GPU` | `GPU` | `CPU` (fallback) |
|
|
2293
|
+
*
|
|
2294
|
+
* @param renderer - The Three.js renderer instance used for rendering.
|
|
2295
|
+
* @param preference - The user-specified simulation backend preference.
|
|
2296
|
+
* @returns The resolved {@link SimulationBackend} (`CPU` or `GPU`).
|
|
2297
|
+
*/
|
|
2298
|
+
declare function resolveSimulationBackend(renderer: unknown, preference?: SimulationBackend): SimulationBackend.CPU | SimulationBackend.GPU;
|
|
2299
|
+
|
|
2300
|
+
/**
|
|
2301
|
+
* Serializes a `ParticleSystemConfig` to a JSON string.
|
|
2302
|
+
*
|
|
2303
|
+
* - `THREE.Vector3` / `THREE.Vector2` are converted to plain `{x, y, z}` / `{x, y}` objects.
|
|
2304
|
+
* - `renderer.blending` is converted to its string identifier (e.g. `"THREE.AdditiveBlending"`).
|
|
2305
|
+
* - `EasingCurve.curveFunction` is replaced by a `curveFunctionId` string.
|
|
2306
|
+
* Only predefined `CurveFunctionId` functions can be serialized; custom functions throw.
|
|
2307
|
+
* - `THREE.Texture` (`map`), callback fields (`onUpdate`, `onComplete`) are omitted.
|
|
2308
|
+
* - An `_editorData` field and other unknown fields are preserved as-is.
|
|
2309
|
+
* - A `_version` field is added for forward-compatibility.
|
|
2310
|
+
*
|
|
2311
|
+
* @param config - The particle system configuration to serialize.
|
|
2312
|
+
* @returns A JSON string representation of the config.
|
|
2313
|
+
* @throws If the config contains a custom (non-predefined) `curveFunction`.
|
|
2314
|
+
*
|
|
2315
|
+
* @example
|
|
2316
|
+
* ```typescript
|
|
2317
|
+
* import { serializeParticleSystem } from '@newkrok/three-particles';
|
|
2318
|
+
*
|
|
2319
|
+
* const json = serializeParticleSystem(config);
|
|
2320
|
+
* localStorage.setItem('myEffect', json);
|
|
2321
|
+
* ```
|
|
2322
|
+
*/
|
|
2323
|
+
declare function serializeParticleSystem(config: ParticleSystemConfig): string;
|
|
2324
|
+
/**
|
|
2325
|
+
* Deserializes a JSON string produced by `serializeParticleSystem` (or by the
|
|
2326
|
+
* three-particles-editor) into a `ParticleSystemConfig` object.
|
|
2327
|
+
*
|
|
2328
|
+
* - Blending strings (e.g. `"THREE.AdditiveBlending"`) are converted back to
|
|
2329
|
+
* `THREE.Blending` constants.
|
|
2330
|
+
* - `{x, y, z}` objects under `transform` are reconstructed as `THREE.Vector3`.
|
|
2331
|
+
* - `{x, y}` objects under `textureSheetAnimation.tiles` are reconstructed as `THREE.Vector2`.
|
|
2332
|
+
* - Legacy Bézier curves without a `type` field (editor format) are normalized.
|
|
2333
|
+
* - Easing curves stored as `{ type: "EASING", curveFunctionId }` have their
|
|
2334
|
+
* `curveFunction` resolved from the predefined map.
|
|
2335
|
+
* - `_editorData` and other unknown fields are preserved.
|
|
2336
|
+
*
|
|
2337
|
+
* @param json - A JSON string produced by `serializeParticleSystem` or the editor.
|
|
2338
|
+
* @returns A fully reconstructed `ParticleSystemConfig`.
|
|
2339
|
+
*
|
|
2340
|
+
* @example
|
|
2341
|
+
* ```typescript
|
|
2342
|
+
* import { deserializeParticleSystem } from '@newkrok/three-particles';
|
|
2343
|
+
*
|
|
2344
|
+
* const config = deserializeParticleSystem(localStorage.getItem('myEffect')!);
|
|
2345
|
+
* createParticleSystem(config);
|
|
2346
|
+
* ```
|
|
2347
|
+
*/
|
|
2348
|
+
declare function deserializeParticleSystem(json: string): ParticleSystemConfig;
|
|
2349
|
+
|
|
2095
2350
|
/**
|
|
2096
2351
|
* Calculates random position and velocity for particles emitted from a sphere.
|
|
2097
2352
|
*
|
|
@@ -2255,6 +2510,106 @@ declare const isLifeTimeCurve: (value: Constant | RandomBetweenTwoConstants | Li
|
|
|
2255
2510
|
declare const getCurveFunctionFromConfig: (particleSystemId: number, lifetimeCurve: LifetimeCurve) => CurveFunction;
|
|
2256
2511
|
declare const calculateValue: (particleSystemId: number, value: Constant | RandomBetweenTwoConstants | LifetimeCurve, time?: number) => number;
|
|
2257
2512
|
|
|
2513
|
+
/**
|
|
2514
|
+
* Interleaved scalar buffer layout constants.
|
|
2515
|
+
*
|
|
2516
|
+
* All per-particle float attributes (except position and quat) are packed
|
|
2517
|
+
* into a single InterleavedBuffer to stay within the WebGPU vertex buffer
|
|
2518
|
+
* limit of 8.
|
|
2519
|
+
*
|
|
2520
|
+
* Buffer layout per particle (stride = 10 floats):
|
|
2521
|
+
* ```
|
|
2522
|
+
* [isActive, lifetime, startLifetime, startFrame, size, rotation, colorR, colorG, colorB, colorA]
|
|
2523
|
+
* ```
|
|
2524
|
+
*/
|
|
2525
|
+
/** Number of float32 elements per particle in the interleaved scalar buffer. */
|
|
2526
|
+
declare const SCALAR_STRIDE = 10;
|
|
2527
|
+
/** Offset for the isActive flag (0 = inactive, 1 = active). */
|
|
2528
|
+
declare const S_IS_ACTIVE = 0;
|
|
2529
|
+
/** Offset for the current lifetime of the particle in milliseconds. */
|
|
2530
|
+
declare const S_LIFETIME = 1;
|
|
2531
|
+
/** Offset for the total lifetime of the particle in milliseconds. */
|
|
2532
|
+
declare const S_START_LIFETIME = 2;
|
|
2533
|
+
/** Offset for the texture sheet animation start frame index. */
|
|
2534
|
+
declare const S_START_FRAME = 3;
|
|
2535
|
+
/** Offset for the particle size. */
|
|
2536
|
+
declare const S_SIZE = 4;
|
|
2537
|
+
/** Offset for the particle rotation (radians). */
|
|
2538
|
+
declare const S_ROTATION = 5;
|
|
2539
|
+
/** Offset for the red color channel (0..1). */
|
|
2540
|
+
declare const S_COLOR_R = 6;
|
|
2541
|
+
/** Offset for the green color channel (0..1). */
|
|
2542
|
+
declare const S_COLOR_G = 7;
|
|
2543
|
+
/** Offset for the blue color channel (0..1). */
|
|
2544
|
+
declare const S_COLOR_B = 8;
|
|
2545
|
+
/** Offset for the alpha (opacity) channel (0..1). */
|
|
2546
|
+
declare const S_COLOR_A = 9;
|
|
2547
|
+
|
|
2548
|
+
type TSLMaterialFactory = {
|
|
2549
|
+
createTSLParticleMaterial: (rendererType: RendererType, sharedUniforms: Record<string, {
|
|
2550
|
+
value: unknown;
|
|
2551
|
+
}>, rendererConfig: {
|
|
2552
|
+
transparent: boolean;
|
|
2553
|
+
blending: THREE.Blending;
|
|
2554
|
+
depthTest: boolean;
|
|
2555
|
+
depthWrite: boolean;
|
|
2556
|
+
}, gpuCompute?: boolean) => THREE.Material;
|
|
2557
|
+
createTSLTrailMaterial: (trailUniforms: Record<string, {
|
|
2558
|
+
value: unknown;
|
|
2559
|
+
}>, rendererConfig: {
|
|
2560
|
+
transparent: boolean;
|
|
2561
|
+
blending: THREE.Blending;
|
|
2562
|
+
depthTest: boolean;
|
|
2563
|
+
depthWrite: boolean;
|
|
2564
|
+
}) => THREE.Material;
|
|
2565
|
+
createComputePipeline?: (...args: any[]) => any;
|
|
2566
|
+
writeParticleToModifierBuffers?: (...args: any[]) => void;
|
|
2567
|
+
deactivateParticleInModifierBuffers?: (...args: any[]) => void;
|
|
2568
|
+
flushEmitQueue?: (...args: any[]) => number;
|
|
2569
|
+
registerCurveDataLength?: (...args: any[]) => void;
|
|
2570
|
+
encodeForceFieldsForGPU?: (...args: any[]) => Float32Array;
|
|
2571
|
+
encodeCollisionPlanesForGPU?: (...args: any[]) => Float32Array;
|
|
2572
|
+
};
|
|
2573
|
+
/**
|
|
2574
|
+
* Registers the TSL (Three Shading Language) material factory for WebGPU support.
|
|
2575
|
+
*
|
|
2576
|
+
* Call this **once** before creating any particle systems that use WebGPU rendering.
|
|
2577
|
+
* The factory functions are imported from the `@newkrok/three-particles/webgpu` sub-module.
|
|
2578
|
+
*
|
|
2579
|
+
* When registered, all particle systems will use TSL-based `NodeMaterial` (compiles to WGSL)
|
|
2580
|
+
* instead of GLSL `ShaderMaterial`. If the factory also includes the GPU compute functions
|
|
2581
|
+
* (`createComputePipeline`, `writeParticleToModifierBuffers`, etc.), particle systems with
|
|
2582
|
+
* `simulationBackend: 'AUTO'` or `'GPU'` will run physics and modifiers on the GPU.
|
|
2583
|
+
*
|
|
2584
|
+
* @param factory - Object containing TSL material creators and optional GPU compute helpers.
|
|
2585
|
+
*
|
|
2586
|
+
* @example
|
|
2587
|
+
* ```typescript
|
|
2588
|
+
* import { registerTSLMaterialFactory } from '@newkrok/three-particles';
|
|
2589
|
+
* import {
|
|
2590
|
+
* createTSLParticleMaterial,
|
|
2591
|
+
* createTSLTrailMaterial,
|
|
2592
|
+
* createComputePipeline,
|
|
2593
|
+
* writeParticleToModifierBuffers,
|
|
2594
|
+
* deactivateParticleInModifierBuffers,
|
|
2595
|
+
* flushEmitQueue,
|
|
2596
|
+
* registerCurveDataLength,
|
|
2597
|
+
* encodeForceFieldsForGPU,
|
|
2598
|
+
* } from '@newkrok/three-particles/webgpu';
|
|
2599
|
+
*
|
|
2600
|
+
* registerTSLMaterialFactory({
|
|
2601
|
+
* createTSLParticleMaterial,
|
|
2602
|
+
* createTSLTrailMaterial,
|
|
2603
|
+
* createComputePipeline,
|
|
2604
|
+
* writeParticleToModifierBuffers,
|
|
2605
|
+
* deactivateParticleInModifierBuffers,
|
|
2606
|
+
* flushEmitQueue,
|
|
2607
|
+
* registerCurveDataLength,
|
|
2608
|
+
* encodeForceFieldsForGPU,
|
|
2609
|
+
* });
|
|
2610
|
+
* ```
|
|
2611
|
+
*/
|
|
2612
|
+
declare const registerTSLMaterialFactory: (factory: TSLMaterialFactory) => void;
|
|
2258
2613
|
/**
|
|
2259
2614
|
* Mapping of blending mode string identifiers to Three.js blending constants.
|
|
2260
2615
|
*
|
|
@@ -2360,4 +2715,4 @@ declare const getDefaultParticleSystemConfig: () => any;
|
|
|
2360
2715
|
declare const createParticleSystem: (config?: ParticleSystemConfig, externalNow?: number) => ParticleSystem;
|
|
2361
2716
|
declare const updateParticleSystems: (cycleData: CycleData) => void;
|
|
2362
2717
|
|
|
2363
|
-
export { type BezierCurve, type BezierPoint, type Box, type Burst, type BurstState, type Circle, type Cone, type Constant, type CurveBase, type CurveFunction, CurveFunctionId, type CycleData, type EasingCurve, type Emission, EmitFrom, type ForceFieldConfig, ForceFieldFalloff, ForceFieldType, type GeneralData, LifeTimeCurve, type LifetimeCurve, type MappedAttributes, type MeshConfig, type MinMaxColor, type Noise, type NoiseConfig, type NormalizedForceFieldConfig, type NormalizedParticleSystemConfig, type ParticleSystem, type ParticleSystemConfig, type ParticleSystemInstance, type Point3D, type RandomBetweenTwoConstants, type Rectangle, type Renderer, RendererType, type Rgb, Shape, type ShapeConfig, SimulationSpace, type SoftParticlesConfig, type Sphere, type SubEmitterConfig, SubEmitterTrigger, type TextureSheetAnimation, TimeMode, type TrailConfig, type Transform, type VelocityOverLifetime, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultMeshTexture, createDefaultParticleTexture, createParticleSystem, curveFunctionIdMap, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isLifeTimeCurve, removeBezierCurveFunction, updateParticleSystems };
|
|
2718
|
+
export { type BezierCurve, type BezierPoint, type Box, type Burst, type BurstState, type Circle, type CollisionPlaneConfig, CollisionPlaneMode, type Cone, type Constant, type CurveBase, type CurveFunction, CurveFunctionId, type CycleData, type EasingCurve, type Emission, EmitFrom, type ForceFieldConfig, ForceFieldFalloff, ForceFieldType, type GeneralData, LifeTimeCurve, type LifetimeCurve, type MappedAttributes, type MeshConfig, type MinMaxColor, type Noise, type NoiseConfig, type NormalizedCollisionPlaneConfig, type NormalizedForceFieldConfig, type NormalizedParticleSystemConfig, type ParticleSystem, type ParticleSystemConfig, type ParticleSystemInstance, type Point3D, type RandomBetweenTwoConstants, type Rectangle, type Renderer, RendererType, type Rgb, SCALAR_STRIDE, S_COLOR_A, S_COLOR_B, S_COLOR_G, S_COLOR_R, S_IS_ACTIVE, S_LIFETIME, S_ROTATION, S_SIZE, S_START_FRAME, S_START_LIFETIME, Shape, type ShapeConfig, SimulationBackend, SimulationSpace, type SoftParticlesConfig, type Sphere, type SubEmitterConfig, SubEmitterTrigger, type TextureSheetAnimation, TimeMode, type TrailConfig, type Transform, type VelocityOverLifetime, applyModifiers, blendingMap, calculateRandomPositionAndVelocityOnBox, calculateRandomPositionAndVelocityOnCircle, calculateRandomPositionAndVelocityOnCone, calculateRandomPositionAndVelocityOnRectangle, calculateRandomPositionAndVelocityOnSphere, calculateValue, createBezierCurveFunction, createDefaultMeshTexture, createDefaultParticleTexture, createParticleSystem, curveFunctionIdMap, deserializeParticleSystem, getBezierCacheSize, getCurveFunction, getCurveFunctionFromConfig, getDefaultParticleSystemConfig, isComputeCapableRenderer, isLifeTimeCurve, registerTSLMaterialFactory, removeBezierCurveFunction, resolveSimulationBackend, serializeParticleSystem, updateParticleSystems };
|