@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.
- package/README.md +1048 -0
- package/build/EmissionShape.d.ts +33 -0
- package/build/EmissionShape.js +129 -0
- package/build/Emitter.d.ts +58 -0
- package/build/Emitter.js +166 -0
- package/build/GpuModule.d.ts +28 -0
- package/build/GpuModule.js +28 -0
- package/build/Module.d.ts +19 -0
- package/build/Module.js +31 -0
- package/build/Particle.d.ts +60 -0
- package/build/Particle.js +52 -0
- package/build/ParticleForceField.d.ts +39 -0
- package/build/ParticleForceField.js +101 -0
- package/build/ParticleForceFieldHelper.d.ts +18 -0
- package/build/ParticleForceFieldHelper.js +103 -0
- package/build/ParticleSystem.d.ts +122 -0
- package/build/ParticleSystem.js +609 -0
- package/build/Renderer.d.ts +15 -0
- package/build/Renderer.js +11 -0
- package/build/assets/images/default.png +0 -0
- package/build/collision/ThreeCollisionBackend.d.ts +47 -0
- package/build/collision/ThreeCollisionBackend.js +340 -0
- package/build/enums/Axis.d.ts +6 -0
- package/build/enums/Axis.js +7 -0
- package/build/enums/DynamicValueType.d.ts +6 -0
- package/build/enums/DynamicValueType.js +7 -0
- package/build/enums/EmissionSource copy.d.ts +7 -0
- package/build/enums/EmissionSource copy.js +7 -0
- package/build/enums/EmissionSource.d.ts +7 -0
- package/build/enums/EmissionSource.js +7 -0
- package/build/enums/EndBehavior.d.ts +6 -0
- package/build/enums/EndBehavior.js +7 -0
- package/build/enums/SimulationSpace.d.ts +5 -0
- package/build/enums/SimulationSpace.js +6 -0
- package/build/enums/SpriteMaterialType.d.ts +5 -0
- package/build/enums/SpriteMaterialType.js +6 -0
- package/build/enums/TagSelectionMethod.d.ts +6 -0
- package/build/enums/TagSelectionMethod.js +7 -0
- package/build/enums/TrailMode copy.d.ts +5 -0
- package/build/enums/TrailMode copy.js +7 -0
- package/build/enums/TrailMode.d.ts +5 -0
- package/build/enums/TrailMode.js +7 -0
- package/build/enums/TrailTextureMode.d.ts +7 -0
- package/build/enums/TrailTextureMode.js +9 -0
- package/build/gpu/GpuDynamicValue.d.ts +9 -0
- package/build/gpu/GpuDynamicValue.js +113 -0
- package/build/gpu/GpuMath.d.ts +3 -0
- package/build/gpu/GpuMath.js +12 -0
- package/build/gpu/GpuParticleContext.d.ts +63 -0
- package/build/gpu/GpuParticleContext.js +291 -0
- package/build/helpers/acceptMultiple.d.ts +2 -0
- package/build/helpers/acceptMultiple.js +6 -0
- package/build/helpers/evaluateDynamic.d.ts +2 -0
- package/build/helpers/evaluateDynamic.js +18 -0
- package/build/helpers/evaluateDynamicColor.d.ts +3 -0
- package/build/helpers/evaluateDynamicColor.js +5 -0
- package/build/helpers/evaluateDynamicNumber.d.ts +2 -0
- package/build/helpers/evaluateDynamicNumber.js +4 -0
- package/build/helpers/evaluateDynamicVector3.d.ts +3 -0
- package/build/helpers/evaluateDynamicVector3.js +5 -0
- package/build/helpers/isPointInMesh.d.ts +2 -0
- package/build/helpers/isPointInMesh.js +8 -0
- package/build/helpers/particleRatio.d.ts +2 -0
- package/build/helpers/particleRatio.js +13 -0
- package/build/helpers/tagsIntersect.d.ts +2 -0
- package/build/helpers/tagsIntersect.js +4 -0
- package/build/index.d.ts +37 -0
- package/build/index.js +34 -0
- package/build/interfaces/ICollisionBackend.d.ts +21 -0
- package/build/interfaces/ICollisionBackend.js +1 -0
- package/build/interfaces/IParticleForceField.d.ts +5 -0
- package/build/interfaces/IParticleForceField.js +1 -0
- package/build/interfaces/InitialParticleValues.d.ts +18 -0
- package/build/interfaces/InitialParticleValues.js +1 -0
- package/build/materials/BasicSprite.d.ts +21 -0
- package/build/materials/BasicSprite.js +46 -0
- package/build/materials/UnlitSprite.d.ts +13 -0
- package/build/materials/UnlitSprite.js +31 -0
- package/build/materials/WebGPUBasicSprite.d.ts +8 -0
- package/build/materials/WebGPUBasicSprite.js +65 -0
- package/build/materials/WebGPUUnlitSprite.d.ts +8 -0
- package/build/materials/WebGPUUnlitSprite.js +49 -0
- package/build/modules/Audio.d.ts +60 -0
- package/build/modules/Audio.js +181 -0
- package/build/modules/Collision.d.ts +40 -0
- package/build/modules/Collision.js +162 -0
- package/build/modules/ColorBySpeed.d.ts +18 -0
- package/build/modules/ColorBySpeed.js +26 -0
- package/build/modules/ColorOverLifetime.d.ts +12 -0
- package/build/modules/ColorOverLifetime.js +17 -0
- package/build/modules/ExternalForces.d.ts +21 -0
- package/build/modules/ExternalForces.js +61 -0
- package/build/modules/ForceOverLifetime.d.ts +11 -0
- package/build/modules/ForceOverLifetime.js +12 -0
- package/build/modules/LimitVelocityOverLifetime.d.ts +16 -0
- package/build/modules/LimitVelocityOverLifetime.js +34 -0
- package/build/modules/MassOverLifetime.d.ts +11 -0
- package/build/modules/MassOverLifetime.js +15 -0
- package/build/modules/NoiseModule.d.ts +23 -0
- package/build/modules/NoiseModule.js +45 -0
- package/build/modules/RotationBySpeed.d.ts +14 -0
- package/build/modules/RotationBySpeed.js +19 -0
- package/build/modules/RotationOverLifetime.d.ts +11 -0
- package/build/modules/RotationOverLifetime.js +12 -0
- package/build/modules/ScaleBySpeed.d.ts +14 -0
- package/build/modules/ScaleBySpeed.js +19 -0
- package/build/modules/ScaleOverLifetime.d.ts +11 -0
- package/build/modules/ScaleOverLifetime.js +11 -0
- package/build/modules/TransformByNoise.d.ts +17 -0
- package/build/modules/TransformByNoise.js +32 -0
- package/build/modules/VelocityOverLifetime.d.ts +15 -0
- package/build/modules/VelocityOverLifetime.js +32 -0
- package/build/renderers/LightRenderer.d.ts +54 -0
- package/build/renderers/LightRenderer.js +141 -0
- package/build/renderers/MeshRenderer.d.ts +27 -0
- package/build/renderers/MeshRenderer.js +70 -0
- package/build/renderers/SpriteRenderer.d.ts +95 -0
- package/build/renderers/SpriteRenderer.js +456 -0
- package/build/renderers/TrailRenderer.d.ts +71 -0
- package/build/renderers/TrailRenderer.js +400 -0
- package/build/shaders/BasicSprite.frag.js +1 -0
- package/build/shaders/BasicSprite.vert.js +1 -0
- package/build/shaders/UnlitSprite.frag.js +1 -0
- package/build/shaders/UnlitSprite.vert.js +1 -0
- package/build/types/DynamicValue.d.ts +2 -0
- package/build/types/DynamicValue.js +1 -0
- package/build/types/EnumStringLiteral.d.ts +1 -0
- package/build/types/EnumStringLiteral.js +1 -0
- package/build/types/Multiple.d.ts +2 -0
- package/build/types/Multiple.js +1 -0
- package/build/types/Tag.d.ts +1 -0
- package/build/types/Tag.js +1 -0
- 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;
|