tres-vfx 0.3.0 → 0.5.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 +157 -32
- package/dist/index.d.ts +39 -3
- package/dist/index.js +55 -17
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -105,37 +105,47 @@ The main particle system component.
|
|
|
105
105
|
|
|
106
106
|
#### Basic Props
|
|
107
107
|
|
|
108
|
-
| Prop | Type | Default | Description
|
|
109
|
-
| -------------- | ----------- | ----------- |
|
|
110
|
-
| `name` | `string` | - | Register system for use with VFXEmitter
|
|
111
|
-
| `maxParticles` | `number` | `10000` | Maximum number of particles
|
|
112
|
-
| `autoStart` | `boolean` | `true` | Start emitting automatically
|
|
113
|
-
| `delay` | `number` | `0` | Seconds between emissions (0 = every frame)
|
|
114
|
-
| `emitCount` | `number` | `1` | Particles to emit per burst
|
|
115
|
-
| `position` | `[x, y, z]` | `[0, 0, 0]` | Emitter position
|
|
108
|
+
| Prop | Type | Default | Description |
|
|
109
|
+
| -------------- | ----------- | ----------- | ----------------------------------------------- |
|
|
110
|
+
| `name` | `string` | - | Register system for use with VFXEmitter |
|
|
111
|
+
| `maxParticles` | `number` | `10000` | Maximum number of particles |
|
|
112
|
+
| `autoStart` | `boolean` | `true` | Start emitting automatically |
|
|
113
|
+
| `delay` | `number` | `0` | Seconds between emissions (0 = every frame) |
|
|
114
|
+
| `emitCount` | `number` | `1` | Particles to emit per burst |
|
|
115
|
+
| `position` | `[x, y, z]` | `[0, 0, 0]` | Emitter position |
|
|
116
|
+
| `debug` | `boolean` | `false` | Show interactive debug panel (lazy-loads debug-vfx) |
|
|
116
117
|
|
|
117
118
|
#### Appearance Props
|
|
118
119
|
|
|
119
120
|
| Prop | Type | Default | Description |
|
|
120
121
|
| ------------- | ------------------------ | ------------- | ----------------------------------------------------------- |
|
|
121
122
|
| `size` | `number \| [min, max]` | `[0.1, 0.3]` | Particle size range |
|
|
122
|
-
| `colorStart` | `string[]` | `["#ffffff"]` | Starting colors (random pick)
|
|
123
|
+
| `colorStart` | `string[]` | `["#ffffff"]` | Starting colors (random pick per particle) |
|
|
123
124
|
| `colorEnd` | `string[] \| null` | `null` | Ending colors (null = no transition) |
|
|
124
125
|
| `fadeSize` | `number \| [start, end]` | `[1, 0]` | Size multiplier over lifetime |
|
|
125
126
|
| `fadeOpacity` | `number \| [start, end]` | `[1, 0]` | Opacity over lifetime |
|
|
126
127
|
| `appearance` | `Appearance` | `GRADIENT` | Shape: `DEFAULT`, `GRADIENT`, `CIRCULAR` |
|
|
127
128
|
| `intensity` | `number` | `1` | Color intensity multiplier |
|
|
128
129
|
| `blending` | `Blending` | `NORMAL` | Blend mode: `NORMAL`, `ADDITIVE`, `MULTIPLY`, `SUBTRACTIVE` |
|
|
130
|
+
| `side` | `Side` | `DOUBLE` | Face culling: `FRONT`, `BACK`, `DOUBLE` |
|
|
129
131
|
|
|
130
132
|
#### Physics Props
|
|
131
133
|
|
|
132
|
-
| Prop
|
|
133
|
-
|
|
|
134
|
-
| `lifetime`
|
|
135
|
-
| `speed`
|
|
136
|
-
| `direction`
|
|
137
|
-
| `gravity`
|
|
138
|
-
| `friction`
|
|
134
|
+
| Prop | Type | Default | Description |
|
|
135
|
+
| ------------------------- | ----------------------- | ------------------------- | ---------------------------------------------- |
|
|
136
|
+
| `lifetime` | `number \| [min, max]` | `[1, 2]` | Particle lifetime in seconds |
|
|
137
|
+
| `speed` | `number \| [min, max]` | `[0.1, 0.1]` | Initial speed |
|
|
138
|
+
| `direction` | `Range3D \| [min, max]` | `[[-1,1], [0,1], [-1,1]]` | Emission direction per axis |
|
|
139
|
+
| `gravity` | `[x, y, z]` | `[0, 0, 0]` | Gravity vector |
|
|
140
|
+
| `friction` | `FrictionConfig` | `{ intensity: 0 }` | Velocity damping |
|
|
141
|
+
| `startPositionAsDirection`| `boolean` | `false` | Use spawn offset as velocity direction (radial emission) |
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
interface FrictionConfig {
|
|
145
|
+
intensity: number // Drag amount
|
|
146
|
+
easing?: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' // Deceleration curve
|
|
147
|
+
}
|
|
148
|
+
```
|
|
139
149
|
|
|
140
150
|
#### Emitter Shape Props
|
|
141
151
|
|
|
@@ -153,14 +163,50 @@ The main particle system component.
|
|
|
153
163
|
|
|
154
164
|
| Prop | Type | Default | Description |
|
|
155
165
|
| ------------------- | ----------------------- | ---------- | ---------------------------------------------------------- |
|
|
156
|
-
| `geometry` | `BufferGeometry` | `null` | Custom particle geometry
|
|
157
|
-
| `lighting` | `Lighting` | `STANDARD` | Material: `BASIC
|
|
166
|
+
| `geometry` | `BufferGeometry` | `null` | Custom particle geometry (switches to instanced mesh mode) |
|
|
167
|
+
| `lighting` | `Lighting` | `STANDARD` | Material: `BASIC` (unlit), `STANDARD` (PBR), `PHYSICAL` (full PBR) |
|
|
168
|
+
| `lightingParams` | `LightingParams` | `null` | PBR material parameters (see below) |
|
|
158
169
|
| `shadow` | `boolean` | `false` | Enable shadow casting/receiving |
|
|
159
|
-
| `orientToDirection` | `boolean` | `false` | Orient geometry to velocity
|
|
170
|
+
| `orientToDirection` | `boolean` | `false` | Orient geometry to velocity direction |
|
|
160
171
|
| `orientAxis` | `string` | `"z"` | Axis to align: `"x"`, `"y"`, `"z"`, `"-x"`, `"-y"`, `"-z"` |
|
|
161
172
|
| `rotation` | `Range3D \| [min, max]` | `[0, 0]` | Initial rotation per axis |
|
|
162
173
|
| `rotationSpeed` | `Range3D \| [min, max]` | `[0, 0]` | Rotation speed rad/s |
|
|
163
174
|
|
|
175
|
+
**`lightingParams`** gives full control over PBR material properties when using `lighting: 'standard'` or `'physical'`:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
interface LightingParams {
|
|
179
|
+
roughness?: number // Surface roughness (0 = mirror, 1 = matte)
|
|
180
|
+
metalness?: number // Metallic factor (0 = dielectric, 1 = metal)
|
|
181
|
+
emissive?: string // Emissive color hex string
|
|
182
|
+
emissiveIntensity?: number // Emissive brightness
|
|
183
|
+
envMapIntensity?: number // Environment map strength
|
|
184
|
+
// Physical mode only:
|
|
185
|
+
clearcoat?: number // Clearcoat layer intensity
|
|
186
|
+
clearcoatRoughness?: number // Clearcoat roughness
|
|
187
|
+
transmission?: number // Glass-like transparency
|
|
188
|
+
thickness?: number // Volume thickness for transmission
|
|
189
|
+
ior?: number // Index of refraction
|
|
190
|
+
iridescence?: number // Iridescence effect intensity
|
|
191
|
+
iridescenceIOR?: number // Iridescence index of refraction
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
<VFXParticles
|
|
197
|
+
geometry={gemGeometry}
|
|
198
|
+
lighting="physical"
|
|
199
|
+
lightingParams={{
|
|
200
|
+
roughness: 0.3,
|
|
201
|
+
metalness: 0.8,
|
|
202
|
+
clearcoat: 1,
|
|
203
|
+
clearcoatRoughness: 0.1,
|
|
204
|
+
iridescence: 1,
|
|
205
|
+
iridescenceIOR: 1.5,
|
|
206
|
+
}}
|
|
207
|
+
/>
|
|
208
|
+
```
|
|
209
|
+
|
|
164
210
|
#### Stretch Props
|
|
165
211
|
|
|
166
212
|
| Prop | Type | Default | Description |
|
|
@@ -221,6 +267,79 @@ interface CollisionConfig {
|
|
|
221
267
|
}
|
|
222
268
|
```
|
|
223
269
|
|
|
270
|
+
#### Trail Props
|
|
271
|
+
|
|
272
|
+
| Prop | Type | Default | Description |
|
|
273
|
+
| ------- | ------------- | ------- | --------------------------- |
|
|
274
|
+
| `trail` | `TrailConfig` | `null` | Trail rendering via meshline |
|
|
275
|
+
|
|
276
|
+
Requires `makio-meshline` installed as a peer dependency.
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
interface TrailConfig {
|
|
280
|
+
segments?: number // Trail resolution (default: 32)
|
|
281
|
+
width?: number // Line width (default: 0.1)
|
|
282
|
+
taper?: boolean | ((t: number) => number) // Width taper (default: true)
|
|
283
|
+
opacity?: number | ((data: TrailOpacityData) => Node) // Opacity control (default: 1)
|
|
284
|
+
length?: number // History in seconds (default: 0.5)
|
|
285
|
+
showParticles?: boolean // Show particles alongside trails (default: true)
|
|
286
|
+
fragmentColorFn?: (data: TrailData) => Node // Per-pixel trail coloring
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**`taper`** controls how the trail width varies from head to tail:
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
// Default linear taper (thick at head, thin at tail)
|
|
294
|
+
trail={{ taper: true }}
|
|
295
|
+
|
|
296
|
+
// No tapering (uniform width)
|
|
297
|
+
trail={{ taper: false }}
|
|
298
|
+
|
|
299
|
+
// Custom JS callback: t goes 0 (head) → 1 (tail), return width multiplier
|
|
300
|
+
trail={{ taper: (t) => Math.sin(t * Math.PI) }} // fat middle, thin ends
|
|
301
|
+
trail={{ taper: (t) => Math.abs(Math.sin(t * Math.PI * 4)) }} // wavy
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**`opacity`** controls trail transparency. As a number it sets global opacity. As a TSL callback it runs per-vertex in the fragment shader with full access to particle data:
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
// Global opacity
|
|
308
|
+
trail={{ opacity: 0.5 }}
|
|
309
|
+
|
|
310
|
+
// TSL callback with particle data
|
|
311
|
+
trail={{
|
|
312
|
+
opacity: ({ alpha, trailProgress, progress, lifetime, position, velocity, size }) => {
|
|
313
|
+
// Fade based on trail position and particle lifetime
|
|
314
|
+
return alpha.mul(trailProgress.oneMinus()).mul(lifetime)
|
|
315
|
+
}
|
|
316
|
+
}}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Sorting Props
|
|
320
|
+
|
|
321
|
+
| Prop | Type | Default | Description |
|
|
322
|
+
| ------------------- | --------- | ------- | --------------------------------------------------- |
|
|
323
|
+
| `sortParticles` | `boolean` | `false` | Enable back-to-front depth sorting for transparency |
|
|
324
|
+
| `sortFrameInterval` | `number` | `null` | Run sort every N frames (WebGPU only, performance tuning) |
|
|
325
|
+
|
|
326
|
+
When enabled, particles are sorted by distance to camera for correct alpha blending. On WebGPU this uses a GPU bitonic sort; on WebGL fallback it uses a CPU radix sort.
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
<VFXParticles
|
|
330
|
+
sortParticles
|
|
331
|
+
sortFrameInterval={2} // Sort every other frame for better perf
|
|
332
|
+
blending="normal"
|
|
333
|
+
/>
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### Rendering Props
|
|
337
|
+
|
|
338
|
+
| Prop | Type | Default | Description |
|
|
339
|
+
| ------------- | --------- | ------- | ------------------------------------------------ |
|
|
340
|
+
| `depthTest` | `boolean` | `true` | Test against depth buffer |
|
|
341
|
+
| `renderOrder` | `number` | `0` | Three.js render order (higher = renders on top) |
|
|
342
|
+
|
|
224
343
|
#### Soft Particles Props
|
|
225
344
|
|
|
226
345
|
| Prop | Type | Default | Description |
|
|
@@ -242,25 +361,28 @@ interface CurveData {
|
|
|
242
361
|
}
|
|
243
362
|
```
|
|
244
363
|
|
|
245
|
-
| Prop | Type | Description
|
|
246
|
-
| -------------------- | ----------- |
|
|
247
|
-
| `fadeSizeCurve` | `CurveData` | Size multiplier over lifetime
|
|
248
|
-
| `fadeOpacityCurve` | `CurveData` | Opacity over lifetime
|
|
249
|
-
| `velocityCurve` | `CurveData` | Velocity multiplier (overrides friction)
|
|
250
|
-
| `rotationSpeedCurve` | `CurveData` | Rotation speed multiplier
|
|
364
|
+
| Prop | Type | Description |
|
|
365
|
+
| -------------------- | ----------- | ------------------------------------------------- |
|
|
366
|
+
| `fadeSizeCurve` | `CurveData` | Size multiplier over lifetime |
|
|
367
|
+
| `fadeOpacityCurve` | `CurveData` | Opacity over lifetime |
|
|
368
|
+
| `velocityCurve` | `CurveData` | Velocity multiplier (overrides friction) |
|
|
369
|
+
| `rotationSpeedCurve` | `CurveData` | Rotation speed multiplier |
|
|
370
|
+
| `curveTexturePath` | `string` | Path to pre-baked curve texture (faster startup) |
|
|
251
371
|
|
|
252
372
|
#### Custom Shader Props
|
|
253
373
|
|
|
254
|
-
| Prop | Type
|
|
255
|
-
| ---------------- |
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
| `
|
|
259
|
-
| `
|
|
260
|
-
| `
|
|
374
|
+
| Prop | Type | Description |
|
|
375
|
+
| ---------------- | ---------------------- | -------------------------------------- |
|
|
376
|
+
| `geometryNode` | `GeometryNodeFunction` | Geometry-mode vertex position override |
|
|
377
|
+
| `colorNode` | `NodeFunction` | Custom color shader |
|
|
378
|
+
| `opacityNode` | `NodeFunction` | Custom opacity shader |
|
|
379
|
+
| `backdropNode` | `NodeFunction` | Backdrop sampling (refraction) |
|
|
380
|
+
| `castShadowNode` | `NodeFunction` | Shadow map output |
|
|
381
|
+
| `alphaTestNode` | `NodeFunction` | Alpha test/discard |
|
|
261
382
|
|
|
262
383
|
```ts
|
|
263
384
|
type NodeFunction = (data: ParticleData, defaultColor?: Node) => Node
|
|
385
|
+
type GeometryNodeFunction = (data: ParticleData, defaultPosition: Node) => Node
|
|
264
386
|
|
|
265
387
|
interface ParticleData {
|
|
266
388
|
progress: Node // 0 → 1 over lifetime
|
|
@@ -518,6 +640,9 @@ import type {
|
|
|
518
640
|
TurbulenceConfig,
|
|
519
641
|
CollisionConfig,
|
|
520
642
|
AttractorConfig,
|
|
643
|
+
TrailConfig,
|
|
644
|
+
TrailData,
|
|
645
|
+
TrailOpacityData,
|
|
521
646
|
} from 'r3f-vfx'
|
|
522
647
|
```
|
|
523
648
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as vue from 'vue';
|
|
2
|
-
import { PropType, Ref } from 'vue';
|
|
3
|
-
import * as THREE from 'three/webgpu';
|
|
4
1
|
import * as core_vfx from 'core-vfx';
|
|
5
2
|
import { VFXParticleSystemOptions, FrictionConfig, FlipbookConfig, Rotation3DInput, StretchConfig, TurbulenceConfig, AttractorConfig, CollisionConfig, EmitterControllerOptions, CoreState } from 'core-vfx';
|
|
6
3
|
export { Appearance, AttractorConfig, AttractorType, BaseParticleProps, Blending, CollisionConfig, CurveChannel, CurveData, CurvePoint, CurveTextureResolved, CurveTextureResult, Easing, EmitterController, EmitterControllerOptions, EmitterShape, FlipbookConfig, FrictionConfig, Lighting, NormalizedParticleProps, ParticleData, Rotation3DInput, StretchConfig, TurbulenceConfig, VFXParticleSystem, VFXParticleSystemOptions, bakeCurveToArray, buildCurveTextureBin, createCombinedCurveTexture, isNonDefaultRotation, isWebGPUBackend, normalizeProps, resolveCurveTexture } from 'core-vfx';
|
|
4
|
+
import * as vue from 'vue';
|
|
5
|
+
import { PropType, Ref } from 'vue';
|
|
6
|
+
import * as THREE from 'three/webgpu';
|
|
7
7
|
|
|
8
8
|
declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
9
9
|
name: {
|
|
@@ -121,6 +121,10 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
121
121
|
type: PropType<string | number>;
|
|
122
122
|
default: "standard";
|
|
123
123
|
};
|
|
124
|
+
lightingParams: {
|
|
125
|
+
type: PropType<VFXParticleSystemOptions["lightingParams"]>;
|
|
126
|
+
default: null;
|
|
127
|
+
};
|
|
124
128
|
shadow: {
|
|
125
129
|
type: BooleanConstructor;
|
|
126
130
|
default: boolean;
|
|
@@ -149,6 +153,10 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
149
153
|
type: PropType<unknown>;
|
|
150
154
|
default: null;
|
|
151
155
|
};
|
|
156
|
+
geometryNode: {
|
|
157
|
+
type: PropType<unknown>;
|
|
158
|
+
default: null;
|
|
159
|
+
};
|
|
152
160
|
opacityNode: {
|
|
153
161
|
type: PropType<unknown>;
|
|
154
162
|
default: null;
|
|
@@ -221,6 +229,14 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
221
229
|
type: PropType<CollisionConfig | null>;
|
|
222
230
|
default: null;
|
|
223
231
|
};
|
|
232
|
+
sortParticles: {
|
|
233
|
+
type: BooleanConstructor;
|
|
234
|
+
default: boolean;
|
|
235
|
+
};
|
|
236
|
+
sortFrameInterval: {
|
|
237
|
+
type: PropType<number | null>;
|
|
238
|
+
default: null;
|
|
239
|
+
};
|
|
224
240
|
curveTexturePath: {
|
|
225
241
|
type: PropType<string | null>;
|
|
226
242
|
default: null;
|
|
@@ -351,6 +367,10 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
351
367
|
type: PropType<string | number>;
|
|
352
368
|
default: "standard";
|
|
353
369
|
};
|
|
370
|
+
lightingParams: {
|
|
371
|
+
type: PropType<VFXParticleSystemOptions["lightingParams"]>;
|
|
372
|
+
default: null;
|
|
373
|
+
};
|
|
354
374
|
shadow: {
|
|
355
375
|
type: BooleanConstructor;
|
|
356
376
|
default: boolean;
|
|
@@ -379,6 +399,10 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
379
399
|
type: PropType<unknown>;
|
|
380
400
|
default: null;
|
|
381
401
|
};
|
|
402
|
+
geometryNode: {
|
|
403
|
+
type: PropType<unknown>;
|
|
404
|
+
default: null;
|
|
405
|
+
};
|
|
382
406
|
opacityNode: {
|
|
383
407
|
type: PropType<unknown>;
|
|
384
408
|
default: null;
|
|
@@ -451,6 +475,14 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
451
475
|
type: PropType<CollisionConfig | null>;
|
|
452
476
|
default: null;
|
|
453
477
|
};
|
|
478
|
+
sortParticles: {
|
|
479
|
+
type: BooleanConstructor;
|
|
480
|
+
default: boolean;
|
|
481
|
+
};
|
|
482
|
+
sortFrameInterval: {
|
|
483
|
+
type: PropType<number | null>;
|
|
484
|
+
default: null;
|
|
485
|
+
};
|
|
454
486
|
curveTexturePath: {
|
|
455
487
|
type: PropType<string | null>;
|
|
456
488
|
default: null;
|
|
@@ -466,6 +498,7 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
466
498
|
}>> & Readonly<{}>, {
|
|
467
499
|
direction: Rotation3DInput;
|
|
468
500
|
startPosition: Rotation3DInput;
|
|
501
|
+
lightingParams: core_vfx.LightingParams | undefined;
|
|
469
502
|
name: string;
|
|
470
503
|
debug: boolean;
|
|
471
504
|
maxParticles: number;
|
|
@@ -499,6 +532,7 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
499
532
|
autoStart: boolean;
|
|
500
533
|
delay: number;
|
|
501
534
|
backdropNode: null;
|
|
535
|
+
geometryNode: null;
|
|
502
536
|
opacityNode: null;
|
|
503
537
|
colorNode: null;
|
|
504
538
|
alphaTestNode: null;
|
|
@@ -517,6 +551,8 @@ declare const VFXParticles: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
517
551
|
softParticles: boolean;
|
|
518
552
|
softDistance: number;
|
|
519
553
|
collision: CollisionConfig;
|
|
554
|
+
sortParticles: boolean;
|
|
555
|
+
sortFrameInterval: number | null;
|
|
520
556
|
curveTexturePath: string | null;
|
|
521
557
|
depthTest: boolean;
|
|
522
558
|
renderOrder: number;
|
package/dist/index.js
CHANGED
|
@@ -147,6 +147,10 @@ var VFXParticles = defineComponent({
|
|
|
147
147
|
type: null,
|
|
148
148
|
default: Lighting.STANDARD
|
|
149
149
|
},
|
|
150
|
+
lightingParams: {
|
|
151
|
+
type: Object,
|
|
152
|
+
default: null
|
|
153
|
+
},
|
|
150
154
|
shadow: { type: Boolean, default: false },
|
|
151
155
|
blending: {
|
|
152
156
|
type: null,
|
|
@@ -160,6 +164,7 @@ var VFXParticles = defineComponent({
|
|
|
160
164
|
autoStart: { type: Boolean, default: true },
|
|
161
165
|
delay: { type: Number, default: 0 },
|
|
162
166
|
backdropNode: { type: null, default: null },
|
|
167
|
+
geometryNode: { type: null, default: null },
|
|
163
168
|
opacityNode: { type: null, default: null },
|
|
164
169
|
colorNode: { type: null, default: null },
|
|
165
170
|
alphaTestNode: {
|
|
@@ -205,6 +210,11 @@ var VFXParticles = defineComponent({
|
|
|
205
210
|
type: Object,
|
|
206
211
|
default: null
|
|
207
212
|
},
|
|
213
|
+
sortParticles: { type: Boolean, default: false },
|
|
214
|
+
sortFrameInterval: {
|
|
215
|
+
type: null,
|
|
216
|
+
default: null
|
|
217
|
+
},
|
|
208
218
|
curveTexturePath: {
|
|
209
219
|
type: null,
|
|
210
220
|
default: null
|
|
@@ -213,8 +223,9 @@ var VFXParticles = defineComponent({
|
|
|
213
223
|
renderOrder: { type: Number, default: 0 }
|
|
214
224
|
},
|
|
215
225
|
setup(props, { expose }) {
|
|
216
|
-
var _a, _b, _c, _d;
|
|
217
|
-
const
|
|
226
|
+
var _a, _b, _c, _d, _e;
|
|
227
|
+
const tresCtx = useTresContext();
|
|
228
|
+
const rendererCtx = tresCtx.renderer;
|
|
218
229
|
const { onBeforeRender } = useLoop();
|
|
219
230
|
const systemRef = shallowRef(null);
|
|
220
231
|
const renderObjectRef = shallowRef(null);
|
|
@@ -237,6 +248,7 @@ var VFXParticles = defineComponent({
|
|
|
237
248
|
props.attractors !== null && ((_d = (_c = props.attractors) == null ? void 0 : _c.length) != null ? _d : 0) > 0
|
|
238
249
|
);
|
|
239
250
|
const activeCollision = ref(props.collision !== null);
|
|
251
|
+
const activeLightingParamsKey = ref(JSON.stringify((_e = props.lightingParams) != null ? _e : null));
|
|
240
252
|
const activeNeedsPerParticleColor = ref(
|
|
241
253
|
props.colorStart.length > 1 || props.colorEnd !== null
|
|
242
254
|
);
|
|
@@ -246,7 +258,7 @@ var VFXParticles = defineComponent({
|
|
|
246
258
|
const prevGeometryTypeRef = ref(null);
|
|
247
259
|
const prevGeometryArgsRef = ref(null);
|
|
248
260
|
function buildOptions() {
|
|
249
|
-
var _a2, _b2, _c2, _d2,
|
|
261
|
+
var _a2, _b2, _c2, _d2, _e2, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J;
|
|
250
262
|
const dbg = props.debug ? debugValuesRef.value : null;
|
|
251
263
|
return {
|
|
252
264
|
maxParticles: activeMaxParticles.value,
|
|
@@ -258,7 +270,7 @@ var VFXParticles = defineComponent({
|
|
|
258
270
|
fadeOpacity: (_d2 = dbg == null ? void 0 : dbg.fadeOpacity) != null ? _d2 : props.fadeOpacity,
|
|
259
271
|
fadeOpacityCurve: activeFadeOpacityCurve.value,
|
|
260
272
|
velocityCurve: activeVelocityCurve.value,
|
|
261
|
-
gravity: (
|
|
273
|
+
gravity: (_e2 = dbg == null ? void 0 : dbg.gravity) != null ? _e2 : props.gravity,
|
|
262
274
|
lifetime: (_f = dbg == null ? void 0 : dbg.lifetime) != null ? _f : props.lifetime,
|
|
263
275
|
direction: (_g = dbg == null ? void 0 : dbg.direction) != null ? _g : props.direction,
|
|
264
276
|
startPosition: (_h = dbg == null ? void 0 : dbg.startPosition) != null ? _h : props.startPosition,
|
|
@@ -275,6 +287,7 @@ var VFXParticles = defineComponent({
|
|
|
275
287
|
orientAxis: (_m = dbg == null ? void 0 : dbg.orientAxis) != null ? _m : props.orientAxis,
|
|
276
288
|
stretchBySpeed: (_n = dbg == null ? void 0 : dbg.stretchBySpeed) != null ? _n : props.stretchBySpeed,
|
|
277
289
|
lighting: activeLighting.value,
|
|
290
|
+
lightingParams: props.lightingParams,
|
|
278
291
|
shadow: activeShadow.value,
|
|
279
292
|
blending: (_o = dbg == null ? void 0 : dbg.blending) != null ? _o : props.blending,
|
|
280
293
|
intensity: (_p = dbg == null ? void 0 : dbg.intensity) != null ? _p : props.intensity,
|
|
@@ -295,13 +308,16 @@ var VFXParticles = defineComponent({
|
|
|
295
308
|
softParticles: (_E = dbg == null ? void 0 : dbg.softParticles) != null ? _E : props.softParticles,
|
|
296
309
|
softDistance: (_F = dbg == null ? void 0 : dbg.softDistance) != null ? _F : props.softDistance,
|
|
297
310
|
collision: (_G = dbg == null ? void 0 : dbg.collision) != null ? _G : props.collision,
|
|
311
|
+
sortParticles: (_H = dbg == null ? void 0 : dbg.sortParticles) != null ? _H : props.sortParticles,
|
|
312
|
+
sortFrameInterval: (dbg == null ? void 0 : dbg.sortFrameInterval) !== void 0 ? dbg.sortFrameInterval : props.sortFrameInterval,
|
|
298
313
|
backdropNode: props.backdropNode,
|
|
314
|
+
geometryNode: props.geometryNode,
|
|
299
315
|
opacityNode: props.opacityNode,
|
|
300
316
|
colorNode: props.colorNode,
|
|
301
317
|
alphaTestNode: props.alphaTestNode,
|
|
302
318
|
castShadowNode: props.castShadowNode,
|
|
303
|
-
depthTest: (
|
|
304
|
-
renderOrder: (
|
|
319
|
+
depthTest: (_I = dbg == null ? void 0 : dbg.depthTest) != null ? _I : props.depthTest,
|
|
320
|
+
renderOrder: (_J = dbg == null ? void 0 : dbg.renderOrder) != null ? _J : props.renderOrder,
|
|
305
321
|
curveTexturePath: props.curveTexturePath
|
|
306
322
|
};
|
|
307
323
|
}
|
|
@@ -367,7 +383,7 @@ var VFXParticles = defineComponent({
|
|
|
367
383
|
}
|
|
368
384
|
}
|
|
369
385
|
function handleDebugUpdate(newValues) {
|
|
370
|
-
var _a2, _b2, _c2, _d2,
|
|
386
|
+
var _a2, _b2, _c2, _d2, _e2, _f, _g, _h, _i, _j, _k;
|
|
371
387
|
debugValuesRef.value = __spreadValues(__spreadValues({}, debugValuesRef.value), newValues);
|
|
372
388
|
const system = systemRef.value;
|
|
373
389
|
if (!system) return;
|
|
@@ -398,7 +414,7 @@ var VFXParticles = defineComponent({
|
|
|
398
414
|
}
|
|
399
415
|
if ("turbulence" in newValues) {
|
|
400
416
|
system.setTurbulenceSpeed(
|
|
401
|
-
(_f = (
|
|
417
|
+
(_f = (_e2 = newValues.turbulence) == null ? void 0 : _e2.speed) != null ? _f : 1
|
|
402
418
|
);
|
|
403
419
|
}
|
|
404
420
|
const newFeatures = resolveFeatures(
|
|
@@ -426,6 +442,12 @@ var VFXParticles = defineComponent({
|
|
|
426
442
|
system.setDelay((_g = newValues.delay) != null ? _g : 0);
|
|
427
443
|
if ("emitCount" in newValues)
|
|
428
444
|
system.setEmitCount((_h = newValues.emitCount) != null ? _h : 1);
|
|
445
|
+
if ("sortParticles" in newValues)
|
|
446
|
+
system.setSortEnabled(!!newValues.sortParticles);
|
|
447
|
+
if ("sortFrameInterval" in newValues)
|
|
448
|
+
system.setSortFrameInterval(
|
|
449
|
+
(_i = newValues.sortFrameInterval) != null ? _i : null
|
|
450
|
+
);
|
|
429
451
|
if (newValues.autoStart !== void 0) {
|
|
430
452
|
emitting.value = newValues.autoStart;
|
|
431
453
|
}
|
|
@@ -452,8 +474,8 @@ var VFXParticles = defineComponent({
|
|
|
452
474
|
activeShadow.value = newValues.shadow;
|
|
453
475
|
}
|
|
454
476
|
if ("geometryType" in newValues || "geometryArgs" in newValues) {
|
|
455
|
-
const geoType = (
|
|
456
|
-
const geoArgs = (
|
|
477
|
+
const geoType = (_j = newValues.geometryType) != null ? _j : prevGeometryTypeRef.value;
|
|
478
|
+
const geoArgs = (_k = newValues.geometryArgs) != null ? _k : prevGeometryArgsRef.value;
|
|
457
479
|
const geoTypeChanged = "geometryType" in newValues && geoType !== prevGeometryTypeRef.value;
|
|
458
480
|
const geoArgsChanged = "geometryArgs" in newValues && JSON.stringify(geoArgs) !== JSON.stringify(prevGeometryArgsRef.value);
|
|
459
481
|
if (geoTypeChanged || geoArgsChanged) {
|
|
@@ -529,7 +551,9 @@ var VFXParticles = defineComponent({
|
|
|
529
551
|
attractToCenter: props.attractToCenter,
|
|
530
552
|
softParticles: props.softParticles,
|
|
531
553
|
softDistance: props.softDistance,
|
|
532
|
-
collision: props.collision
|
|
554
|
+
collision: props.collision,
|
|
555
|
+
sortParticles: props.sortParticles,
|
|
556
|
+
sortFrameInterval: props.sortFrameInterval
|
|
533
557
|
}, detectGeometryTypeAndArgs(props.geometry));
|
|
534
558
|
debugValuesRef.value = initialValues;
|
|
535
559
|
prevGeometryTypeRef.value = initialValues.geometryType;
|
|
@@ -556,10 +580,11 @@ var VFXParticles = defineComponent({
|
|
|
556
580
|
props.rotationSpeed,
|
|
557
581
|
props.turbulence,
|
|
558
582
|
props.attractors,
|
|
559
|
-
props.collision
|
|
583
|
+
props.collision,
|
|
584
|
+
props.lightingParams
|
|
560
585
|
],
|
|
561
586
|
() => {
|
|
562
|
-
var _a2, _b2, _c2, _d2;
|
|
587
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
563
588
|
if (props.debug) return;
|
|
564
589
|
activeMaxParticles.value = props.maxParticles;
|
|
565
590
|
activeLighting.value = props.lighting;
|
|
@@ -576,6 +601,7 @@ var VFXParticles = defineComponent({
|
|
|
576
601
|
activeTurbulence.value = props.turbulence !== null && ((_b2 = (_a2 = props.turbulence) == null ? void 0 : _a2.intensity) != null ? _b2 : 0) > 0;
|
|
577
602
|
activeAttractors.value = props.attractors !== null && ((_d2 = (_c2 = props.attractors) == null ? void 0 : _c2.length) != null ? _d2 : 0) > 0;
|
|
578
603
|
activeCollision.value = props.collision !== null;
|
|
604
|
+
activeLightingParamsKey.value = JSON.stringify((_e2 = props.lightingParams) != null ? _e2 : null);
|
|
579
605
|
}
|
|
580
606
|
);
|
|
581
607
|
watch(
|
|
@@ -594,7 +620,8 @@ var VFXParticles = defineComponent({
|
|
|
594
620
|
activeFadeSizeCurve,
|
|
595
621
|
activeFadeOpacityCurve,
|
|
596
622
|
activeVelocityCurve,
|
|
597
|
-
activeRotationSpeedCurve
|
|
623
|
+
activeRotationSpeedCurve,
|
|
624
|
+
activeLightingParamsKey
|
|
598
625
|
],
|
|
599
626
|
() => {
|
|
600
627
|
initSystem();
|
|
@@ -633,7 +660,9 @@ var VFXParticles = defineComponent({
|
|
|
633
660
|
props.orientAxis,
|
|
634
661
|
props.stretchBySpeed,
|
|
635
662
|
props.delay,
|
|
636
|
-
props.emitCount
|
|
663
|
+
props.emitCount,
|
|
664
|
+
props.sortParticles,
|
|
665
|
+
props.sortFrameInterval
|
|
637
666
|
],
|
|
638
667
|
() => {
|
|
639
668
|
var _a2, _b2;
|
|
@@ -644,6 +673,8 @@ var VFXParticles = defineComponent({
|
|
|
644
673
|
system.setDelay(props.delay);
|
|
645
674
|
system.setEmitCount(props.emitCount);
|
|
646
675
|
system.setTurbulenceSpeed((_b2 = (_a2 = props.turbulence) == null ? void 0 : _a2.speed) != null ? _b2 : 1);
|
|
676
|
+
system.setSortFrameInterval(props.sortFrameInterval);
|
|
677
|
+
system.setSortEnabled(props.sortParticles);
|
|
647
678
|
const normalized = normalizeProps({
|
|
648
679
|
size: props.size,
|
|
649
680
|
speed: props.speed,
|
|
@@ -679,10 +710,17 @@ var VFXParticles = defineComponent({
|
|
|
679
710
|
},
|
|
680
711
|
{ deep: true }
|
|
681
712
|
);
|
|
682
|
-
onBeforeRender((
|
|
713
|
+
onBeforeRender((frame) => {
|
|
714
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
683
715
|
const system = systemRef.value;
|
|
684
716
|
if (!system || !system.initialized) return;
|
|
685
|
-
|
|
717
|
+
const delta = (_a2 = frame == null ? void 0 : frame.delta) != null ? _a2 : 0;
|
|
718
|
+
const cam = (_e2 = (_d2 = (_c2 = frame == null ? void 0 : frame.camera) != null ? _c2 : (_b2 = tresCtx.camera) == null ? void 0 : _b2.value) != null ? _d2 : tresCtx.camera) != null ? _e2 : null;
|
|
719
|
+
const pos = cam == null ? void 0 : cam.position;
|
|
720
|
+
if (pos) {
|
|
721
|
+
system.setCameraPosition([pos.x, pos.y, pos.z]);
|
|
722
|
+
}
|
|
723
|
+
void system.update(delta);
|
|
686
724
|
if (emitting.value) {
|
|
687
725
|
system.autoEmit(delta);
|
|
688
726
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tres-vfx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.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.
|
|
28
|
-
"debug-vfx": "0.
|
|
27
|
+
"core-vfx": "0.4.0",
|
|
28
|
+
"debug-vfx": "0.4.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@tresjs/core": ">=5.0.0",
|