lazy-vfx 1.1.1 → 1.1.3
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 +61 -54
- package/dist/lazy-vfx.es.js +18 -19
- package/dist/lazy-vfx.umd.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# ☄️ Lazy VFX
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
*Effortless high-end visual effects for the modern web, built for React & Three.js*
|
|
4
4
|
|
|
5
5
|
Lazy VFX is a minimal, shader-driven VFX engine designed for modern web apps using React and Three.js. It abstracts away all the math and plumbing for emitters, GPU-accelerated particles, and real-time shaders, so you can stay focused on building cinematic, interactive experiences.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
[Live demo](https://lazy-vfx.vercel.app/demo) - [Fireworks demo](#) - [Wizard Game demo](#)
|
|
7
|
+
[Live demo](https://lazy-vfx.vercel.app/demo) - [Fireworks demo](https://fireworks-five-sigma.vercel.app/) - [Wizard Game demo](https://wizard-game-sable.vercel.app/)
|
|
9
8
|
|
|
10
9
|
---
|
|
11
10
|
|
|
@@ -43,7 +42,6 @@ yarn add lazy-vfx
|
|
|
43
42
|
- **VFXParticles:** Defines the particle system and its rendering properties
|
|
44
43
|
- **VFXEmitter:** Controls how and when particles are emitted into the scene
|
|
45
44
|
|
|
46
|
-
|
|
47
45
|
Add cinematic particles in seconds to any [React Three Fiber](https://docs.pmnd.rs/react-three-fiber) scene:
|
|
48
46
|
|
|
49
47
|
```jsx
|
|
@@ -74,11 +72,11 @@ function Experience() {
|
|
|
74
72
|
name="sparks" // A unique identifier for this particle system
|
|
75
73
|
settings={{
|
|
76
74
|
nParticals: 10000, // Maximum number of particles to allocate
|
|
77
|
-
intensity:
|
|
75
|
+
intensity: 2, // Brightness multiplier
|
|
78
76
|
renderMode: "billboard", // "billboard" or "mesh" or "stretchBillboard"
|
|
79
77
|
fadeAlpha: [0.5, 0.5], // Opacity fade in/out settings
|
|
80
78
|
fadeSize: [0, 0], // Size fade in/out settings
|
|
81
|
-
gravity: [0, -
|
|
79
|
+
gravity: [0, -20, 0], // Apply gravity (x, y, z)
|
|
82
80
|
}}
|
|
83
81
|
alphaMap={text}
|
|
84
82
|
// geometry={<sphereGeometry />}
|
|
@@ -87,12 +85,12 @@ function Experience() {
|
|
|
87
85
|
{/* Step 2: Define your emitter */}
|
|
88
86
|
<VFXEmitter
|
|
89
87
|
debug // Show debug visualization
|
|
90
|
-
emitter="
|
|
88
|
+
emitter="sparks" // Target the particle system by name
|
|
91
89
|
settings={{
|
|
92
90
|
duration: 4, // Emission cycle duration in seconds
|
|
93
91
|
delay: 0, // Time delay before starting emission
|
|
94
92
|
nbParticles: 10000, // Number of particles to emit per cycle
|
|
95
|
-
spawnMode: "
|
|
93
|
+
spawnMode: "time", // Emission mode: 'time' or 'burst'
|
|
96
94
|
loop: true, // Continuously emit particles (only if `spawnMode` is 'time')
|
|
97
95
|
|
|
98
96
|
// Position range (min/max)
|
|
@@ -107,20 +105,20 @@ function Experience() {
|
|
|
107
105
|
rotationSpeedMax: [0, 0, 0],
|
|
108
106
|
|
|
109
107
|
// Particle lifetime range [min, max]
|
|
110
|
-
particlesLifetime: [0.1,
|
|
108
|
+
particlesLifetime: [0.1, 5],
|
|
111
109
|
|
|
112
110
|
// Particle speed range [min, max]
|
|
113
|
-
speed: [1,
|
|
111
|
+
speed: [1, 10],
|
|
114
112
|
|
|
115
113
|
// Direction range (min/max)
|
|
116
114
|
directionMin: [-0.5, 0, -0.5],
|
|
117
115
|
directionMax: [0.5, 1, 0.5],
|
|
118
116
|
|
|
119
117
|
// Color at start - an array of strings for random selection
|
|
120
|
-
colorStart: ["#
|
|
118
|
+
colorStart: ["#ffe500", "#ffe500"],
|
|
121
119
|
|
|
122
120
|
// Color at end - an array of strings for random selection
|
|
123
|
-
colorEnd: ["#
|
|
121
|
+
colorEnd: ["#ffe500", "#ffffff"],
|
|
124
122
|
|
|
125
123
|
// Particle size range [min, max]
|
|
126
124
|
size: [0.1, 0.5],
|
|
@@ -130,6 +128,7 @@ function Experience() {
|
|
|
130
128
|
);
|
|
131
129
|
}
|
|
132
130
|
```
|
|
131
|
+
|
|
133
132
|
---
|
|
134
133
|
|
|
135
134
|
## Custom Geometry Example
|
|
@@ -169,6 +168,7 @@ const CustomParticles = () => {
|
|
|
169
168
|
```
|
|
170
169
|
|
|
171
170
|
**Note:**
|
|
171
|
+
|
|
172
172
|
- Ensure the GLTF file at `/models/sword.glb` has a node named `Sword`.
|
|
173
173
|
- If your model's node hierarchy is different, adjust `nodes.Sword.geometry` accordingly.
|
|
174
174
|
|
|
@@ -176,61 +176,68 @@ const CustomParticles = () => {
|
|
|
176
176
|
|
|
177
177
|
### VFXParticles Component
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
|
|
|
184
|
-
|
|
|
179
|
+
|
|
180
|
+
| Property | Type | Description |
|
|
181
|
+
| -------- | ------------- | ------------------------------------------------ |
|
|
182
|
+
| name | string | Unique identifier for this particle system |
|
|
183
|
+
| settings | object | Configuration options for particles |
|
|
184
|
+
| alphaMap | THREE.Texture | Optional texture for particle alpha/transparency |
|
|
185
|
+
| geometry | ReactElement | Optional custom geometry for particles |
|
|
186
|
+
|
|
185
187
|
|
|
186
188
|
#### VFXParticles Settings
|
|
187
189
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
|
191
|
-
|
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
|
|
|
195
|
-
|
|
|
196
|
-
|
|
|
190
|
+
|
|
191
|
+
| Setting | Type | Default | Description |
|
|
192
|
+
| ------------ | ------------------------ | ---------------- | ---------------------------------------- |
|
|
193
|
+
| nbParticles | number | 1000 | Maximum number of particles |
|
|
194
|
+
| intensity | number | 1 | Brightness multiplier |
|
|
195
|
+
| renderMode | 'billboard' | 'mesh' | 'stretchBillboard' |
|
|
196
|
+
| fadeSize | [number, number] | [0.1, 0.9] | Size fade in/out range (0-1 of lifetime) |
|
|
197
|
+
| fadeAlpha | [number, number] | [0, 1.0] | Opacity fade in/out range |
|
|
198
|
+
| gravity | [number, number, number] | [0, 0, 0] | Gravity force applied to particles |
|
|
199
|
+
| blendingMode | THREE.Blending | AdditiveBlending | How particles blend with the scene |
|
|
200
|
+
|
|
197
201
|
|
|
198
202
|
---
|
|
199
203
|
|
|
200
204
|
### VFXEmitter Component
|
|
201
205
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
|
|
|
206
|
+
|
|
207
|
+
| Property | Type | Description |
|
|
208
|
+
| -------- | ------- | ------------------------------------------- |
|
|
209
|
+
| emitter | string | Name of the target particle system |
|
|
210
|
+
| settings | object | Configuration options for emission behavior |
|
|
211
|
+
| debug | boolean | Show Leva controls to adjust settings |
|
|
212
|
+
|
|
207
213
|
|
|
208
214
|
#### VFXEmitter Settings
|
|
209
215
|
|
|
210
|
-
| Setting | Type | Default | Description |
|
|
211
|
-
|---------------------|-----------------------------|---------------------------|-----------------------------------------------------|
|
|
212
|
-
| loop | boolean | true | Continuously emit particles |
|
|
213
|
-
| duration | number | 1 | Emission cycle duration in seconds |
|
|
214
|
-
| nbParticles | number | 100 | Number of particles to emit per cycle |
|
|
215
|
-
| spawnMode | 'time' \| 'burst' | 'time' | How particles are spawned |
|
|
216
|
-
| delay | number | 0 | Time delay before starting emission |
|
|
217
|
-
| particlesLifetime | [number, number] | [0.1, 1] | Particle lifetime range [min, max] |
|
|
218
|
-
| startPositionMin | [number, number, number] | [-0.1, -0.1, -0.1] | Minimum start position |
|
|
219
|
-
| startPositionMax | [number, number, number] | [0.1, 0.1, 0.1] | Maximum start position |
|
|
220
|
-
| startRotationMin | [number, number, number] | [0, 0, 0] | Minimum start rotation |
|
|
221
|
-
| startRotationMax | [number, number, number] | [0, 0, 0] | Maximum start rotation |
|
|
222
|
-
| rotationSpeedMin | [number, number, number] | [0, 0, 0] | Minimum rotation speed |
|
|
223
|
-
| rotationSpeedMax | [number, number, number] | [0, 0, 0] | Maximum rotation speed |
|
|
224
|
-
| directionMin | [number, number, number] | [-1, 0, -1] | Minimum emission direction |
|
|
225
|
-
| directionMax | [number, number, number] | [1, 1, 1] | Maximum emission direction |
|
|
226
|
-
| size | [number, number] | [0.01, 0.25] | Particle size range [min, max] |
|
|
227
|
-
| speed | [number, number] | [1, 12] | Particle speed range [min, max] |
|
|
228
|
-
| colorStart | string[] | ['white'] | Colors at start (randomly selected) |
|
|
229
|
-
| colorEnd | string[] | ['white'] | Colors at end (randomly selected) |
|
|
230
216
|
|
|
231
|
-
|
|
217
|
+
| Setting | Type | Default | Description |
|
|
218
|
+
| ----------------- | ------------------------ | ------------------ | ------------------------------------- |
|
|
219
|
+
| loop | boolean | true | Continuously emit particles |
|
|
220
|
+
| duration | number | 1 | Emission cycle duration in seconds |
|
|
221
|
+
| nbParticles | number | 100 | Number of particles to emit per cycle |
|
|
222
|
+
| spawnMode | 'time' | 'burst' | 'time' |
|
|
223
|
+
| delay | number | 0 | Time delay before starting emission |
|
|
224
|
+
| particlesLifetime | [number, number] | [0.1, 1] | Particle lifetime range [min, max] |
|
|
225
|
+
| startPositionMin | [number, number, number] | [-0.1, -0.1, -0.1] | Minimum start position |
|
|
226
|
+
| startPositionMax | [number, number, number] | [0.1, 0.1, 0.1] | Maximum start position |
|
|
227
|
+
| startRotationMin | [number, number, number] | [0, 0, 0] | Minimum start rotation |
|
|
228
|
+
| startRotationMax | [number, number, number] | [0, 0, 0] | Maximum start rotation |
|
|
229
|
+
| rotationSpeedMin | [number, number, number] | [0, 0, 0] | Minimum rotation speed |
|
|
230
|
+
| rotationSpeedMax | [number, number, number] | [0, 0, 0] | Maximum rotation speed |
|
|
231
|
+
| directionMin | [number, number, number] | [-1, 0, -1] | Minimum emission direction |
|
|
232
|
+
| directionMax | [number, number, number] | [1, 1, 1] | Maximum emission direction |
|
|
233
|
+
| size | [number, number] | [0.01, 0.25] | Particle size range [min, max] |
|
|
234
|
+
| speed | [number, number] | [1, 12] | Particle speed range [min, max] |
|
|
235
|
+
| colorStart | string[] | ['white'] | Colors at start (randomly selected) |
|
|
236
|
+
| colorEnd | string[] | ['white'] | Colors at end (randomly selected) |
|
|
237
|
+
|
|
232
238
|
|
|
239
|
+
---
|
|
233
240
|
|
|
234
241
|
## 📄 License
|
|
235
242
|
|
|
236
|
-
MIT © [Dev-Sameerkhan](https://github.com/Dev-Sameer-Khan)
|
|
243
|
+
MIT © [Dev-Sameerkhan](https://github.com/Dev-Sameer-Khan)
|
package/dist/lazy-vfx.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Ae, { useRef as F, useEffect as Se, forwardRef as he, useState as xe, useImperativeHandle as _e, useCallback as we, useMemo as ae } from "react";
|
|
2
2
|
import { useFrame as ye } from "@react-three/fiber";
|
|
3
3
|
import { Vector3 as te, Quaternion as Re, Euler as se, Matrix4 as Me, Color as Te, PlaneGeometry as Ce, AdditiveBlending as Oe, DynamicDrawUsage as W } from "three";
|
|
4
4
|
import { useControls as ce, button as le, folder as Z } from "leva";
|
|
@@ -54,7 +54,7 @@ function Fe() {
|
|
|
54
54
|
return e.$$typeof === M ? null : e.displayName || e.name || null;
|
|
55
55
|
if (typeof e == "string") return e;
|
|
56
56
|
switch (e) {
|
|
57
|
-
case
|
|
57
|
+
case h:
|
|
58
58
|
return "Fragment";
|
|
59
59
|
case D:
|
|
60
60
|
return "Profiler";
|
|
@@ -71,7 +71,7 @@ function Fe() {
|
|
|
71
71
|
switch (typeof e.tag == "number" && console.error(
|
|
72
72
|
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
73
73
|
), e.$$typeof) {
|
|
74
|
-
case
|
|
74
|
+
case A:
|
|
75
75
|
return "Portal";
|
|
76
76
|
case _:
|
|
77
77
|
return e.displayName || "Context";
|
|
@@ -112,7 +112,7 @@ function Fe() {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
function a(e) {
|
|
115
|
-
if (e ===
|
|
115
|
+
if (e === h) return "<>";
|
|
116
116
|
if (typeof e == "object" && e !== null && e.$$typeof === y)
|
|
117
117
|
return "<...>";
|
|
118
118
|
try {
|
|
@@ -241,7 +241,7 @@ React keys must be passed directly to JSX without using spread:
|
|
|
241
241
|
function z(e) {
|
|
242
242
|
return typeof e == "object" && e !== null && e.$$typeof === S;
|
|
243
243
|
}
|
|
244
|
-
var s =
|
|
244
|
+
var s = Ae, S = Symbol.for("react.transitional.element"), A = Symbol.for("react.portal"), h = Symbol.for("react.fragment"), x = Symbol.for("react.strict_mode"), D = Symbol.for("react.profiler"), N = Symbol.for("react.consumer"), _ = Symbol.for("react.context"), E = Symbol.for("react.forward_ref"), f = Symbol.for("react.suspense"), Y = Symbol.for("react.suspense_list"), $ = Symbol.for("react.memo"), y = Symbol.for("react.lazy"), w = Symbol.for("react.activity"), M = Symbol.for("react.client.reference"), C = s.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, L = Object.prototype.hasOwnProperty, U = Array.isArray, I = console.createTask ? console.createTask : function() {
|
|
245
245
|
return null;
|
|
246
246
|
};
|
|
247
247
|
s = {
|
|
@@ -253,7 +253,7 @@ React keys must be passed directly to JSX without using spread:
|
|
|
253
253
|
s,
|
|
254
254
|
i
|
|
255
255
|
)(), G = I(a(i)), j = {};
|
|
256
|
-
q.Fragment =
|
|
256
|
+
q.Fragment = h, q.jsx = function(e, t, u) {
|
|
257
257
|
var d = 1e4 > C.recentlyCreatedOwnerStacks++;
|
|
258
258
|
return n(
|
|
259
259
|
e,
|
|
@@ -444,7 +444,7 @@ const De = ({ settings: o, onChange: v, onRestart: l }) => {
|
|
|
444
444
|
}
|
|
445
445
|
r(...a);
|
|
446
446
|
}
|
|
447
|
-
})), K = new te(), oe = new Re(), Ne = new se(), ee = new se(), Le = new te(), Xe =
|
|
447
|
+
})), K = new te(), oe = new Re(), Ne = new se(), ee = new se(), Le = new te(), Xe = he(
|
|
448
448
|
({ debug: o, emitter: v, settings: l = {}, ...a }, r) => {
|
|
449
449
|
const [
|
|
450
450
|
{
|
|
@@ -459,8 +459,8 @@ const De = ({ settings: o, onChange: v, onRestart: l }) => {
|
|
|
459
459
|
particlesLifetime: z = [0.1, 1],
|
|
460
460
|
speed: s = [5, 20],
|
|
461
461
|
size: S = [0.1, 1],
|
|
462
|
-
startPositionMin:
|
|
463
|
-
startPositionMax:
|
|
462
|
+
startPositionMin: A = [-1, -1, -1],
|
|
463
|
+
startPositionMax: h = [1, 1, 1],
|
|
464
464
|
startRotationMin: x = [0, 0, 0],
|
|
465
465
|
startRotationMax: D = [0, 0, 0],
|
|
466
466
|
rotationSpeedMin: N = [0, 0, 0],
|
|
@@ -488,9 +488,9 @@ const De = ({ settings: o, onChange: v, onRestart: l }) => {
|
|
|
488
488
|
const j = g(S[0], S[1]), e = n[me(0, n.length - 1)];
|
|
489
489
|
return {
|
|
490
490
|
position: [
|
|
491
|
-
K.x + g(
|
|
492
|
-
K.y + g(
|
|
493
|
-
K.z + g(
|
|
491
|
+
K.x + g(A[0], h[0]),
|
|
492
|
+
K.y + g(A[1], h[1]),
|
|
493
|
+
K.z + g(A[2], h[2])
|
|
494
494
|
],
|
|
495
495
|
direction: [
|
|
496
496
|
g(E[0], f[0]),
|
|
@@ -673,13 +673,13 @@ var Ue = `varying vec2 vUv;
|
|
|
673
673
|
const ve = new te(), pe = new se(), ge = new Re(), Ee = new te(1, 1, 1), be = new Me(), k = new Te(), Ge = ({ name: o, settings: v = {}, alphaMap: l, geometry: a }) => {
|
|
674
674
|
const {
|
|
675
675
|
nbParticles: r = 1e3,
|
|
676
|
-
intensity: i =
|
|
676
|
+
intensity: i = 2,
|
|
677
677
|
renderMode: p = "mesh",
|
|
678
678
|
fadeSize: c = [0.1, 0.9],
|
|
679
679
|
fadeAlpha: T = [0, 1],
|
|
680
680
|
gravity: R = [0, 0, 0]
|
|
681
681
|
} = v, n = F(), P = ae(() => new Ce(0.5, 0.5), []), z = () => {
|
|
682
|
-
if (!
|
|
682
|
+
if (!A.current || !n.current)
|
|
683
683
|
return;
|
|
684
684
|
[
|
|
685
685
|
n.current.instanceMatrix,
|
|
@@ -697,8 +697,8 @@ const ve = new te(), pe = new se(), ge = new Re(), Ee = new te(1, 1, 1), be = ne
|
|
|
697
697
|
S.current * f.itemSize,
|
|
698
698
|
s.current * f.itemSize - S.current * f.itemSize
|
|
699
699
|
), f.needsUpdate = !0;
|
|
700
|
-
}), S.current = s.current,
|
|
701
|
-
}, s = F(0), S = F(0),
|
|
700
|
+
}), S.current = s.current, A.current = !1;
|
|
701
|
+
}, s = F(0), S = F(0), A = F(!1), h = (E, f) => {
|
|
702
702
|
const Y = n.current.geometry.getAttribute("instanceColor"), $ = n.current.geometry.getAttribute("instanceColorEnd"), y = n.current.geometry.getAttribute("instanceDirection"), w = n.current.geometry.getAttribute("instanceLifetime"), M = n.current.geometry.getAttribute("instanceSpeed"), C = n.current.geometry.getAttribute(
|
|
703
703
|
"instanceRotationSpeed"
|
|
704
704
|
);
|
|
@@ -723,7 +723,7 @@ const ve = new te(), pe = new se(), ge = new Re(), Ee = new te(1, 1, 1), be = ne
|
|
|
723
723
|
s.current * 3
|
|
724
724
|
), y.set(O, s.current * 3), w.set(G, s.current * 2), M.set([t], s.current), C.set(V, s.current * 3), s.current++, s.current = s.current % r;
|
|
725
725
|
}
|
|
726
|
-
n.current.instanceMatrix.needsUpdate = !0, Y.needsUpdate = !0, $.needsUpdate = !0, y.needsUpdate = !0, w.needsUpdate = !0, M.needsUpdate = !0, C.needsUpdate = !0,
|
|
726
|
+
n.current.instanceMatrix.needsUpdate = !0, Y.needsUpdate = !0, $.needsUpdate = !0, y.needsUpdate = !0, w.needsUpdate = !0, M.needsUpdate = !0, C.needsUpdate = !0, A.current = !0;
|
|
727
727
|
}, [x] = xe({
|
|
728
728
|
instanceColor: new Float32Array(r * 3),
|
|
729
729
|
instanceColorEnd: new Float32Array(r * 3),
|
|
@@ -732,7 +732,7 @@ const ve = new te(), pe = new se(), ge = new Re(), Ee = new te(1, 1, 1), be = ne
|
|
|
732
732
|
instanceSpeed: new Float32Array(r * 1),
|
|
733
733
|
instanceRotationSpeed: new Float32Array(r * 3)
|
|
734
734
|
}), D = ie((E) => E.registerEmitter), N = ie((E) => E.unregisterEmitter);
|
|
735
|
-
Se(() => (D(o,
|
|
735
|
+
Se(() => (D(o, h), () => {
|
|
736
736
|
N(o);
|
|
737
737
|
}), []);
|
|
738
738
|
const _ = ae(
|
|
@@ -763,7 +763,6 @@ const ve = new te(), pe = new se(), ge = new Re(), Ee = new te(1, 1, 1), be = ne
|
|
|
763
763
|
vertexShader: Ue,
|
|
764
764
|
fragmentShader: Ie,
|
|
765
765
|
blending: Oe,
|
|
766
|
-
depthTest: !1,
|
|
767
766
|
depthWrite: !1,
|
|
768
767
|
transparent: !0,
|
|
769
768
|
defines: {
|
package/dist/lazy-vfx.umd.js
CHANGED
|
@@ -149,4 +149,4 @@ React keys must be passed directly to JSX without using spread:
|
|
|
149
149
|
#else
|
|
150
150
|
gl_FragColor = vec4(color, alpha);
|
|
151
151
|
#endif
|
|
152
|
-
}`;const fe=new m.Vector3,de=new m.Euler,me=new m.Quaternion,ve=new m.Vector3(1,1,1),pe=new m.Matrix4,k=new m.Color,we=({name:o,settings:g={},alphaMap:u,geometry:a})=>{const{nbParticles:r=1e3,intensity:i=
|
|
152
|
+
}`;const fe=new m.Vector3,de=new m.Euler,me=new m.Quaternion,ve=new m.Vector3(1,1,1),pe=new m.Matrix4,k=new m.Color,we=({name:o,settings:g={},alphaMap:u,geometry:a})=>{const{nbParticles:r=1e3,intensity:i=2,renderMode:b="mesh",fadeSize:l=[.1,.9],fadeAlpha:F=[0,1],gravity:_=[0,0,0]}=g,n=c.useRef(),w=c.useMemo(()=>new m.PlaneGeometry(.5,.5),[]),N=()=>{if(!M.current||!n.current)return;[n.current.instanceMatrix,n.current.geometry.getAttribute("instanceColor"),n.current.geometry.getAttribute("instanceColorEnd"),n.current.geometry.getAttribute("instanceDirection"),n.current.geometry.getAttribute("instanceLifetime"),n.current.geometry.getAttribute("instanceSpeed"),n.current.geometry.getAttribute("instanceRotationSpeed")].forEach(d=>{d.clearUpdateRanges(),R.current>s.current?(d.addUpdateRange(0,s.current*d.itemSize),d.addUpdateRange(R.current*d.itemSize,r*d.itemSize-R.current*d.itemSize)):d.addUpdateRange(R.current*d.itemSize,s.current*d.itemSize-R.current*d.itemSize),d.needsUpdate=!0}),R.current=s.current,M.current=!1},s=c.useRef(0),R=c.useRef(0),M=c.useRef(!1),h=(x,d)=>{const B=n.current.geometry.getAttribute("instanceColor"),W=n.current.geometry.getAttribute("instanceColorEnd"),A=n.current.geometry.getAttribute("instanceDirection"),C=n.current.geometry.getAttribute("instanceLifetime"),j=n.current.geometry.getAttribute("instanceSpeed"),D=n.current.geometry.getAttribute("instanceRotationSpeed");for(let V=0;V<x;V++){s.current>=r&&(s.current=0);const{scale:Y,rotation:X,rotationSpeed:G,position:Z,direction:z,lifetime:K,colorStart:U,colorEnd:e,speed:t}=d();fe.set(...Z),de.set(...X),me.setFromEuler(de),ve.set(...Y),pe.compose(fe,me,ve),n.current.setMatrixAt(s.current,pe),k.set(U),B.set([k.r,k.g,k.b],s.current*3),k.set(e),W.set([k.r,k.g,k.b],s.current*3),A.set(z,s.current*3),C.set(K,s.current*2),j.set([t],s.current),D.set(G,s.current*3),s.current++,s.current=s.current%r}n.current.instanceMatrix.needsUpdate=!0,B.needsUpdate=!0,W.needsUpdate=!0,A.needsUpdate=!0,C.needsUpdate=!0,j.needsUpdate=!0,D.needsUpdate=!0,M.current=!0},[P]=c.useState({instanceColor:new Float32Array(r*3),instanceColorEnd:new Float32Array(r*3),instanceDirection:new Float32Array(r*3),instanceLifetime:new Float32Array(r*2),instanceSpeed:new Float32Array(r*1),instanceRotationSpeed:new Float32Array(r*3)}),L=re(x=>x.registerEmitter),I=re(x=>x.unregisterEmitter);c.useEffect(()=>(L(o,h),()=>{I(o)}),[]);const T=c.useMemo(()=>({uTime:{value:0},uIntensity:{value:i},uFadeSize:{value:l},uFadeAlpha:{value:F},uGravity:{value:_},uAlphaMap:{value:u}}),[]);return ie.useFrame(({clock:x})=>{T&&(T.uTime.value=x.elapsedTime)}),S.jsx(S.Fragment,{children:S.jsxs("instancedMesh",{args:[w,null,r],ref:n,onBeforeRender:N,children:[a,S.jsx("shaderMaterial",{uniforms:T,vertexShader:Ae,fragmentShader:_e,blending:m.AdditiveBlending,depthWrite:!1,transparent:!0,defines:{BILLBOARD_MODE:b==="billboard",MESH_MODE:b==="mesh",ALPHAMAP:!!u}}),S.jsx("instancedBufferAttribute",{attach:"geometry-attributes-instanceColor",args:[P.instanceColor],itemSize:3,count:r,usage:m.DynamicDrawUsage}),S.jsx("instancedBufferAttribute",{attach:"geometry-attributes-instanceColorEnd",args:[P.instanceColorEnd],itemSize:3,count:r,usage:m.DynamicDrawUsage}),S.jsx("instancedBufferAttribute",{attach:"geometry-attributes-instanceDirection",args:[P.instanceDirection],itemSize:3,count:r,usage:m.DynamicDrawUsage}),S.jsx("instancedBufferAttribute",{attach:"geometry-attributes-instanceLifetime",args:[P.instanceLifetime],itemSize:2,count:r,usage:m.DynamicDrawUsage}),S.jsx("instancedBufferAttribute",{attach:"geometry-attributes-instanceSpeed",args:[P.instanceSpeed],itemSize:1,count:r,usage:m.DynamicDrawUsage}),S.jsx("instancedBufferAttribute",{attach:"geometry-attributes-instanceRotationSpeed",args:[P.instanceRotationSpeed],itemSize:3,count:r,usage:m.DynamicDrawUsage})]})})};y.VFXEmitter=Pe,y.VFXParticles=we,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})}));
|