@rzmps/rzmps 1.0.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.
Files changed (133) hide show
  1. package/README.md +1048 -0
  2. package/build/EmissionShape.d.ts +33 -0
  3. package/build/EmissionShape.js +129 -0
  4. package/build/Emitter.d.ts +58 -0
  5. package/build/Emitter.js +166 -0
  6. package/build/GpuModule.d.ts +28 -0
  7. package/build/GpuModule.js +28 -0
  8. package/build/Module.d.ts +19 -0
  9. package/build/Module.js +31 -0
  10. package/build/Particle.d.ts +60 -0
  11. package/build/Particle.js +52 -0
  12. package/build/ParticleForceField.d.ts +39 -0
  13. package/build/ParticleForceField.js +101 -0
  14. package/build/ParticleForceFieldHelper.d.ts +18 -0
  15. package/build/ParticleForceFieldHelper.js +103 -0
  16. package/build/ParticleSystem.d.ts +122 -0
  17. package/build/ParticleSystem.js +609 -0
  18. package/build/Renderer.d.ts +15 -0
  19. package/build/Renderer.js +11 -0
  20. package/build/assets/images/default.png +0 -0
  21. package/build/collision/ThreeCollisionBackend.d.ts +47 -0
  22. package/build/collision/ThreeCollisionBackend.js +340 -0
  23. package/build/enums/Axis.d.ts +6 -0
  24. package/build/enums/Axis.js +7 -0
  25. package/build/enums/DynamicValueType.d.ts +6 -0
  26. package/build/enums/DynamicValueType.js +7 -0
  27. package/build/enums/EmissionSource copy.d.ts +7 -0
  28. package/build/enums/EmissionSource copy.js +7 -0
  29. package/build/enums/EmissionSource.d.ts +7 -0
  30. package/build/enums/EmissionSource.js +7 -0
  31. package/build/enums/EndBehavior.d.ts +6 -0
  32. package/build/enums/EndBehavior.js +7 -0
  33. package/build/enums/SimulationSpace.d.ts +5 -0
  34. package/build/enums/SimulationSpace.js +6 -0
  35. package/build/enums/SpriteMaterialType.d.ts +5 -0
  36. package/build/enums/SpriteMaterialType.js +6 -0
  37. package/build/enums/TagSelectionMethod.d.ts +6 -0
  38. package/build/enums/TagSelectionMethod.js +7 -0
  39. package/build/enums/TrailMode copy.d.ts +5 -0
  40. package/build/enums/TrailMode copy.js +7 -0
  41. package/build/enums/TrailMode.d.ts +5 -0
  42. package/build/enums/TrailMode.js +7 -0
  43. package/build/enums/TrailTextureMode.d.ts +7 -0
  44. package/build/enums/TrailTextureMode.js +9 -0
  45. package/build/gpu/GpuDynamicValue.d.ts +9 -0
  46. package/build/gpu/GpuDynamicValue.js +113 -0
  47. package/build/gpu/GpuMath.d.ts +3 -0
  48. package/build/gpu/GpuMath.js +12 -0
  49. package/build/gpu/GpuParticleContext.d.ts +63 -0
  50. package/build/gpu/GpuParticleContext.js +291 -0
  51. package/build/helpers/acceptMultiple.d.ts +2 -0
  52. package/build/helpers/acceptMultiple.js +6 -0
  53. package/build/helpers/evaluateDynamic.d.ts +2 -0
  54. package/build/helpers/evaluateDynamic.js +18 -0
  55. package/build/helpers/evaluateDynamicColor.d.ts +3 -0
  56. package/build/helpers/evaluateDynamicColor.js +5 -0
  57. package/build/helpers/evaluateDynamicNumber.d.ts +2 -0
  58. package/build/helpers/evaluateDynamicNumber.js +4 -0
  59. package/build/helpers/evaluateDynamicVector3.d.ts +3 -0
  60. package/build/helpers/evaluateDynamicVector3.js +5 -0
  61. package/build/helpers/isPointInMesh.d.ts +2 -0
  62. package/build/helpers/isPointInMesh.js +8 -0
  63. package/build/helpers/particleRatio.d.ts +2 -0
  64. package/build/helpers/particleRatio.js +13 -0
  65. package/build/helpers/tagsIntersect.d.ts +2 -0
  66. package/build/helpers/tagsIntersect.js +4 -0
  67. package/build/index.d.ts +37 -0
  68. package/build/index.js +34 -0
  69. package/build/interfaces/ICollisionBackend.d.ts +21 -0
  70. package/build/interfaces/ICollisionBackend.js +1 -0
  71. package/build/interfaces/IParticleForceField.d.ts +5 -0
  72. package/build/interfaces/IParticleForceField.js +1 -0
  73. package/build/interfaces/InitialParticleValues.d.ts +18 -0
  74. package/build/interfaces/InitialParticleValues.js +1 -0
  75. package/build/materials/BasicSprite.d.ts +21 -0
  76. package/build/materials/BasicSprite.js +46 -0
  77. package/build/materials/UnlitSprite.d.ts +13 -0
  78. package/build/materials/UnlitSprite.js +31 -0
  79. package/build/materials/WebGPUBasicSprite.d.ts +8 -0
  80. package/build/materials/WebGPUBasicSprite.js +65 -0
  81. package/build/materials/WebGPUUnlitSprite.d.ts +8 -0
  82. package/build/materials/WebGPUUnlitSprite.js +49 -0
  83. package/build/modules/Audio.d.ts +60 -0
  84. package/build/modules/Audio.js +181 -0
  85. package/build/modules/Collision.d.ts +40 -0
  86. package/build/modules/Collision.js +162 -0
  87. package/build/modules/ColorBySpeed.d.ts +18 -0
  88. package/build/modules/ColorBySpeed.js +26 -0
  89. package/build/modules/ColorOverLifetime.d.ts +12 -0
  90. package/build/modules/ColorOverLifetime.js +17 -0
  91. package/build/modules/ExternalForces.d.ts +21 -0
  92. package/build/modules/ExternalForces.js +61 -0
  93. package/build/modules/ForceOverLifetime.d.ts +11 -0
  94. package/build/modules/ForceOverLifetime.js +12 -0
  95. package/build/modules/LimitVelocityOverLifetime.d.ts +16 -0
  96. package/build/modules/LimitVelocityOverLifetime.js +34 -0
  97. package/build/modules/MassOverLifetime.d.ts +11 -0
  98. package/build/modules/MassOverLifetime.js +15 -0
  99. package/build/modules/NoiseModule.d.ts +23 -0
  100. package/build/modules/NoiseModule.js +45 -0
  101. package/build/modules/RotationBySpeed.d.ts +14 -0
  102. package/build/modules/RotationBySpeed.js +19 -0
  103. package/build/modules/RotationOverLifetime.d.ts +11 -0
  104. package/build/modules/RotationOverLifetime.js +12 -0
  105. package/build/modules/ScaleBySpeed.d.ts +14 -0
  106. package/build/modules/ScaleBySpeed.js +19 -0
  107. package/build/modules/ScaleOverLifetime.d.ts +11 -0
  108. package/build/modules/ScaleOverLifetime.js +11 -0
  109. package/build/modules/TransformByNoise.d.ts +17 -0
  110. package/build/modules/TransformByNoise.js +32 -0
  111. package/build/modules/VelocityOverLifetime.d.ts +15 -0
  112. package/build/modules/VelocityOverLifetime.js +32 -0
  113. package/build/renderers/LightRenderer.d.ts +54 -0
  114. package/build/renderers/LightRenderer.js +141 -0
  115. package/build/renderers/MeshRenderer.d.ts +27 -0
  116. package/build/renderers/MeshRenderer.js +70 -0
  117. package/build/renderers/SpriteRenderer.d.ts +95 -0
  118. package/build/renderers/SpriteRenderer.js +456 -0
  119. package/build/renderers/TrailRenderer.d.ts +71 -0
  120. package/build/renderers/TrailRenderer.js +400 -0
  121. package/build/shaders/BasicSprite.frag.js +1 -0
  122. package/build/shaders/BasicSprite.vert.js +1 -0
  123. package/build/shaders/UnlitSprite.frag.js +1 -0
  124. package/build/shaders/UnlitSprite.vert.js +1 -0
  125. package/build/types/DynamicValue.d.ts +2 -0
  126. package/build/types/DynamicValue.js +1 -0
  127. package/build/types/EnumStringLiteral.d.ts +1 -0
  128. package/build/types/EnumStringLiteral.js +1 -0
  129. package/build/types/Multiple.d.ts +2 -0
  130. package/build/types/Multiple.js +1 -0
  131. package/build/types/Tag.d.ts +1 -0
  132. package/build/types/Tag.js +1 -0
  133. package/package.json +39 -0
@@ -0,0 +1,46 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import * as THREE from 'three';
13
+ import basicSpriteVert from '../shaders/BasicSprite.vert.js';
14
+ import basicSpriteFrag from '../shaders/BasicSprite.frag.js';
15
+ const BasicSprite = (texture, options = {}) => {
16
+ const { gridSize, frames, alphaMap, normalMap, normalStrength = 1, normalLighting, sphericalNormals, roughness = 0.5, roughnessMap, envMap, envIntensity = 1.0, softParticles, softParticleDistance = 0 } = options, materialOptions = __rest(options, ["gridSize", "frames", "alphaMap", "normalMap", "normalStrength", "normalLighting", "sphericalNormals", "roughness", "roughnessMap", "envMap", "envIntensity", "softParticles", "softParticleDistance"]);
17
+ return new THREE.ShaderMaterial(Object.assign({ vertexShader: basicSpriteVert, fragmentShader: basicSpriteFrag, uniforms: THREE.UniformsUtils.merge([
18
+ THREE.UniformsLib.lights,
19
+ {
20
+ pointTexture: { value: texture },
21
+ gridSize: { value: gridSize !== null && gridSize !== void 0 ? gridSize : { x: 1, y: 1 } },
22
+ n_frames: { value: frames !== null && frames !== void 0 ? frames : 1 },
23
+ alphaMap: { value: alphaMap !== null && alphaMap !== void 0 ? alphaMap : null },
24
+ hasAlphaMap: { value: Boolean(alphaMap) },
25
+ normalMap: { value: normalMap !== null && normalMap !== void 0 ? normalMap : null },
26
+ hasNormalMap: { value: Boolean(normalMap) },
27
+ normalStrength: { value: normalStrength },
28
+ // Normal lighting, if not already set, defaults to 1 if there is a normal map present and 0 if not.
29
+ normalLighting: { value: normalLighting !== null && normalLighting !== void 0 ? normalLighting : (normalMap ? 1 : 0) },
30
+ sphericalNormals: { value: sphericalNormals !== null && sphericalNormals !== void 0 ? sphericalNormals : false },
31
+ roughness: { value: roughness },
32
+ roughnessMap: { value: roughnessMap !== null && roughnessMap !== void 0 ? roughnessMap : null },
33
+ hasRoughnessMap: { value: Boolean(roughnessMap) },
34
+ envMap: { value: envMap },
35
+ envIntensity: { value: envIntensity },
36
+ hasEnvMap: { value: Boolean(envMap) },
37
+ softParticles: { value: Boolean(softParticleDistance) },
38
+ softParticleDistance: { value: softParticleDistance },
39
+ sceneDepthTexture: { value: null },
40
+ depthResolution: { value: new THREE.Vector2() },
41
+ depthCameraNear: { value: 0.1 },
42
+ depthCameraFar: { value: 2000 },
43
+ },
44
+ ]), depthTest: true, depthWrite: false, lights: true, transparent: true, vertexColors: true }, materialOptions));
45
+ };
46
+ export default BasicSprite;
@@ -0,0 +1,13 @@
1
+ import * as THREE from 'three';
2
+ export interface UnlitSpriteOptions {
3
+ gridSize: {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ frames: number;
8
+ alphaMap: THREE.Texture;
9
+ softParticles: boolean;
10
+ softParticleDistance: number;
11
+ }
12
+ declare const UnlitSprite: (texture: THREE.Texture, options?: Partial<UnlitSpriteOptions>) => THREE.ShaderMaterial;
13
+ export default UnlitSprite;
@@ -0,0 +1,31 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import * as THREE from 'three';
13
+ import unlitSpriteVert from '../shaders/UnlitSprite.vert.js';
14
+ import unlitSpriteFrag from '../shaders/UnlitSprite.frag.js';
15
+ const UnlitSprite = (texture, options = {}) => {
16
+ const { gridSize, frames, alphaMap, softParticles, softParticleDistance = 0 } = options, materialOptions = __rest(options, ["gridSize", "frames", "alphaMap", "softParticles", "softParticleDistance"]);
17
+ return new THREE.ShaderMaterial(Object.assign({ vertexShader: unlitSpriteVert, fragmentShader: unlitSpriteFrag, uniforms: {
18
+ pointTexture: { value: texture },
19
+ gridSize: { value: gridSize !== null && gridSize !== void 0 ? gridSize : { x: 1, y: 1 } },
20
+ n_frames: { value: frames !== null && frames !== void 0 ? frames : 1 },
21
+ alphaMap: { value: alphaMap !== null && alphaMap !== void 0 ? alphaMap : null },
22
+ hasAlphaMap: { value: Boolean(alphaMap) },
23
+ softParticles: { value: Boolean(softParticleDistance) },
24
+ softParticleDistance: { value: softParticleDistance },
25
+ sceneDepthTexture: { value: null },
26
+ depthResolution: { value: new THREE.Vector2() },
27
+ depthCameraNear: { value: 0.1 },
28
+ depthCameraFar: { value: 2000 },
29
+ }, depthTest: true, depthWrite: false, transparent: true, vertexColors: true }, materialOptions));
30
+ };
31
+ export default UnlitSprite;
@@ -0,0 +1,8 @@
1
+ import * as THREE from 'three';
2
+ import MeshStandardNodeMaterial from 'three/src/materials/nodes/MeshStandardNodeMaterial.js';
3
+ import { BasicSpriteOptions } from './BasicSprite';
4
+ type WebGPUBasicSpriteOptions = BasicSpriteOptions & {
5
+ sceneDepthTexture: THREE.DepthTexture;
6
+ };
7
+ declare const WebGPUBasicSprite: (pointTexture: THREE.Texture, options?: Partial<WebGPUBasicSpriteOptions>) => MeshStandardNodeMaterial;
8
+ export default WebGPUBasicSprite;
@@ -0,0 +1,65 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import * as THREE from 'three';
13
+ import MeshStandardNodeMaterial from 'three/src/materials/nodes/MeshStandardNodeMaterial.js';
14
+ import { cameraFar, cameraNear } from 'three/src/nodes/accessors/Camera.js';
15
+ import { attribute } from 'three/src/nodes/core/AttributeNode.js';
16
+ import { positionView } from 'three/src/nodes/accessors/Position.js';
17
+ import { texture } from 'three/src/nodes/accessors/TextureNode.js';
18
+ import { uv } from 'three/src/nodes/accessors/UV.js';
19
+ import { viewportUV } from 'three/src/nodes/display/ScreenNode.js';
20
+ import { perspectiveDepthToViewZ } from 'three/src/nodes/display/ViewportDepthNode.js';
21
+ import { abs, dot, smoothstep } from 'three/src/nodes/math/MathNode.js';
22
+ import { spritesheetUV } from 'three/src/nodes/utils/SpriteSheetUV.js';
23
+ import { float, vec2, vec3 } from 'three/src/nodes/tsl/TSLBase.js';
24
+ const WebGPUBasicSprite = (pointTexture, options = {}) => {
25
+ var _a, _b;
26
+ const { gridSize, frames, alphaMap, normalMap, normalStrength, roughness, roughnessMap, envMap, envIntensity, normalLighting, sphericalNormals, softParticles, softParticleDistance, sceneDepthTexture } = options, materialOptions = __rest(options, ["gridSize", "frames", "alphaMap", "normalMap", "normalStrength", "roughness", "roughnessMap", "envMap", "envIntensity", "normalLighting", "sphericalNormals", "softParticles", "softParticleDistance", "sceneDepthTexture"]);
27
+ const material = new MeshStandardNodeMaterial(Object.assign({ depthTest: true, depthWrite: false, metalness: 0, roughness: roughness !== null && roughness !== void 0 ? roughness : 0.5, transparent: true, vertexColors: true, side: THREE.DoubleSide }, materialOptions));
28
+ const spriteUv = spritesheetUV(vec2((_a = gridSize === null || gridSize === void 0 ? void 0 : gridSize.x) !== null && _a !== void 0 ? _a : 1, (_b = gridSize === null || gridSize === void 0 ? void 0 : gridSize.y) !== null && _b !== void 0 ? _b : 1), uv(), attribute('frame', 'float'));
29
+ const spriteColor = texture(pointTexture, spriteUv);
30
+ let opacity = spriteColor.a.mul(attribute('instanceAlpha', 'float'));
31
+ if (alphaMap) {
32
+ opacity = opacity.mul(texture(alphaMap, spriteUv).r);
33
+ }
34
+ if (softParticleDistance && sceneDepthTexture) {
35
+ const sceneViewZ = perspectiveDepthToViewZ(texture(sceneDepthTexture, viewportUV).r, cameraNear, cameraFar);
36
+ const particleViewZ = positionView.z;
37
+ const fade = smoothstep(float(0), float(softParticleDistance), abs(particleViewZ.sub(sceneViewZ)));
38
+ opacity = opacity.mul(fade);
39
+ }
40
+ if (sphericalNormals) {
41
+ const localUv = uv().mul(2).sub(1);
42
+ const normalZ = float(1).sub(dot(localUv, localUv)).max(0).sqrt();
43
+ material.normalNode = vec3(localUv.x, localUv.y, normalZ).normalize();
44
+ }
45
+ material.name = 'RZMPS WebGPU Basic Sprite';
46
+ material.colorNode = spriteColor.rgb;
47
+ material.opacityNode = opacity;
48
+ material.alphaTest = 0.001;
49
+ material.envMap = envMap !== null && envMap !== void 0 ? envMap : null;
50
+ material.envMapIntensity = envIntensity !== null && envIntensity !== void 0 ? envIntensity : 1;
51
+ material.roughnessNode = roughnessMap
52
+ ? texture(roughnessMap, spriteUv).r.mul(roughness !== null && roughness !== void 0 ? roughness : 0.5)
53
+ : float(roughness !== null && roughness !== void 0 ? roughness : 0.5);
54
+ material.metalnessNode = float(0);
55
+ material.userData.frames = frames !== null && frames !== void 0 ? frames : 1;
56
+ material.userData.normalMap = normalMap;
57
+ material.userData.normalStrength = normalStrength;
58
+ material.userData.roughnessMap = roughnessMap;
59
+ material.userData.normalLighting = normalLighting;
60
+ material.userData.sphericalNormals = sphericalNormals;
61
+ material.userData.softParticles = softParticles;
62
+ material.userData.softParticleDistance = softParticleDistance;
63
+ return material;
64
+ };
65
+ export default WebGPUBasicSprite;
@@ -0,0 +1,8 @@
1
+ import * as THREE from 'three';
2
+ import MeshBasicNodeMaterial from 'three/src/materials/nodes/MeshBasicNodeMaterial.js';
3
+ import { UnlitSpriteOptions } from './UnlitSprite';
4
+ type WebGPUUnlitSpriteOptions = UnlitSpriteOptions & {
5
+ sceneDepthTexture: THREE.DepthTexture;
6
+ };
7
+ declare const WebGPUUnlitSprite: (pointTexture: THREE.Texture, options?: Partial<WebGPUUnlitSpriteOptions>) => MeshBasicNodeMaterial;
8
+ export default WebGPUUnlitSprite;
@@ -0,0 +1,49 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import * as THREE from 'three';
13
+ import MeshBasicNodeMaterial from 'three/src/materials/nodes/MeshBasicNodeMaterial.js';
14
+ import { cameraFar, cameraNear } from 'three/src/nodes/accessors/Camera.js';
15
+ import { attribute } from 'three/src/nodes/core/AttributeNode.js';
16
+ import { positionView } from 'three/src/nodes/accessors/Position.js';
17
+ import { texture } from 'three/src/nodes/accessors/TextureNode.js';
18
+ import { uv } from 'three/src/nodes/accessors/UV.js';
19
+ import { viewportUV } from 'three/src/nodes/display/ScreenNode.js';
20
+ import { perspectiveDepthToViewZ } from 'three/src/nodes/display/ViewportDepthNode.js';
21
+ import { abs, smoothstep } from 'three/src/nodes/math/MathNode.js';
22
+ import { spritesheetUV } from 'three/src/nodes/utils/SpriteSheetUV.js';
23
+ import { float, vec2 } from 'three/src/nodes/tsl/TSLBase.js';
24
+ const WebGPUUnlitSprite = (pointTexture, options = {}) => {
25
+ var _a, _b;
26
+ const { gridSize, frames, alphaMap, softParticles, softParticleDistance, sceneDepthTexture } = options, materialOptions = __rest(options, ["gridSize", "frames", "alphaMap", "softParticles", "softParticleDistance", "sceneDepthTexture"]);
27
+ const material = new MeshBasicNodeMaterial(Object.assign({ depthTest: true, depthWrite: false, transparent: true, vertexColors: true, side: THREE.DoubleSide }, materialOptions));
28
+ const spriteUv = spritesheetUV(vec2((_a = gridSize === null || gridSize === void 0 ? void 0 : gridSize.x) !== null && _a !== void 0 ? _a : 1, (_b = gridSize === null || gridSize === void 0 ? void 0 : gridSize.y) !== null && _b !== void 0 ? _b : 1), uv(), attribute('frame', 'float'));
29
+ const spriteColor = texture(pointTexture, spriteUv);
30
+ let opacity = spriteColor.a.mul(attribute('instanceAlpha', 'float'));
31
+ if (alphaMap) {
32
+ opacity = opacity.mul(texture(alphaMap, spriteUv).r);
33
+ }
34
+ if (softParticleDistance && sceneDepthTexture) {
35
+ const sceneViewZ = perspectiveDepthToViewZ(texture(sceneDepthTexture, viewportUV).r, cameraNear, cameraFar);
36
+ const particleViewZ = positionView.z;
37
+ const fade = smoothstep(float(0), float(softParticleDistance), abs(particleViewZ.sub(sceneViewZ)));
38
+ opacity = opacity.mul(fade);
39
+ }
40
+ material.name = 'RZMPS WebGPU Unlit Sprite';
41
+ material.colorNode = spriteColor.rgb;
42
+ material.opacityNode = opacity;
43
+ material.alphaTest = 0.001;
44
+ material.userData.frames = frames !== null && frames !== void 0 ? frames : 1;
45
+ material.userData.softParticles = softParticles;
46
+ material.userData.softParticleDistance = softParticleDistance;
47
+ return material;
48
+ };
49
+ export default WebGPUUnlitSprite;
@@ -0,0 +1,60 @@
1
+ import * as THREE from 'three';
2
+ import Module, { ModuleOptions } from '../Module';
3
+ import Particle from '../Particle';
4
+ import ParticleSystem from '../ParticleSystem';
5
+ import { DynamicValue } from '../types/DynamicValue';
6
+ import { StrictMultiple } from '../types/Multiple';
7
+ export interface AudioOptions extends Partial<ModuleOptions> {
8
+ listener: THREE.AudioListener;
9
+ sound: StrictMultiple<AudioBuffer>;
10
+ onCollisionSound: StrictMultiple<AudioBuffer>;
11
+ onSpawnSound: StrictMultiple<AudioBuffer>;
12
+ onDeathSound: StrictMultiple<AudioBuffer>;
13
+ shouldPlay: (particle: Particle) => boolean;
14
+ loop: boolean;
15
+ ratio: number;
16
+ collisionRatio: number;
17
+ pitch: DynamicValue<number>;
18
+ volume: DynamicValue<number>;
19
+ sizeAffectsPitch: number;
20
+ sizeAffectsVolume: number;
21
+ alphaAffectsPitch: number;
22
+ alphaAffectsVolume: number;
23
+ speedAffectsPitch: number;
24
+ speedAffectsVolume: number;
25
+ }
26
+ declare class Audio extends Module {
27
+ listener?: THREE.AudioListener;
28
+ sound?: AudioBuffer[];
29
+ onCollisionSound?: AudioBuffer[];
30
+ onSpawnSound?: AudioBuffer[];
31
+ onDeathSound?: AudioBuffer[];
32
+ shouldPlay: (particle: Particle) => boolean;
33
+ loop: boolean;
34
+ ratio: number;
35
+ collisionRatio: number;
36
+ pitch: DynamicValue<number>;
37
+ volume: DynamicValue<number>;
38
+ sizeAffectsPitch: number;
39
+ sizeAffectsVolume: number;
40
+ alphaAffectsPitch: number;
41
+ alphaAffectsVolume: number;
42
+ speedAffectsPitch: number;
43
+ speedAffectsVolume: number;
44
+ private _system?;
45
+ private _particleAudio;
46
+ private _eventAudio;
47
+ private _setupCallbacks;
48
+ constructor(options?: Partial<AudioOptions>);
49
+ prepare(system: ParticleSystem): void;
50
+ private _updateParticle;
51
+ private _handleEvent;
52
+ private _playOneShot;
53
+ private _getPitch;
54
+ private _getVolume;
55
+ private _getEffect;
56
+ private _cleanParticleAudio;
57
+ private _removeParticleAudio;
58
+ cleanup(): void;
59
+ }
60
+ export default Audio;
@@ -0,0 +1,181 @@
1
+ import * as THREE from 'three';
2
+ import Module from '../Module';
3
+ import evaluateDynamicNumber from '../helpers/evaluateDynamicNumber';
4
+ import particleRatio from '../helpers/particleRatio';
5
+ import acceptMultiple from '../helpers/acceptMultiple';
6
+ const AUDIO_LISTENER_KEY = "__rzmps_audioListener";
7
+ class Audio extends Module {
8
+ constructor(options = {}) {
9
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
10
+ super((particle) => this._updateParticle(particle), options);
11
+ this.shouldPlay = () => true;
12
+ this.loop = true;
13
+ this._particleAudio = new Map();
14
+ this._eventAudio = new Set();
15
+ this._setupCallbacks = false;
16
+ this.listener = options.listener;
17
+ this.sound = options.sound
18
+ ? acceptMultiple(options.sound)
19
+ : undefined;
20
+ this.onCollisionSound = options.onCollisionSound
21
+ ? acceptMultiple(options.onCollisionSound)
22
+ : undefined;
23
+ this.onSpawnSound = options.onSpawnSound
24
+ ? acceptMultiple(options.onSpawnSound)
25
+ : undefined;
26
+ this.onDeathSound = options.onDeathSound
27
+ ? acceptMultiple(options.onDeathSound)
28
+ : undefined;
29
+ this.shouldPlay = (_a = options.shouldPlay) !== null && _a !== void 0 ? _a : this.shouldPlay;
30
+ this.loop = (_b = options.loop) !== null && _b !== void 0 ? _b : this.loop;
31
+ this.ratio = THREE.MathUtils.clamp((_c = options.ratio) !== null && _c !== void 0 ? _c : 1, 0, 1);
32
+ this.collisionRatio = THREE.MathUtils.clamp((_d = options.collisionRatio) !== null && _d !== void 0 ? _d : this.ratio, 0, 1);
33
+ this.pitch = (_e = options.pitch) !== null && _e !== void 0 ? _e : 1;
34
+ this.volume = (_f = options.volume) !== null && _f !== void 0 ? _f : 1;
35
+ this.sizeAffectsPitch = Math.max(0, (_g = options.sizeAffectsPitch) !== null && _g !== void 0 ? _g : 0);
36
+ this.sizeAffectsVolume = Math.max(0, (_h = options.sizeAffectsVolume) !== null && _h !== void 0 ? _h : 0);
37
+ this.alphaAffectsPitch = Math.max(0, (_j = options.alphaAffectsPitch) !== null && _j !== void 0 ? _j : 0);
38
+ this.alphaAffectsVolume = Math.max(0, (_k = options.alphaAffectsVolume) !== null && _k !== void 0 ? _k : 0);
39
+ this.speedAffectsPitch = Math.max(0, (_l = options.speedAffectsPitch) !== null && _l !== void 0 ? _l : 0);
40
+ this.speedAffectsVolume = Math.max(0, (_m = options.speedAffectsVolume) !== null && _m !== void 0 ? _m : 0);
41
+ }
42
+ prepare(system) {
43
+ this._system = system;
44
+ if (!this._setupCallbacks) {
45
+ system.onCollision((particle, _) => this._handleEvent(particle, this.onCollisionSound));
46
+ system.onDeath((particle) => this._handleEvent(particle, this.onDeathSound));
47
+ system.onSpawn((particle) => this._handleEvent(particle, this.onSpawnSound));
48
+ this._setupCallbacks = true;
49
+ }
50
+ if (!this.listener) {
51
+ // Try to get listener from cache
52
+ if (system.scene)
53
+ this.listener = system.scene.userData[AUDIO_LISTENER_KEY];
54
+ // Try to get listener from camera
55
+ if (system.sceneCamera) {
56
+ system.sceneCamera.traverse((object) => {
57
+ if (!this.listener && object instanceof THREE.AudioListener) {
58
+ this.listener = object;
59
+ }
60
+ });
61
+ // Add to camera if its not there
62
+ if (!this.listener) {
63
+ this.listener = new THREE.AudioListener();
64
+ system.sceneCamera.add(this.listener);
65
+ }
66
+ }
67
+ // If we found a listener, add it to the scene cache
68
+ if (this.listener && system.scene)
69
+ system.scene.userData[AUDIO_LISTENER_KEY] = this.listener;
70
+ }
71
+ this._cleanParticleAudio(system.particles);
72
+ }
73
+ _updateParticle(particle) {
74
+ if (!this.listener || !this.sound || !this._system)
75
+ return;
76
+ if (!particleRatio(particle, this.ratio) || !this.shouldPlay(particle)) {
77
+ this._removeParticleAudio(particle.id);
78
+ return;
79
+ }
80
+ let state = this._particleAudio.get(particle.id);
81
+ if (!state) {
82
+ const audio = new THREE.PositionalAudio(this.listener);
83
+ const sound = this.sound[Math.floor(Math.random() * this.sound.length)];
84
+ audio.setBuffer(sound);
85
+ audio.setLoop(this.loop);
86
+ this._system.add(audio);
87
+ state = {
88
+ audio,
89
+ buffer: sound,
90
+ };
91
+ this._particleAudio.set(particle.id, state);
92
+ audio.play();
93
+ }
94
+ state.audio.position.copy(particle.position);
95
+ state.audio.setPlaybackRate(this._getPitch(particle));
96
+ state.audio.setVolume(this._getVolume(particle));
97
+ }
98
+ _handleEvent(particle, audio) {
99
+ if (!audio
100
+ || (audio === null || audio === void 0 ? void 0 : audio.length) === 0
101
+ || !particleRatio(particle, this.collisionRatio)
102
+ || !this.shouldPlay(particle)) {
103
+ return;
104
+ }
105
+ this._playOneShot(audio[Math.floor(Math.random() * audio.length)], particle);
106
+ }
107
+ _playOneShot(clip, particle) {
108
+ if (!this.listener || !this._system)
109
+ return;
110
+ const audio = new THREE.PositionalAudio(this.listener);
111
+ audio.setBuffer(clip);
112
+ audio.setLoop(false);
113
+ audio.position.copy(particle.position);
114
+ audio.setPlaybackRate(this._getPitch(particle));
115
+ audio.setVolume(this._getVolume(particle));
116
+ this._system.add(audio);
117
+ this._eventAudio.add(audio);
118
+ audio.play();
119
+ /*
120
+ * THREE.Audio creates a new AudioBufferSourceNode when play() is
121
+ * called. Clean the temporary source up once that playback ends.
122
+ */
123
+ if (audio.source) {
124
+ audio.source.addEventListener('ended', () => {
125
+ this._eventAudio.delete(audio);
126
+ audio.removeFromParent();
127
+ });
128
+ }
129
+ }
130
+ _getPitch(particle) {
131
+ const base = evaluateDynamicNumber(this.pitch, particle.time, particle.id);
132
+ return Math.max(0, base
133
+ * this._getEffect(particle.scale.length(), this.sizeAffectsPitch)
134
+ * this._getEffect(particle.alpha, this.alphaAffectsPitch)
135
+ * this._getEffect(particle.velocity.length() * particle.speed, this.speedAffectsPitch));
136
+ }
137
+ _getVolume(particle) {
138
+ const base = evaluateDynamicNumber(this.volume, particle.time, particle.id);
139
+ return Math.max(0, base
140
+ * this._getEffect(particle.scale.length(), this.sizeAffectsVolume)
141
+ * this._getEffect(particle.alpha, this.alphaAffectsVolume)
142
+ * this._getEffect(particle.velocity.length(), this.speedAffectsVolume));
143
+ }
144
+ // eslint-disable-next-line class-methods-use-this
145
+ _getEffect(value, effect) {
146
+ return Math.pow(Math.max(0, value), effect);
147
+ }
148
+ _cleanParticleAudio(particles) {
149
+ const activeParticles = new Set(particles
150
+ .filter((particle) => particleRatio(particle, this.ratio))
151
+ .map((particle) => particle.id));
152
+ this._particleAudio.forEach((_state, id) => {
153
+ if (!activeParticles.has(id)) {
154
+ this._removeParticleAudio(id);
155
+ }
156
+ });
157
+ }
158
+ _removeParticleAudio(id) {
159
+ const state = this._particleAudio.get(id);
160
+ if (!state)
161
+ return;
162
+ if (state.audio.isPlaying) {
163
+ state.audio.stop();
164
+ }
165
+ state.audio.removeFromParent();
166
+ this._particleAudio.delete(id);
167
+ }
168
+ cleanup() {
169
+ this._particleAudio.forEach((_state, id) => {
170
+ this._removeParticleAudio(id);
171
+ });
172
+ this._eventAudio.forEach((audio) => {
173
+ if (audio.isPlaying) {
174
+ audio.stop();
175
+ }
176
+ audio.removeFromParent();
177
+ });
178
+ this._eventAudio.clear();
179
+ }
180
+ }
181
+ export default Audio;
@@ -0,0 +1,40 @@
1
+ import Module, { ModuleOptions } from '../Module';
2
+ import Particle from '../Particle';
3
+ import { DynamicValue } from '../types/DynamicValue';
4
+ import { ICollisionBackend, CollisionHit } from '../interfaces/ICollisionBackend';
5
+ import ParticleSystem from '../ParticleSystem';
6
+ export type CollisionListener = (particle: Particle, collision: CollisionHit) => void;
7
+ export interface CollisionOptions extends Partial<ModuleOptions> {
8
+ backend: ICollisionBackend;
9
+ dampen: DynamicValue<number>;
10
+ bounce: DynamicValue<number>;
11
+ lifetimeLoss: DynamicValue<number>;
12
+ applyImpulses: boolean;
13
+ radiusScale: number;
14
+ minKillSpeed: number;
15
+ maxKillSpeed: number;
16
+ onCollision?: CollisionListener;
17
+ }
18
+ declare class Collision extends Module {
19
+ backend?: ICollisionBackend;
20
+ dampen: DynamicValue<number>;
21
+ bounce: DynamicValue<number>;
22
+ lifetimeLoss: DynamicValue<number>;
23
+ applyImpulses: boolean;
24
+ radiusScale: number;
25
+ minKillSpeed: number;
26
+ maxKillSpeed: number;
27
+ private collisionListeners;
28
+ private _system?;
29
+ constructor(options?: Partial<CollisionOptions>);
30
+ onCollision(listener: CollisionListener): void;
31
+ removeCollisionListener(listener: CollisionListener): void;
32
+ prepare(system: ParticleSystem, deltaTime: number): void;
33
+ private collide;
34
+ private resolvePosition;
35
+ private resolveVelocity;
36
+ private resolveLifetime;
37
+ private getParticleRadius;
38
+ private killParticle;
39
+ }
40
+ export default Collision;