vanilla-vfx 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # r3f-vfx
1
+ # ✨ Three VFX ✨
2
2
 
3
- High-performance GPU-accelerated particle system for Three.js WebGPU with React Three Fiber.
3
+ High-performance GPU-accelerated particle system for Three.js WebGPU.
4
+
5
+ Available for React Three Fiber (R3F), and experimentally for vanilla Three.js, TresJS (Vue), and Threlte (Svelte).
4
6
 
5
7
  ## Features
6
8
 
@@ -11,25 +13,21 @@ High-performance GPU-accelerated particle system for Three.js WebGPU with React
11
13
  - 📊 **Curve-based Control** - Bezier curves for size, opacity, velocity, and rotation over lifetime
12
14
  - 🔗 **Emitter System** - Decoupled emitters that can share particle systems
13
15
  - ⚡ **WebGPU Native** - Built specifically for Three.js WebGPU renderer
16
+ - 🐢 **WebGL fallback** – Three VFX targets WebGPU ([79% global support](https://caniuse.com/webgpu)) but provides a CPU fallback
14
17
 
15
- ## Installation
18
+ ## Quick Start
16
19
 
17
- ```bash
18
- npm install r3f-vfx
19
- ```
20
+ ### React Three Fiber
20
21
 
21
- ### Peer Dependencies
22
+ Add it to your React Three Fiber project with:
22
23
 
23
24
  ```bash
24
- npm install three @react-three/fiber react
25
+ npm install r3f-vfx
25
26
  ```
26
27
 
27
- ## Quick Start
28
-
29
28
  ```tsx
30
29
  import { Canvas } from '@react-three/fiber'
31
- import { VFXParticles, Appearance, EmitterShape } from 'r3f-vfx'
32
- import * as THREE from 'three/webgpu'
30
+ import { VFXParticles } from 'r3f-vfx'
33
31
 
34
32
  function App() {
35
33
  return (
@@ -40,7 +38,64 @@ function App() {
40
38
  }
41
39
  ```
42
40
 
43
- That's it, start designing in the debug panel, then copy JSX
41
+ ### Vanilla Three.js (Experimental)
42
+
43
+ Add it to your vanilla Three.js project with:
44
+
45
+ ```bash
46
+ npm install vanilla-vfx
47
+ ```
48
+
49
+ ```ts
50
+ import { VFXParticles } from 'vanilla-vfx'
51
+
52
+ const particles = new VFXParticles(renderer, { debug: true })
53
+ scene.add(particles.renderObject)
54
+ ```
55
+
56
+ ### TresJS / Vue (Experimental)
57
+
58
+ Add it to your TresJS project with:
59
+
60
+ ```bash
61
+ npm install tres-vfx
62
+ ```
63
+
64
+ ```vue
65
+ <script setup>
66
+ import { TresCanvas } from '@tresjs/core'
67
+ import { VFXParticles } from 'tres-vfx'
68
+ </script>
69
+
70
+ <template>
71
+ <TresCanvas>
72
+ <VFXParticles debug />
73
+ </TresCanvas>
74
+ </template>
75
+ ```
76
+
77
+ ### Threlte / Svelte (Experimental)
78
+
79
+ Add it to your Threlte project with:
80
+
81
+ ```bash
82
+ npm install threlte-vfx
83
+ ```
84
+
85
+ ```svelte
86
+ <script>
87
+ import { Canvas } from '@threlte/core'
88
+ import VFXParticles from 'threlte-vfx/VFXParticles.svelte'
89
+ </script>
90
+
91
+ <Canvas>
92
+ <VFXParticles debug />
93
+ </Canvas>
94
+ ```
95
+
96
+ ## How to use
97
+
98
+ Use the debug panel to design your effect, then copy the generated code and replace it in your code.
44
99
 
45
100
  ## API Reference
46
101
 
package/dist/index.d.ts CHANGED
@@ -4,8 +4,6 @@ export { Appearance, AttractorConfig, AttractorType, BaseParticleProps, Blending
4
4
 
5
5
  type VFXParticlesOptions = VFXParticleSystemOptions & {
6
6
  debug?: boolean;
7
- /** Optional fallback Object3D to display when WebGPU is not available */
8
- fallback?: THREE.Object3D;
9
7
  };
10
8
  declare class VFXParticles {
11
9
  readonly group: THREE.Group;
@@ -16,7 +14,6 @@ declare class VFXParticles {
16
14
  private emitAccumulator;
17
15
  private debug;
18
16
  private initialized;
19
- private disabled;
20
17
  constructor(renderer: THREE.WebGPURenderer, options?: VFXParticlesOptions);
21
18
  get object3D(): THREE.Group;
22
19
  get uniforms(): Record<string, {
package/dist/index.js CHANGED
@@ -14618,12 +14618,12 @@ var VarNode = class extends Node {
14618
14618
  generate(builder) {
14619
14619
  const { node, name, readOnly } = this;
14620
14620
  const { renderer } = builder;
14621
- const isWebGPUBackend3 = renderer.backend.isWebGPUBackend === true;
14621
+ const isWebGPUBackend2 = renderer.backend.isWebGPUBackend === true;
14622
14622
  let isDeterministic = false;
14623
14623
  let shouldTreatAsReadOnly = false;
14624
14624
  if (readOnly) {
14625
14625
  isDeterministic = builder.isDeterministic(node);
14626
- shouldTreatAsReadOnly = isWebGPUBackend3 ? readOnly : isDeterministic;
14626
+ shouldTreatAsReadOnly = isWebGPUBackend2 ? readOnly : isDeterministic;
14627
14627
  }
14628
14628
  const nodeType = this.getNodeType(builder);
14629
14629
  if (nodeType == "void") {
@@ -14639,7 +14639,7 @@ var VarNode = class extends Node {
14639
14639
  const propertyName = builder.getPropertyName(nodeVar);
14640
14640
  let declarationPrefix = propertyName;
14641
14641
  if (shouldTreatAsReadOnly) {
14642
- if (isWebGPUBackend3) {
14642
+ if (isWebGPUBackend2) {
14643
14643
  declarationPrefix = isDeterministic ? `const ${propertyName}` : `let ${propertyName}`;
14644
14644
  } else {
14645
14645
  const count = node.getArrayCount(builder);
@@ -20247,37 +20247,21 @@ if (typeof Float16Array !== "undefined") {
20247
20247
  // src/VFXParticles.ts
20248
20248
  import {
20249
20249
  VFXParticleSystem,
20250
- isWebGPUBackend,
20251
20250
  needsRecreation,
20252
20251
  updateUniformsPartial
20253
20252
  } from "core-vfx";
20254
- var warnedWebGL = false;
20255
20253
  var VFXParticles = class {
20256
20254
  constructor(renderer, options) {
20257
20255
  this.system = null;
20258
20256
  this.isEmitting = true;
20259
20257
  this.emitAccumulator = 0;
20260
20258
  this.initialized = false;
20261
- this.disabled = false;
20262
20259
  var _a;
20263
20260
  this.renderer = renderer;
20264
20261
  this.debug = (_a = options == null ? void 0 : options.debug) != null ? _a : false;
20265
20262
  this.config = __spreadValues({}, options);
20266
20263
  delete this.config.debug;
20267
- delete this.config.fallback;
20268
20264
  this.group = new Group();
20269
- if (!isWebGPUBackend(renderer)) {
20270
- this.disabled = true;
20271
- if (!warnedWebGL) {
20272
- warnedWebGL = true;
20273
- console.warn(
20274
- "r3f-vfx: WebGPU backend not detected. Particle system disabled."
20275
- );
20276
- }
20277
- if (options == null ? void 0 : options.fallback) {
20278
- this.group.add(options.fallback);
20279
- }
20280
- }
20281
20265
  }
20282
20266
  get object3D() {
20283
20267
  return this.group;
@@ -20287,7 +20271,6 @@ var VFXParticles = class {
20287
20271
  return this.system ? this.system.uniforms : null;
20288
20272
  }
20289
20273
  async init() {
20290
- if (this.disabled) return;
20291
20274
  if (this.initialized) return;
20292
20275
  if (this.debug) {
20293
20276
  const { DEFAULT_VALUES } = await import("debug-vfx");
@@ -20305,7 +20288,6 @@ var VFXParticles = class {
20305
20288
  }
20306
20289
  }
20307
20290
  update(delta) {
20308
- if (this.disabled) return;
20309
20291
  if (!this.system || !this.system.initialized) return;
20310
20292
  if (this.isEmitting) {
20311
20293
  const delay = this.system.normalizedProps.delay;
@@ -20337,7 +20319,6 @@ var VFXParticles = class {
20337
20319
  this.initialized = false;
20338
20320
  }
20339
20321
  spawn(x = 0, y = 0, z = 0, count, overrides) {
20340
- if (this.disabled) return;
20341
20322
  if (!this.system) return;
20342
20323
  this.system.spawn(
20343
20324
  x,
@@ -20348,23 +20329,19 @@ var VFXParticles = class {
20348
20329
  );
20349
20330
  }
20350
20331
  start() {
20351
- if (this.disabled) return;
20352
20332
  this.isEmitting = true;
20353
20333
  this.emitAccumulator = 0;
20354
20334
  if (this.system) this.system.start();
20355
20335
  }
20356
20336
  stop() {
20357
- if (this.disabled) return;
20358
20337
  this.isEmitting = false;
20359
20338
  if (this.system) this.system.stop();
20360
20339
  }
20361
20340
  clear() {
20362
- if (this.disabled) return;
20363
20341
  if (this.system) this.system.clear();
20364
20342
  }
20365
20343
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20366
20344
  setProps(newValues) {
20367
- if (this.disabled) return;
20368
20345
  this.config = __spreadValues(__spreadValues({}, this.config), newValues);
20369
20346
  if (this.system && needsRecreation(this.system.features, newValues, this.config)) {
20370
20347
  this.recreateSystem();
@@ -20449,7 +20426,12 @@ import {
20449
20426
  Easing,
20450
20427
  Lighting
20451
20428
  } from "core-vfx";
20452
- import { VFXParticleSystem as VFXParticleSystem2, EmitterController, isWebGPUBackend as isWebGPUBackend2, resolveCurveTexture } from "core-vfx";
20429
+ import {
20430
+ VFXParticleSystem as VFXParticleSystem2,
20431
+ EmitterController,
20432
+ isWebGPUBackend,
20433
+ resolveCurveTexture
20434
+ } from "core-vfx";
20453
20435
  export {
20454
20436
  Appearance,
20455
20437
  AttractorType,
@@ -20460,7 +20442,7 @@ export {
20460
20442
  Lighting,
20461
20443
  VFXParticleSystem2 as VFXParticleSystem,
20462
20444
  VFXParticles,
20463
- isWebGPUBackend2 as isWebGPUBackend,
20445
+ isWebGPUBackend,
20464
20446
  resolveCurveTexture
20465
20447
  };
20466
20448
  /*! Bundled license information:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-vfx",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -24,8 +24,8 @@
24
24
  "prepublishOnly": "bun run typecheck && bun run build && bun run copy-readme"
25
25
  },
26
26
  "dependencies": {
27
- "core-vfx": "0.1.0",
28
- "debug-vfx": "0.1.0"
27
+ "core-vfx": "0.2.0",
28
+ "debug-vfx": "0.1.2"
29
29
  },
30
30
  "devDependencies": {
31
31
  "tsup": "8.5.1",