@newkrok/three-particles 0.6.2 → 0.8.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
@@ -7,6 +7,7 @@ Particle system for ThreeJS
7
7
  You can create your own particle effects with it's editor https://github.com/NewKrok/three-particles-editor
8
8
 
9
9
  # Video
10
+
10
11
  - Projectiles: https://youtu.be/Q352JuxON04
11
12
  - First preview: https://youtu.be/dtN_bndvoGU
12
13
 
@@ -22,4 +23,4 @@ Install with npm
22
23
  `npm i @newkrok/three-particles`
23
24
 
24
25
  Add as a package.json dependency
25
- `"dependencies": { ... "@newkrok/three-particles": "0.6.2" ... }, `
26
+ `"dependencies": { ... "@newkrok/three-particles": "0.7.0" ... }, `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newkrok/three-particles",
3
- "version": "0.6.2",
3
+ "version": "0.8.0",
4
4
  "description": "Particle system for ThreeJS",
5
5
  "main": "src/js/three-particles.js",
6
6
  "bin": {
@@ -27,8 +27,9 @@
27
27
  "homepage": "https://github.com/NewKrok/three-particles#readme",
28
28
  "dependencies": {
29
29
  "easing-functions": "1.0.1",
30
- "three": "0.137.0",
31
- "three-noise": "^1.1.1"
30
+ "three": "0.140.0",
31
+ "three-noise": "1.1.2",
32
+ "@newkrok/three-utils": "0.1.0"
32
33
  },
33
34
  "scripts": {
34
35
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -4,6 +4,9 @@ const ParticleSystemFragmentShader = `
4
4
  uniform float fps;
5
5
  uniform bool useFPSForFrameIndex;
6
6
  uniform vec2 tiles;
7
+ uniform bool discardBackgroundColor;
8
+ uniform vec3 backgroundColor;
9
+ uniform float backgroundColorTolerance;
7
10
 
8
11
  varying vec4 vColor;
9
12
  varying float vLifetime;
@@ -56,6 +59,8 @@ const ParticleSystemFragmentShader = `
56
59
  vec4 rotatedTexture = texture2D(map, uvPoint);
57
60
 
58
61
  gl_FragColor = gl_FragColor * rotatedTexture;
62
+
63
+ if (discardBackgroundColor && abs(length(rotatedTexture.rgb - backgroundColor.rgb)) < backgroundColorTolerance ) discard;
59
64
  }
60
65
  `;
61
66
 
@@ -2,7 +2,9 @@ import * as THREE from "three";
2
2
 
3
3
  import { getCurveFunction } from "./three-particles-curves.js";
4
4
 
5
+ const ROTATION_CONVERTER = THREE.MathUtils.radToDeg(1);
5
6
  const noiseInput = new THREE.Vector3(0, 0, 0);
7
+ const orbitalEuler = new THREE.Euler();
6
8
 
7
9
  const curveModifiers = [
8
10
  // {key:"colorOverLifetime", attributeKeys:["colorR", "colorG", "colorB"]},
@@ -23,12 +25,38 @@ export const applyModifiers = ({
23
25
  noise,
24
26
  startValues,
25
27
  lifetimeValues,
28
+ hasOrbitalVelocity,
29
+ orbitalVelocityData,
26
30
  normalizedConfig,
27
31
  attributes,
32
+ particleLifetime,
28
33
  particleLifetimePercentage,
29
34
  particleIndex,
30
35
  forceUpdate = false,
31
36
  }) => {
37
+ if (hasOrbitalVelocity) {
38
+ const positionIndex = particleIndex * 3;
39
+ const positionArr = attributes.position.array;
40
+ const { speed, positionOffset } = orbitalVelocityData[particleIndex];
41
+
42
+ positionArr[positionIndex] -= positionOffset.x;
43
+ positionArr[positionIndex + 1] -= positionOffset.y;
44
+ positionArr[positionIndex + 2] -= positionOffset.z;
45
+
46
+ orbitalEuler.set(
47
+ speed.x * ROTATION_CONVERTER * delta,
48
+ speed.z * ROTATION_CONVERTER * delta,
49
+ speed.y * ROTATION_CONVERTER * delta
50
+ );
51
+ positionOffset.applyEuler(orbitalEuler);
52
+
53
+ positionArr[positionIndex] += positionOffset.x;
54
+ positionArr[positionIndex + 1] += positionOffset.y;
55
+ positionArr[positionIndex + 2] += positionOffset.z;
56
+
57
+ attributes.position.needsUpdate = true;
58
+ }
59
+
32
60
  curveModifiers.forEach(({ key, attributeKeys, startValueKeys }) => {
33
61
  const curveModifier = normalizedConfig[key];
34
62
  if (curveModifier.isActive) {
@@ -2,37 +2,9 @@ import * as THREE from "three";
2
2
 
3
3
  import { EmitFrom } from "../three-particles.js";
4
4
 
5
- export const patchObject = (
6
- objectA,
7
- objectB,
8
- config = { skippedProperties: [], applyToFirstObject: false }
9
- ) => {
10
- const result = {};
11
- Object.keys(objectA).forEach((key) => {
12
- if (!config.skippedProperties || !config.skippedProperties.includes(key)) {
13
- if (
14
- typeof objectA[key] === "object" &&
15
- objectA[key] &&
16
- objectB[key] &&
17
- !Array.isArray(objectA[key])
18
- ) {
19
- result[key] = patchObject(objectA[key], objectB[key], config);
20
- } else {
21
- result[key] =
22
- objectB[key] === 0
23
- ? 0
24
- : objectB[key] === false
25
- ? false
26
- : objectB[key] || objectA[key];
27
- if (config.applyToFirstObject) objectA[key] = result[key];
28
- }
29
- }
30
- });
31
- return result;
32
- };
33
-
34
5
  export const calculateRandomPositionAndVelocityOnSphere = (
35
6
  position,
7
+ quaternion,
36
8
  velocity,
37
9
  startSpeed,
38
10
  { radius, radiusThickness, arc }
@@ -59,6 +31,8 @@ export const calculateRandomPositionAndVelocityOnSphere = (
59
31
  radius * normalizedThickness * zDirection +
60
32
  radius * radiusThickness * randomizedDistanceRatio * zDirection;
61
33
 
34
+ position.applyQuaternion(quaternion);
35
+
62
36
  const randomizedSpeed = THREE.MathUtils.randFloat(
63
37
  startSpeed.min,
64
38
  startSpeed.max
@@ -69,10 +43,12 @@ export const calculateRandomPositionAndVelocityOnSphere = (
69
43
  position.y * speedMultiplierByPosition * randomizedSpeed,
70
44
  position.z * speedMultiplierByPosition * randomizedSpeed
71
45
  );
46
+ velocity.applyQuaternion(quaternion);
72
47
  };
73
48
 
74
49
  export const calculateRandomPositionAndVelocityOnCone = (
75
50
  position,
51
+ quaternion,
76
52
  velocity,
77
53
  startSpeed,
78
54
  { radius, radiusThickness, arc, angle = 90 }
@@ -92,6 +68,8 @@ export const calculateRandomPositionAndVelocityOnCone = (
92
68
  radius * radiusThickness * randomizedDistanceRatio * yDirection;
93
69
  position.z = 0;
94
70
 
71
+ position.applyQuaternion(quaternion);
72
+
95
73
  const positionLength = position.length();
96
74
  const normalizedAngle = Math.abs(
97
75
  (positionLength / radius) * THREE.Math.degToRad(angle)
@@ -114,10 +92,12 @@ export const calculateRandomPositionAndVelocityOnCone = (
114
92
  randomizedSpeed,
115
93
  Math.cos(normalizedAngle) * randomizedSpeed
116
94
  );
95
+ velocity.applyQuaternion(quaternion);
117
96
  };
118
97
 
119
98
  export const calculateRandomPositionAndVelocityOnBox = (
120
99
  position,
100
+ quaternion,
121
101
  velocity,
122
102
  startSpeed,
123
103
  { scale, emitFrom }
@@ -157,15 +137,19 @@ export const calculateRandomPositionAndVelocityOnBox = (
157
137
  break;
158
138
  }
159
139
 
140
+ position.applyQuaternion(quaternion);
141
+
160
142
  const randomizedSpeed = THREE.MathUtils.randFloat(
161
143
  startSpeed.min,
162
144
  startSpeed.max
163
145
  );
164
146
  velocity.set(0, 0, randomizedSpeed);
147
+ velocity.applyQuaternion(quaternion);
165
148
  };
166
149
 
167
150
  export const calculateRandomPositionAndVelocityOnCircle = (
168
151
  position,
152
+ quaternion,
169
153
  velocity,
170
154
  startSpeed,
171
155
  { radius, radiusThickness, arc }
@@ -185,6 +169,8 @@ export const calculateRandomPositionAndVelocityOnCircle = (
185
169
  radius * radiusThickness * randomizedDistanceRatio * yDirection;
186
170
  position.z = 0;
187
171
 
172
+ position.applyQuaternion(quaternion);
173
+
188
174
  const randomizedSpeed = THREE.MathUtils.randFloat(
189
175
  startSpeed.min,
190
176
  startSpeed.max
@@ -197,10 +183,12 @@ export const calculateRandomPositionAndVelocityOnCircle = (
197
183
  position.y * speedMultiplierByPosition * randomizedSpeed,
198
184
  0
199
185
  );
186
+ velocity.applyQuaternion(quaternion);
200
187
  };
201
188
 
202
189
  export const calculateRandomPositionAndVelocityOnRectangle = (
203
190
  position,
191
+ quaternion,
204
192
  velocity,
205
193
  startSpeed,
206
194
  { rotation, scale }
@@ -213,9 +201,12 @@ export const calculateRandomPositionAndVelocityOnRectangle = (
213
201
  position.y = yOffset * Math.cos(rotationX);
214
202
  position.z = xOffset * Math.sin(rotationY) - yOffset * Math.sin(rotationX);
215
203
 
204
+ position.applyQuaternion(quaternion);
205
+
216
206
  const randomizedSpeed = THREE.MathUtils.randFloat(
217
207
  startSpeed.min,
218
208
  startSpeed.max
219
209
  );
220
210
  velocity.set(0, 0, randomizedSpeed);
211
+ velocity.applyQuaternion(quaternion);
221
212
  };
@@ -6,15 +6,16 @@ import {
6
6
  calculateRandomPositionAndVelocityOnCone,
7
7
  calculateRandomPositionAndVelocityOnRectangle,
8
8
  calculateRandomPositionAndVelocityOnSphere,
9
- patchObject,
10
9
  } from "./three-particles/three-particles-utils.js";
11
10
 
12
11
  import { CurveFunction } from "./three-particles/three-particles-curves.js";
13
12
  import { FBM } from "three-noise/build/three-noise.module.js";
13
+ import { Gyroscope } from "three/examples/jsm/misc/Gyroscope";
14
14
  import ParticleSystemFragmentShader from "./three-particles/shaders/particle-system-fragment-shader.glsl.js";
15
15
  import ParticleSystemVertexShader from "./three-particles/shaders/particle-system-vertex-shader.glsl.js";
16
16
  import { applyModifiers } from "./three-particles/three-particles-modifiers.js";
17
17
  import { createBezierCurveFunction } from "./three-particles/three-particles-bezier";
18
+ import { patchObject } from "@newkrok/three-utils/src/js/newkrok/three-utils/object-utils.js";
18
19
 
19
20
  let createdParticleSystems = [];
20
21
 
@@ -108,6 +109,9 @@ const DEFAULT_PARTICLE_SYSTEM_CONFIG = {
108
109
  map: null,
109
110
  renderer: {
110
111
  blending: THREE.NormalBlending,
112
+ discardBackgroundColor: false,
113
+ backgroundColorTolerance: 1.0,
114
+ backgroundColor: { r: 1.0, g: 1.0, b: 1.0 },
111
115
  transparent: true,
112
116
  depthTest: true,
113
117
  depthWrite: false,
@@ -192,6 +196,7 @@ const calculatePositionAndVelocity = (
192
196
  { shape, sphere, cone, circle, rectangle, box },
193
197
  startSpeed,
194
198
  position,
199
+ quaternion,
195
200
  velocity,
196
201
  velocityOverLifetime
197
202
  ) => {
@@ -199,6 +204,7 @@ const calculatePositionAndVelocity = (
199
204
  case Shape.SPHERE:
200
205
  calculateRandomPositionAndVelocityOnSphere(
201
206
  position,
207
+ quaternion,
202
208
  velocity,
203
209
  startSpeed,
204
210
  sphere
@@ -208,6 +214,7 @@ const calculatePositionAndVelocity = (
208
214
  case Shape.CONE:
209
215
  calculateRandomPositionAndVelocityOnCone(
210
216
  position,
217
+ quaternion,
211
218
  velocity,
212
219
  startSpeed,
213
220
  cone
@@ -217,6 +224,7 @@ const calculatePositionAndVelocity = (
217
224
  case Shape.CIRCLE:
218
225
  calculateRandomPositionAndVelocityOnCircle(
219
226
  position,
227
+ quaternion,
220
228
  velocity,
221
229
  startSpeed,
222
230
  circle
@@ -226,6 +234,7 @@ const calculatePositionAndVelocity = (
226
234
  case Shape.RECTANGLE:
227
235
  calculateRandomPositionAndVelocityOnRectangle(
228
236
  position,
237
+ quaternion,
229
238
  velocity,
230
239
  startSpeed,
231
240
  rectangle
@@ -235,6 +244,7 @@ const calculatePositionAndVelocity = (
235
244
  case Shape.BOX:
236
245
  calculateRandomPositionAndVelocityOnBox(
237
246
  position,
247
+ quaternion,
238
248
  velocity,
239
249
  startSpeed,
240
250
  box
@@ -243,18 +253,33 @@ const calculatePositionAndVelocity = (
243
253
  }
244
254
 
245
255
  if (velocityOverLifetime.isActive) {
246
- velocity.x += THREE.MathUtils.randFloat(
247
- velocityOverLifetime.linear.x.min,
248
- velocityOverLifetime.linear.x.max
249
- );
250
- velocity.y += THREE.MathUtils.randFloat(
251
- velocityOverLifetime.linear.y.min,
252
- velocityOverLifetime.linear.y.max
253
- );
254
- velocity.z += THREE.MathUtils.randFloat(
255
- velocityOverLifetime.linear.z.min,
256
- velocityOverLifetime.linear.z.max
257
- );
256
+ if (
257
+ velocityOverLifetime.linear.x.min !== 0 ||
258
+ velocityOverLifetime.linear.x.max !== 0
259
+ ) {
260
+ velocity.x += THREE.MathUtils.randFloat(
261
+ velocityOverLifetime.linear.x.min,
262
+ velocityOverLifetime.linear.x.max
263
+ );
264
+ }
265
+ if (
266
+ velocityOverLifetime.linear.y.min !== 0 ||
267
+ velocityOverLifetime.linear.y.max !== 0
268
+ ) {
269
+ velocity.y += THREE.MathUtils.randFloat(
270
+ velocityOverLifetime.linear.y.min,
271
+ velocityOverLifetime.linear.y.max
272
+ );
273
+ }
274
+ if (
275
+ velocityOverLifetime.linear.z.min !== 0 ||
276
+ velocityOverLifetime.linear.z.max !== 0
277
+ ) {
278
+ velocity.z += THREE.MathUtils.randFloat(
279
+ velocityOverLifetime.linear.z.min,
280
+ velocityOverLifetime.linear.z.max
281
+ );
282
+ }
258
283
  }
259
284
  };
260
285
 
@@ -268,10 +293,13 @@ export const createParticleSystem = (
268
293
  currentWorldPosition: new THREE.Vector3(-99999),
269
294
  worldPositionChange: new THREE.Vector3(),
270
295
  worldQuaternion: new THREE.Quaternion(),
296
+ wrapperQuaternion: new THREE.Quaternion(),
271
297
  lastWorldQuaternion: new THREE.Quaternion(-99999),
272
298
  worldEuler: new THREE.Euler(),
273
299
  gravityVelocity: new THREE.Vector3(0, 0, 0),
274
300
  startValues: {},
301
+ hasOrbitalVelocity: false,
302
+ orbitalVelocityData: [],
275
303
  lifetimeValues: {},
276
304
  creationTimes: [],
277
305
  noise: null,
@@ -332,6 +360,24 @@ export const createParticleSystem = (
332
360
  );
333
361
 
334
362
  generalData.creationTimes = Array.from({ length: maxParticles }, () => 0);
363
+ generalData.hasOrbitalVelocity =
364
+ normalizedConfig.velocityOverLifetime.isActive &&
365
+ (normalizedConfig.velocityOverLifetime.orbital.x.min !== 0 ||
366
+ normalizedConfig.velocityOverLifetime.orbital.x.max !== 0 ||
367
+ normalizedConfig.velocityOverLifetime.orbital.y.min !== 0 ||
368
+ normalizedConfig.velocityOverLifetime.orbital.y.max !== 0 ||
369
+ normalizedConfig.velocityOverLifetime.orbital.z.min !== 0 ||
370
+ normalizedConfig.velocityOverLifetime.orbital.z.max !== 0);
371
+
372
+ if (generalData.hasOrbitalVelocity) {
373
+ generalData.orbitalVelocityData = Array.from(
374
+ { length: maxParticles },
375
+ () => ({
376
+ speed: new THREE.Vector3(),
377
+ positionOffset: new THREE.Vector3(),
378
+ })
379
+ );
380
+ }
335
381
 
336
382
  const startValueKeys = ["startSize", "startOpacity"];
337
383
  startValueKeys.forEach((key) => {
@@ -391,6 +437,15 @@ export const createParticleSystem = (
391
437
  useFPSForFrameIndex: {
392
438
  value: textureSheetAnimation.timeMode === TimeMode.FPS,
393
439
  },
440
+ backgroundColor: {
441
+ value: renderer.backgroundColor,
442
+ },
443
+ discardBackgroundColor: {
444
+ value: renderer.discardBackgroundColor,
445
+ },
446
+ backgroundColorTolerance: {
447
+ value: renderer.backgroundColorTolerance,
448
+ },
394
449
  },
395
450
  vertexShader: ParticleSystemVertexShader,
396
451
  fragmentShader: ParticleSystemFragmentShader,
@@ -407,6 +462,7 @@ export const createParticleSystem = (
407
462
  shape,
408
463
  startSpeed,
409
464
  startPositions[i],
465
+ generalData.wrapperQuaternion,
410
466
  velocities[i],
411
467
  velocityOverLifetime
412
468
  );
@@ -538,6 +594,7 @@ export const createParticleSystem = (
538
594
  shape,
539
595
  startSpeed,
540
596
  startPositions[particleIndex],
597
+ generalData.wrapperQuaternion,
541
598
  velocities[particleIndex],
542
599
  velocityOverLifetime
543
600
  );
@@ -550,6 +607,31 @@ export const createParticleSystem = (
550
607
  (position ? position.z : 0) + startPositions[particleIndex].z;
551
608
  geometry.attributes.position.needsUpdate = true;
552
609
 
610
+ if (generalData.hasOrbitalVelocity) {
611
+ generalData.orbitalVelocityData[particleIndex].speed.set(
612
+ THREE.MathUtils.randFloat(
613
+ normalizedConfig.velocityOverLifetime.orbital.x.min,
614
+ normalizedConfig.velocityOverLifetime.orbital.x.max
615
+ ) *
616
+ (Math.PI / 180),
617
+ THREE.MathUtils.randFloat(
618
+ normalizedConfig.velocityOverLifetime.orbital.y.min,
619
+ normalizedConfig.velocityOverLifetime.orbital.y.max
620
+ ) *
621
+ (Math.PI / 180),
622
+ THREE.MathUtils.randFloat(
623
+ normalizedConfig.velocityOverLifetime.orbital.z.min,
624
+ normalizedConfig.velocityOverLifetime.orbital.z.max
625
+ ) *
626
+ (Math.PI / 180)
627
+ );
628
+ generalData.orbitalVelocityData[particleIndex].positionOffset.set(
629
+ startPositions[particleIndex].x,
630
+ startPositions[particleIndex].y,
631
+ startPositions[particleIndex].z
632
+ );
633
+ }
634
+
553
635
  geometry.attributes.lifetime.array[particleIndex] = 0;
554
636
  geometry.attributes.lifetime.needsUpdate = true;
555
637
 
@@ -559,15 +641,18 @@ export const createParticleSystem = (
559
641
  noise: generalData.noise,
560
642
  startValues: generalData.startValues,
561
643
  lifetimeValues: generalData.lifetimeValues,
644
+ hasOrbitalVelocity: generalData.hasOrbitalVelocity,
645
+ orbitalVelocityData: generalData.orbitalVelocityData,
562
646
  normalizedConfig,
563
647
  attributes: particleSystem.geometry.attributes,
648
+ particleLifetime: 0,
564
649
  particleLifetimePercentage: 0,
565
650
  particleIndex,
566
651
  forceUpdate: true,
567
652
  });
568
653
  };
569
654
 
570
- const particleSystem = new THREE.Points(geometry, material);
655
+ let particleSystem = new THREE.Points(geometry, material);
571
656
  particleSystem.sortParticles = true;
572
657
 
573
658
  particleSystem.position.copy(transform.position);
@@ -579,8 +664,15 @@ export const createParticleSystem = (
579
664
  const calculatedCreationTime =
580
665
  now + THREE.MathUtils.randFloat(startDelay.min, startDelay.max) * 1000;
581
666
 
667
+ let wrapper;
668
+ if (normalizedConfig.simulationSpace === SimulationSpace.WORLD) {
669
+ wrapper = new Gyroscope();
670
+ wrapper.add(particleSystem);
671
+ }
672
+
582
673
  createdParticleSystems.push({
583
674
  particleSystem,
675
+ wrapper,
584
676
  generalData,
585
677
  onUpdate,
586
678
  onComplete,
@@ -597,18 +689,26 @@ export const createParticleSystem = (
597
689
  deactivateParticle,
598
690
  activateParticle,
599
691
  });
600
- return particleSystem;
692
+
693
+ return wrapper || particleSystem;
601
694
  };
602
695
 
603
696
  export const destroyParticleSystem = (particleSystem) => {
604
697
  createdParticleSystems = createdParticleSystems.filter(
605
- ({ particleSystem: savedParticleSystem }) =>
606
- savedParticleSystem !== particleSystem
607
- );
698
+ ({ particleSystem: savedParticleSystem, wrapper }) => {
699
+ if (
700
+ savedParticleSystem !== particleSystem &&
701
+ wrapper !== particleSystem
702
+ ) {
703
+ return true;
704
+ }
608
705
 
609
- particleSystem.geometry.dispose();
610
- particleSystem.material.dispose();
611
- particleSystem.parent.remove(particleSystem);
706
+ savedParticleSystem.geometry.dispose();
707
+ savedParticleSystem.material.dispose();
708
+ savedParticleSystem.parent.remove(savedParticleSystem);
709
+ return false;
710
+ }
711
+ );
612
712
  };
613
713
 
614
714
  export const updateParticleSystems = ({ now, delta, elapsed }) => {
@@ -618,6 +718,7 @@ export const updateParticleSystems = ({ now, delta, elapsed }) => {
618
718
  generalData,
619
719
  onComplete,
620
720
  particleSystem,
721
+ wrapper,
621
722
  creationTime,
622
723
  lastEmissionTime,
623
724
  duration,
@@ -640,8 +741,11 @@ export const updateParticleSystems = ({ now, delta, elapsed }) => {
640
741
  worldQuaternion,
641
742
  worldEuler,
642
743
  gravityVelocity,
744
+ hasOrbitalVelocity,
643
745
  } = generalData;
644
746
 
747
+ if (wrapper) generalData.wrapperQuaternion.copy(wrapper.parent.quaternion);
748
+
645
749
  const lastWorldPositionSnapshot = { ...lastWorldPosition };
646
750
 
647
751
  const lifetime = now - creationTime;
@@ -654,7 +758,6 @@ export const updateParticleSystems = ({ now, delta, elapsed }) => {
654
758
  currentWorldPosition.y - lastWorldPosition.y,
655
759
  currentWorldPosition.z - lastWorldPosition.z
656
760
  );
657
- worldPositionChange.applyQuaternion(worldQuaternion.invert());
658
761
  }
659
762
  generalData.distanceFromLastEmitByDistance += worldPositionChange.length();
660
763
  particleSystem.getWorldPosition(lastWorldPosition);
@@ -685,9 +788,9 @@ export const updateParticleSystems = ({ now, delta, elapsed }) => {
685
788
  deactivateParticle(index);
686
789
  else {
687
790
  const velocity = velocities[index];
688
- velocity.x -= gravityVelocity.x;
689
- velocity.y -= gravityVelocity.y;
690
- velocity.z -= gravityVelocity.z;
791
+ velocity.x -= gravityVelocity.x * delta;
792
+ velocity.y -= gravityVelocity.y * delta;
793
+ velocity.z -= gravityVelocity.z * delta;
691
794
 
692
795
  if (
693
796
  gravity !== 0 ||
@@ -707,6 +810,7 @@ export const updateParticleSystems = ({ now, delta, elapsed }) => {
707
810
  positionArr[positionIndex + 1] -= worldPositionChange.y;
708
811
  positionArr[positionIndex + 2] -= worldPositionChange.z;
709
812
  }
813
+
710
814
  positionArr[positionIndex] += velocity.x * delta;
711
815
  positionArr[positionIndex + 1] += velocity.y * delta;
712
816
  positionArr[positionIndex + 2] += velocity.z * delta;
@@ -726,8 +830,11 @@ export const updateParticleSystems = ({ now, delta, elapsed }) => {
726
830
  noise: generalData.noise,
727
831
  startValues: generalData.startValues,
728
832
  lifetimeValues: generalData.lifetimeValues,
833
+ hasOrbitalVelocity: generalData.hasOrbitalVelocity,
834
+ orbitalVelocityData: generalData.orbitalVelocityData,
729
835
  normalizedConfig,
730
836
  attributes: particleSystem.geometry.attributes,
837
+ particleLifetime,
731
838
  particleLifetimePercentage,
732
839
  particleIndex: index,
733
840
  });