@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,456 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import Renderer from '../Renderer';
|
|
3
|
+
import simple from '../assets/images/default.png';
|
|
4
|
+
import UnlitSprite from '../materials/UnlitSprite';
|
|
5
|
+
import BasicSprite from '../materials/BasicSprite';
|
|
6
|
+
import WebGPUUnlitSprite from '../materials/WebGPUUnlitSprite';
|
|
7
|
+
import WebGPUBasicSprite from '../materials/WebGPUBasicSprite';
|
|
8
|
+
import evaluateDynamicNumber from '../helpers/evaluateDynamicNumber';
|
|
9
|
+
import seedrandom from 'seedrandom';
|
|
10
|
+
import { SpriteMaterialType } from '../enums/SpriteMaterialType';
|
|
11
|
+
import { TRAIL_RENDERER_USER_DATA_KEY } from './TrailRenderer';
|
|
12
|
+
export const SPRITE_RENDERER_USER_DATA_KEY = "__rzmps_spriteRenderer";
|
|
13
|
+
export const SCENE_DEPTH_DATA_USER_DATA_KEY = "__rzmps_sceneDepthData";
|
|
14
|
+
export const WEBGPU_SCENE_DEPTH_DATA_USER_DATA_KEY = "__rzmps_webgpuSceneDepthData";
|
|
15
|
+
export const WEBGPU_SCENE_DEPTH_TEXTURE = new THREE.DepthTexture(1, 1, THREE.UnsignedIntType);
|
|
16
|
+
class SpriteRenderer extends Renderer {
|
|
17
|
+
get materialOptions() { return this._materialOptions; }
|
|
18
|
+
set materialOptions(value) {
|
|
19
|
+
this._materialOptions = value;
|
|
20
|
+
this.material = this.loadMaterial(value);
|
|
21
|
+
this.points.material = this.material;
|
|
22
|
+
this.webgpuMaterial = this.loadWebGPUMaterial(value);
|
|
23
|
+
this.webgpuMesh.material = this.webgpuMaterial;
|
|
24
|
+
}
|
|
25
|
+
constructor(texture = simple, options = {}) {
|
|
26
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
27
|
+
super(options);
|
|
28
|
+
this.frames = 1;
|
|
29
|
+
this.materialType = SpriteMaterialType.Unlit;
|
|
30
|
+
this.tileSize = new THREE.Vector2(0, 0);
|
|
31
|
+
this.tileMargin = new THREE.Vector2(0, 0);
|
|
32
|
+
this.gridSize = new THREE.Vector2(1, 1);
|
|
33
|
+
this.fps = 1;
|
|
34
|
+
this.randomStartFrame = false;
|
|
35
|
+
this.castShadow = false;
|
|
36
|
+
this.softParticleDistance = 0;
|
|
37
|
+
this.hiddenMaterial = new THREE.MeshBasicMaterial({
|
|
38
|
+
colorWrite: false,
|
|
39
|
+
depthWrite: false,
|
|
40
|
+
transparent: true,
|
|
41
|
+
opacity: 0,
|
|
42
|
+
});
|
|
43
|
+
this.webgpuCapacity = 10000;
|
|
44
|
+
this.matrix = new THREE.Matrix4();
|
|
45
|
+
this.quaternion = new THREE.Quaternion();
|
|
46
|
+
this.cameraQuaternion = new THREE.Quaternion();
|
|
47
|
+
this.rollQuaternion = new THREE.Quaternion();
|
|
48
|
+
this.rollAxis = new THREE.Vector3(0, 0, 1);
|
|
49
|
+
this.scaleVector = new THREE.Vector3();
|
|
50
|
+
this.color = new THREE.Color();
|
|
51
|
+
const textureLoader = new THREE.TextureLoader();
|
|
52
|
+
this.texture = typeof texture === 'string' ? textureLoader.load(texture, (tex) => {
|
|
53
|
+
if (!options.tileSize) {
|
|
54
|
+
this.tileSize = new THREE.Vector2(tex.image.naturalWidth / this.gridSize.x, tex.image.naturalHeight / this.gridSize.y);
|
|
55
|
+
}
|
|
56
|
+
}) : texture;
|
|
57
|
+
this.fps = (_a = options.fps) !== null && _a !== void 0 ? _a : 1;
|
|
58
|
+
this.alphaMap = typeof options.alphaMap === 'string'
|
|
59
|
+
? textureLoader.load(options.alphaMap)
|
|
60
|
+
: options.alphaMap;
|
|
61
|
+
this.materialType = (_b = options.material) !== null && _b !== void 0 ? _b : this.materialType;
|
|
62
|
+
this.tileSize = new THREE.Vector2((_c = options.tileSize) === null || _c === void 0 ? void 0 : _c.x, (_d = options.tileSize) === null || _d === void 0 ? void 0 : _d.y);
|
|
63
|
+
this.tileMargin = new THREE.Vector2((_e = options.tileMargin) === null || _e === void 0 ? void 0 : _e.x, (_f = options.tileMargin) === null || _f === void 0 ? void 0 : _f.y);
|
|
64
|
+
this.gridSize = new THREE.Vector2((_h = (_g = options.gridSize) === null || _g === void 0 ? void 0 : _g.x) !== null && _h !== void 0 ? _h : 1, (_k = (_j = options.gridSize) === null || _j === void 0 ? void 0 : _j.y) !== null && _k !== void 0 ? _k : 1);
|
|
65
|
+
this.castShadow = (_l = options.castShadow) !== null && _l !== void 0 ? _l : this.castShadow;
|
|
66
|
+
this.softParticleDistance = (_p = (_m = options.softParticleDistance) !== null && _m !== void 0 ? _m : (_o = options.materialOptions) === null || _o === void 0 ? void 0 : _o.softParticleDistance) !== null && _p !== void 0 ? _p : 0;
|
|
67
|
+
this.frames = (_q = options.frames) !== null && _q !== void 0 ? _q : this.gridSize.x * this.gridSize.y;
|
|
68
|
+
this.randomStartFrame = (_r = options.randomStartFrame) !== null && _r !== void 0 ? _r : false;
|
|
69
|
+
this.geometry = new THREE.BufferGeometry();
|
|
70
|
+
// Set material options and load material
|
|
71
|
+
this._materialOptions = options.materialOptions;
|
|
72
|
+
this.material = this.loadMaterial(this._materialOptions);
|
|
73
|
+
this.points = new THREE.Points(this.geometry, this.material);
|
|
74
|
+
this.points.frustumCulled = false;
|
|
75
|
+
this.points.castShadow = this.castShadow;
|
|
76
|
+
this.points.visible = false;
|
|
77
|
+
this.points.material = this.hiddenMaterial;
|
|
78
|
+
this.webgpuGeometry = new THREE.PlaneGeometry(1, 1);
|
|
79
|
+
this.webgpuFrameAttribute = new THREE.InstancedBufferAttribute(new Float32Array(this.webgpuCapacity), 1);
|
|
80
|
+
this.webgpuAlphaAttribute = new THREE.InstancedBufferAttribute(new Float32Array(this.webgpuCapacity), 1);
|
|
81
|
+
this.webgpuGeometry.setAttribute('frame', this.webgpuFrameAttribute);
|
|
82
|
+
this.webgpuGeometry.setAttribute('instanceAlpha', this.webgpuAlphaAttribute);
|
|
83
|
+
this.webgpuMaterial = this.loadWebGPUMaterial(this._materialOptions);
|
|
84
|
+
this.webgpuMesh = new THREE.InstancedMesh(this.webgpuGeometry, this.webgpuMaterial, this.webgpuCapacity);
|
|
85
|
+
this.webgpuMesh.frustumCulled = false;
|
|
86
|
+
this.webgpuMesh.castShadow = this.castShadow;
|
|
87
|
+
this.webgpuMesh.count = 0;
|
|
88
|
+
this.webgpuMesh.visible = false;
|
|
89
|
+
this.webgpuMesh.setColorAt(0, new THREE.Color(1, 1, 1));
|
|
90
|
+
// Add user data to the points so we can recognize it elsewhere
|
|
91
|
+
this.points.userData[SPRITE_RENDERER_USER_DATA_KEY] = true;
|
|
92
|
+
this.webgpuMesh.userData[SPRITE_RENDERER_USER_DATA_KEY] = true;
|
|
93
|
+
}
|
|
94
|
+
setup(system) {
|
|
95
|
+
system.addRendererObject(this.points);
|
|
96
|
+
system.addRendererObject(this.webgpuMesh);
|
|
97
|
+
this.points.onBeforeRender = (renderer) => this.setActiveRenderer(renderer);
|
|
98
|
+
this.webgpuMesh.onBeforeRender = (renderer) => this.setActiveRenderer(renderer);
|
|
99
|
+
}
|
|
100
|
+
_update(particles, system) {
|
|
101
|
+
var _a, _b, _c, _d, _e;
|
|
102
|
+
this.setActiveRenderer(system.sceneRenderer);
|
|
103
|
+
// Update attributes
|
|
104
|
+
if (this.isWebGPURenderer(system.sceneRenderer)) {
|
|
105
|
+
this.updateWebGPUInstances(particles, system.sceneCamera, system.sceneRenderer);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.updateAttributes(particles);
|
|
109
|
+
}
|
|
110
|
+
// Should the points cast a shadow?
|
|
111
|
+
this.points.castShadow = this.castShadow;
|
|
112
|
+
this.webgpuMesh.castShadow = this.castShadow;
|
|
113
|
+
const environment = this._materialOptions && 'envMap' in this._materialOptions
|
|
114
|
+
? (_c = (_a = this._materialOptions.envMap) !== null && _a !== void 0 ? _a : (_b = system.scene) === null || _b === void 0 ? void 0 : _b.environment) !== null && _c !== void 0 ? _c : null
|
|
115
|
+
: (_e = (_d = system.scene) === null || _d === void 0 ? void 0 : _d.environment) !== null && _e !== void 0 ? _e : null;
|
|
116
|
+
if (this.isWebGPURenderer(system.sceneRenderer)) {
|
|
117
|
+
this.updateWebGPUEnvironmentMap(environment);
|
|
118
|
+
this.updateWebGPUSoftParticles(system.sceneRenderer, system.scene, system.sceneCamera);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// Set uniforms for soft particles
|
|
122
|
+
this.setUniformValue('softParticles', Boolean(this.softParticleDistance));
|
|
123
|
+
this.setUniformValue('softParticleDistance', this.softParticleDistance);
|
|
124
|
+
// Get depth texture for soft particles
|
|
125
|
+
if (!(system.sceneRenderer instanceof THREE.WebGLRenderer))
|
|
126
|
+
return;
|
|
127
|
+
if (!(system.scene instanceof THREE.Scene))
|
|
128
|
+
return;
|
|
129
|
+
if (!(system.sceneCamera instanceof THREE.Camera))
|
|
130
|
+
return;
|
|
131
|
+
const depthTexture = this.getSceneDepth(system.sceneRenderer, system.scene, system.sceneCamera);
|
|
132
|
+
const cameraNear = 'near' in system.sceneCamera ? system.sceneCamera.near : undefined;
|
|
133
|
+
const cameraFar = 'far' in system.sceneCamera ? system.sceneCamera.far : undefined;
|
|
134
|
+
const softParticles = this.softParticleDistance > 0
|
|
135
|
+
&& Boolean(depthTexture)
|
|
136
|
+
&& typeof cameraNear === 'number'
|
|
137
|
+
&& typeof cameraFar === 'number';
|
|
138
|
+
if (softParticles && depthTexture) {
|
|
139
|
+
this.setUniformValue('softParticles', true);
|
|
140
|
+
this.setUniformValue('sceneDepthTexture', depthTexture);
|
|
141
|
+
const depthResolution = this.getUniformValue('depthResolution', () => new THREE.Vector2());
|
|
142
|
+
system.sceneRenderer.getDrawingBufferSize(depthResolution);
|
|
143
|
+
this.setUniformValue('depthCameraNear', cameraNear);
|
|
144
|
+
this.setUniformValue('depthCameraFar', cameraFar);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.setUniformValue('softParticles', false);
|
|
148
|
+
}
|
|
149
|
+
// Update environment map
|
|
150
|
+
this.updateEnvironmentMap(system.sceneRenderer, environment);
|
|
151
|
+
}
|
|
152
|
+
updateAttributes(particles) {
|
|
153
|
+
this.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(particles.flatMap((particle) => particle.position.toArray())), 3));
|
|
154
|
+
this.geometry.setAttribute('scale', new THREE.BufferAttribute(new Float32Array(particles.flatMap((particle) => particle.scale.toArray())), 3));
|
|
155
|
+
this.geometry.setAttribute('rotation', new THREE.BufferAttribute(new Float32Array(particles.flatMap((particle) => particle.rotation.toArray())), 3));
|
|
156
|
+
this.geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(particles.flatMap((particle) => particle.color.toArray().concat(particle.alpha))), 4));
|
|
157
|
+
this.geometry.setAttribute('frame', new THREE.BufferAttribute(new Float32Array(particles.flatMap((particle) => this.getParticleFrame(particle))), 1));
|
|
158
|
+
}
|
|
159
|
+
destroy() {
|
|
160
|
+
var _a;
|
|
161
|
+
(_a = this.environmentRenderTarget) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
162
|
+
this.environmentRenderTarget = undefined;
|
|
163
|
+
this.geometry.dispose();
|
|
164
|
+
this.material.dispose();
|
|
165
|
+
this.webgpuGeometry.dispose();
|
|
166
|
+
this.webgpuMaterial.dispose();
|
|
167
|
+
this.hiddenMaterial.dispose();
|
|
168
|
+
this.points.removeFromParent();
|
|
169
|
+
this.webgpuMesh.removeFromParent();
|
|
170
|
+
}
|
|
171
|
+
loadMaterial(options) {
|
|
172
|
+
const createMaterial = this.materialType === SpriteMaterialType.Basic ? BasicSprite : UnlitSprite;
|
|
173
|
+
return createMaterial(this.texture, Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), { frames: this.frames, gridSize: this.gridSize, alphaMap: this.alphaMap, softParticleDistance: this.softParticleDistance }));
|
|
174
|
+
}
|
|
175
|
+
loadWebGPUMaterial(options) {
|
|
176
|
+
const createMaterial = this.materialType === SpriteMaterialType.Basic ? WebGPUBasicSprite : WebGPUUnlitSprite;
|
|
177
|
+
return createMaterial(this.texture, Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), { frames: this.frames, gridSize: this.gridSize, alphaMap: this.alphaMap, softParticleDistance: this.softParticleDistance, sceneDepthTexture: WEBGPU_SCENE_DEPTH_TEXTURE }));
|
|
178
|
+
}
|
|
179
|
+
isWebGPURenderer(renderer) {
|
|
180
|
+
return Boolean(renderer === null || renderer === void 0 ? void 0 : renderer.isWebGPURenderer);
|
|
181
|
+
}
|
|
182
|
+
setActiveRenderer(renderer) {
|
|
183
|
+
const usingWebGPU = this.isWebGPURenderer(renderer);
|
|
184
|
+
const usingWebGL = renderer && !usingWebGPU;
|
|
185
|
+
this.points.visible = Boolean(usingWebGL);
|
|
186
|
+
this.points.material = usingWebGL ? this.material : this.hiddenMaterial;
|
|
187
|
+
this.webgpuMesh.visible = usingWebGPU;
|
|
188
|
+
}
|
|
189
|
+
updateWebGPUInstances(particles, camera, renderer) {
|
|
190
|
+
const count = Math.min(particles.length, this.webgpuCapacity);
|
|
191
|
+
this.webgpuMesh.count = count;
|
|
192
|
+
if (camera) {
|
|
193
|
+
camera.getWorldQuaternion(this.cameraQuaternion);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
this.cameraQuaternion.identity();
|
|
197
|
+
}
|
|
198
|
+
for (let index = 0; index < count; index += 1) {
|
|
199
|
+
const particle = particles[index];
|
|
200
|
+
this.rollQuaternion.setFromAxisAngle(this.rollAxis, particle.rotation.x);
|
|
201
|
+
this.quaternion.copy(this.cameraQuaternion).multiply(this.rollQuaternion);
|
|
202
|
+
this.scaleVector.copy(this.getWebGPUWorldScale(particle, camera, renderer));
|
|
203
|
+
this.matrix.compose(particle.position, this.quaternion, this.scaleVector);
|
|
204
|
+
this.webgpuMesh.setMatrixAt(index, this.matrix);
|
|
205
|
+
this.webgpuMesh.setColorAt(index, this.color.copy(particle.color));
|
|
206
|
+
this.webgpuFrameAttribute.setX(index, this.getParticleFrame(particle));
|
|
207
|
+
this.webgpuAlphaAttribute.setX(index, particle.alpha);
|
|
208
|
+
}
|
|
209
|
+
this.webgpuMesh.instanceMatrix.needsUpdate = true;
|
|
210
|
+
if (this.webgpuMesh.instanceColor)
|
|
211
|
+
this.webgpuMesh.instanceColor.needsUpdate = true;
|
|
212
|
+
this.webgpuFrameAttribute.needsUpdate = true;
|
|
213
|
+
this.webgpuAlphaAttribute.needsUpdate = true;
|
|
214
|
+
}
|
|
215
|
+
getWebGPUWorldScale(particle, camera, renderer) {
|
|
216
|
+
var _a, _b, _c;
|
|
217
|
+
const width = particle.scale.x;
|
|
218
|
+
const height = particle.scale.y;
|
|
219
|
+
if (!(camera instanceof THREE.PerspectiveCamera)) {
|
|
220
|
+
this.scaleVector.set(width, height, 1);
|
|
221
|
+
return this.scaleVector;
|
|
222
|
+
}
|
|
223
|
+
const drawingBufferHeight = (_c = (_a = renderer === null || renderer === void 0 ? void 0 : renderer.getDrawingBufferSize(new THREE.Vector2()).y) !== null && _a !== void 0 ? _a : (_b = renderer === null || renderer === void 0 ? void 0 : renderer.domElement) === null || _b === void 0 ? void 0 : _b.height) !== null && _c !== void 0 ? _c : 600;
|
|
224
|
+
const worldUnitsPerPointSizeUnit = 2
|
|
225
|
+
* Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2)
|
|
226
|
+
* 300
|
|
227
|
+
/ drawingBufferHeight;
|
|
228
|
+
this.scaleVector.set(width * worldUnitsPerPointSizeUnit, height * worldUnitsPerPointSizeUnit, 1);
|
|
229
|
+
return this.scaleVector;
|
|
230
|
+
}
|
|
231
|
+
getParticleFrame(particle) {
|
|
232
|
+
return (this.randomStartFrame
|
|
233
|
+
? Math.floor(seedrandom(particle.id).quick() * this.frames)
|
|
234
|
+
: 0) + (Math.floor((particle.realtime / 1000) * evaluateDynamicNumber(this.fps, particle.time, particle.id)) % this.frames);
|
|
235
|
+
}
|
|
236
|
+
updateWebGPUEnvironmentMap(environment) {
|
|
237
|
+
if (this.materialType !== SpriteMaterialType.Basic)
|
|
238
|
+
return;
|
|
239
|
+
const material = this.webgpuMaterial;
|
|
240
|
+
const nextEnvironment = environment !== null && environment !== void 0 ? environment : null;
|
|
241
|
+
if (material.envMap === nextEnvironment)
|
|
242
|
+
return;
|
|
243
|
+
material.envMap = nextEnvironment;
|
|
244
|
+
material.needsUpdate = true;
|
|
245
|
+
}
|
|
246
|
+
updateWebGPUSoftParticles(renderer, scene, camera) {
|
|
247
|
+
if (!this.softParticleDistance)
|
|
248
|
+
return;
|
|
249
|
+
if (!renderer || !scene || !camera)
|
|
250
|
+
return;
|
|
251
|
+
this.getWebGPUSceneDepth(renderer, scene, camera);
|
|
252
|
+
}
|
|
253
|
+
updateEnvironmentMap(renderer, environment) {
|
|
254
|
+
var _a;
|
|
255
|
+
if (this.materialType !== SpriteMaterialType.Basic)
|
|
256
|
+
return;
|
|
257
|
+
if (environment === this.environmentSource
|
|
258
|
+
&& renderer === this.environmentRenderer) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
(_a = this.environmentRenderTarget) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
262
|
+
this.environmentRenderTarget = undefined;
|
|
263
|
+
this.environmentSource = environment !== null && environment !== void 0 ? environment : undefined;
|
|
264
|
+
this.environmentRenderer = renderer;
|
|
265
|
+
if (!environment) {
|
|
266
|
+
this.setEnvironmentMap(null);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
// Already a PMREM CubeUV texture.
|
|
270
|
+
if (environment.mapping === THREE.CubeUVReflectionMapping) {
|
|
271
|
+
this.setEnvironmentMap(environment);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const pmremGenerator = new THREE.PMREMGenerator(renderer);
|
|
275
|
+
let renderTarget;
|
|
276
|
+
if (environment.isCubeTexture) {
|
|
277
|
+
renderTarget =
|
|
278
|
+
pmremGenerator.fromCubemap(environment);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
renderTarget =
|
|
282
|
+
pmremGenerator.fromEquirectangular(environment);
|
|
283
|
+
}
|
|
284
|
+
pmremGenerator.dispose();
|
|
285
|
+
this.environmentRenderTarget = renderTarget;
|
|
286
|
+
this.setEnvironmentMap(renderTarget.texture);
|
|
287
|
+
}
|
|
288
|
+
setEnvironmentMap(environment) {
|
|
289
|
+
var _a, _b, _c, _d, _e;
|
|
290
|
+
var _f;
|
|
291
|
+
if (this.materialType !== SpriteMaterialType.Basic)
|
|
292
|
+
return;
|
|
293
|
+
this.material.uniforms.envMap.value = environment;
|
|
294
|
+
this.material.uniforms.hasEnvMap.value = environment !== null;
|
|
295
|
+
if (!environment) {
|
|
296
|
+
(_a = this.material.defines) === null || _a === void 0 ? true : delete _a.ENVMAP_TYPE_CUBE_UV;
|
|
297
|
+
(_b = this.material.defines) === null || _b === void 0 ? true : delete _b.CUBEUV_TEXEL_WIDTH;
|
|
298
|
+
(_c = this.material.defines) === null || _c === void 0 ? true : delete _c.CUBEUV_TEXEL_HEIGHT;
|
|
299
|
+
(_d = this.material.defines) === null || _d === void 0 ? true : delete _d.CUBEUV_MAX_MIP;
|
|
300
|
+
this.material.needsUpdate = true;
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const image = environment.source.data;
|
|
304
|
+
const imageHeight = image.height;
|
|
305
|
+
const maxMip = Math.log2(imageHeight) - 2;
|
|
306
|
+
const texelHeight = 1 / imageHeight;
|
|
307
|
+
const texelWidth = 1 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16));
|
|
308
|
+
(_e = (_f = this.material).defines) !== null && _e !== void 0 ? _e : (_f.defines = {});
|
|
309
|
+
this.material.defines.ENVMAP_TYPE_CUBE_UV = '';
|
|
310
|
+
this.material.defines.CUBEUV_TEXEL_WIDTH = `${texelWidth}`;
|
|
311
|
+
this.material.defines.CUBEUV_TEXEL_HEIGHT = `${texelHeight}`;
|
|
312
|
+
this.material.defines.CUBEUV_MAX_MIP = `${maxMip}.0`;
|
|
313
|
+
this.material.needsUpdate = true;
|
|
314
|
+
}
|
|
315
|
+
setUniformValue(name, value) {
|
|
316
|
+
var _a;
|
|
317
|
+
var _b;
|
|
318
|
+
(_a = (_b = this.material.uniforms)[name]) !== null && _a !== void 0 ? _a : (_b[name] = { value });
|
|
319
|
+
this.material.uniforms[name].value = value;
|
|
320
|
+
}
|
|
321
|
+
getUniformValue(name, create) {
|
|
322
|
+
var _a;
|
|
323
|
+
var _b;
|
|
324
|
+
(_a = (_b = this.material.uniforms)[name]) !== null && _a !== void 0 ? _a : (_b[name] = { value: create() });
|
|
325
|
+
return this.material.uniforms[name].value;
|
|
326
|
+
}
|
|
327
|
+
getSceneDepth(renderer, scene, camera) {
|
|
328
|
+
var _a, _b, _c;
|
|
329
|
+
let data = scene.userData[SCENE_DEPTH_DATA_USER_DATA_KEY];
|
|
330
|
+
if (!data) {
|
|
331
|
+
const size = renderer.getDrawingBufferSize(new THREE.Vector2());
|
|
332
|
+
const depthTexture = new THREE.DepthTexture(size.x, size.y, THREE.UnsignedIntType);
|
|
333
|
+
const target = new THREE.WebGLRenderTarget(size.x, size.y, {
|
|
334
|
+
depthBuffer: true,
|
|
335
|
+
depthTexture,
|
|
336
|
+
});
|
|
337
|
+
const material = new THREE.MeshDepthMaterial({
|
|
338
|
+
depthPacking: THREE.BasicDepthPacking,
|
|
339
|
+
});
|
|
340
|
+
material.colorWrite = false;
|
|
341
|
+
data = {
|
|
342
|
+
target,
|
|
343
|
+
material,
|
|
344
|
+
frame: -1,
|
|
345
|
+
rendering: false,
|
|
346
|
+
};
|
|
347
|
+
scene.userData[SCENE_DEPTH_DATA_USER_DATA_KEY] = data;
|
|
348
|
+
}
|
|
349
|
+
if (data.rendering) {
|
|
350
|
+
return (_a = data.target.depthTexture) !== null && _a !== void 0 ? _a : undefined;
|
|
351
|
+
}
|
|
352
|
+
const frame = renderer.info.render.frame;
|
|
353
|
+
if (data.frame === frame) {
|
|
354
|
+
return (_b = data.target.depthTexture) !== null && _b !== void 0 ? _b : undefined;
|
|
355
|
+
}
|
|
356
|
+
data.frame = frame;
|
|
357
|
+
data.rendering = true;
|
|
358
|
+
const size = renderer.getDrawingBufferSize(new THREE.Vector2());
|
|
359
|
+
if (data.target.width !== size.x
|
|
360
|
+
|| data.target.height !== size.y) {
|
|
361
|
+
data.target.setSize(size.x, size.y);
|
|
362
|
+
}
|
|
363
|
+
const previousTarget = renderer.getRenderTarget();
|
|
364
|
+
const previousOverrideMaterial = scene.overrideMaterial;
|
|
365
|
+
const hiddenSpriteRenderers = this.hideSpriteRenderers(scene);
|
|
366
|
+
try {
|
|
367
|
+
scene.overrideMaterial = data.material;
|
|
368
|
+
renderer.setRenderTarget(data.target);
|
|
369
|
+
renderer.clear();
|
|
370
|
+
renderer.render(scene, camera);
|
|
371
|
+
data.frame = renderer.info.render.frame;
|
|
372
|
+
}
|
|
373
|
+
finally {
|
|
374
|
+
renderer.setRenderTarget(previousTarget);
|
|
375
|
+
scene.overrideMaterial = previousOverrideMaterial;
|
|
376
|
+
this.restoreSpriteRenderers(hiddenSpriteRenderers);
|
|
377
|
+
data.rendering = false;
|
|
378
|
+
}
|
|
379
|
+
return (_c = data.target.depthTexture) !== null && _c !== void 0 ? _c : undefined;
|
|
380
|
+
}
|
|
381
|
+
getWebGPUSceneDepth(renderer, scene, camera) {
|
|
382
|
+
var _a, _b;
|
|
383
|
+
let data = scene.userData[WEBGPU_SCENE_DEPTH_DATA_USER_DATA_KEY];
|
|
384
|
+
if (!data) {
|
|
385
|
+
const size = renderer.getDrawingBufferSize(new THREE.Vector2());
|
|
386
|
+
const target = new THREE.RenderTarget(size.x, size.y, {
|
|
387
|
+
depthBuffer: true,
|
|
388
|
+
depthTexture: WEBGPU_SCENE_DEPTH_TEXTURE,
|
|
389
|
+
samples: 0,
|
|
390
|
+
});
|
|
391
|
+
const material = new THREE.MeshBasicMaterial({
|
|
392
|
+
colorWrite: false,
|
|
393
|
+
depthTest: true,
|
|
394
|
+
depthWrite: true,
|
|
395
|
+
});
|
|
396
|
+
data = {
|
|
397
|
+
target,
|
|
398
|
+
material,
|
|
399
|
+
rendering: false,
|
|
400
|
+
};
|
|
401
|
+
scene.userData[WEBGPU_SCENE_DEPTH_DATA_USER_DATA_KEY] = data;
|
|
402
|
+
}
|
|
403
|
+
if (data.rendering) {
|
|
404
|
+
return (_a = data.target.depthTexture) !== null && _a !== void 0 ? _a : undefined;
|
|
405
|
+
}
|
|
406
|
+
data.rendering = true;
|
|
407
|
+
const size = renderer.getDrawingBufferSize(new THREE.Vector2());
|
|
408
|
+
if (data.target.width !== size.x
|
|
409
|
+
|| data.target.height !== size.y) {
|
|
410
|
+
data.target.setSize(size.x, size.y);
|
|
411
|
+
}
|
|
412
|
+
const previousTarget = renderer.getRenderTarget();
|
|
413
|
+
const previousOverrideMaterial = scene.overrideMaterial;
|
|
414
|
+
const hiddenParticleRenderers = this.hideParticleRenderers(scene);
|
|
415
|
+
try {
|
|
416
|
+
scene.overrideMaterial = data.material;
|
|
417
|
+
renderer.setRenderTarget(data.target);
|
|
418
|
+
renderer.clear();
|
|
419
|
+
renderer.render(scene, camera);
|
|
420
|
+
}
|
|
421
|
+
finally {
|
|
422
|
+
renderer.setRenderTarget(previousTarget);
|
|
423
|
+
scene.overrideMaterial = previousOverrideMaterial;
|
|
424
|
+
this.restoreParticleRenderers(hiddenParticleRenderers);
|
|
425
|
+
data.rendering = false;
|
|
426
|
+
}
|
|
427
|
+
return (_b = data.target.depthTexture) !== null && _b !== void 0 ? _b : undefined;
|
|
428
|
+
}
|
|
429
|
+
hideSpriteRenderers(scene) {
|
|
430
|
+
return this.hideParticleRenderers(scene, false);
|
|
431
|
+
}
|
|
432
|
+
hideParticleRenderers(scene, includeTrails = true) {
|
|
433
|
+
const hidden = [];
|
|
434
|
+
scene.traverse((object) => {
|
|
435
|
+
const isSpriteRenderer = object.userData[SPRITE_RENDERER_USER_DATA_KEY];
|
|
436
|
+
const isTrailRenderer = includeTrails && object.userData[TRAIL_RENDERER_USER_DATA_KEY];
|
|
437
|
+
if (!isSpriteRenderer && !isTrailRenderer)
|
|
438
|
+
return;
|
|
439
|
+
hidden.push({
|
|
440
|
+
object,
|
|
441
|
+
visible: object.visible,
|
|
442
|
+
});
|
|
443
|
+
object.visible = false;
|
|
444
|
+
});
|
|
445
|
+
return hidden;
|
|
446
|
+
}
|
|
447
|
+
restoreSpriteRenderers(hidden) {
|
|
448
|
+
this.restoreParticleRenderers(hidden);
|
|
449
|
+
}
|
|
450
|
+
restoreParticleRenderers(hidden) {
|
|
451
|
+
hidden.forEach(({ object, visible }) => {
|
|
452
|
+
object.visible = visible;
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
export default SpriteRenderer;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import Renderer, { RendererOptions } from '../Renderer';
|
|
3
|
+
import Particle from '../Particle';
|
|
4
|
+
import ParticleSystem from '../ParticleSystem';
|
|
5
|
+
import { DynamicValue } from '../types/DynamicValue';
|
|
6
|
+
import { TrailMode } from '../enums/TrailMode';
|
|
7
|
+
import { TrailTextureMode } from '../enums/TrailTextureMode';
|
|
8
|
+
export declare const TRAIL_RENDERER_USER_DATA_KEY = "__rzmps_trailRenderer";
|
|
9
|
+
export interface TrailRendererOptions extends RendererOptions {
|
|
10
|
+
mode: TrailMode | `${TrailMode}`;
|
|
11
|
+
textureMode: TrailTextureMode | `${TrailTextureMode}`;
|
|
12
|
+
ratio: number;
|
|
13
|
+
lifetime: DynamicValue<number>;
|
|
14
|
+
minimumVertexDistance: number;
|
|
15
|
+
dieWithParticles: boolean;
|
|
16
|
+
ribbonCount: number;
|
|
17
|
+
width: DynamicValue<number>;
|
|
18
|
+
widthOverTrail: DynamicValue<number>;
|
|
19
|
+
sizeAffectsWidth: boolean;
|
|
20
|
+
sizeAffectsLifetime: boolean;
|
|
21
|
+
inheritParticleColor: boolean;
|
|
22
|
+
colorOverLifetime: DynamicValue<THREE.Color>;
|
|
23
|
+
colorOverTrail: DynamicValue<THREE.Color>;
|
|
24
|
+
material: THREE.Material;
|
|
25
|
+
materialOptions: THREE.MeshStandardMaterialParameters;
|
|
26
|
+
castShadow: boolean;
|
|
27
|
+
receiveShadow: boolean;
|
|
28
|
+
}
|
|
29
|
+
declare class TrailRenderer extends Renderer {
|
|
30
|
+
mode: TrailMode;
|
|
31
|
+
ratio: number;
|
|
32
|
+
lifetime: DynamicValue<number>;
|
|
33
|
+
minimumVertexDistance: number;
|
|
34
|
+
dieWithParticles: boolean;
|
|
35
|
+
ribbonCount: number;
|
|
36
|
+
textureMode: TrailTextureMode;
|
|
37
|
+
width: DynamicValue<number>;
|
|
38
|
+
sizeAffectsWidth: boolean;
|
|
39
|
+
sizeAffectsLifetime: boolean;
|
|
40
|
+
inheritParticleColor: boolean;
|
|
41
|
+
colorOverLifetime: DynamicValue<THREE.Color>;
|
|
42
|
+
widthOverTrail: DynamicValue<number>;
|
|
43
|
+
colorOverTrail: DynamicValue<THREE.Color>;
|
|
44
|
+
geometry: THREE.BufferGeometry;
|
|
45
|
+
material: THREE.Material | THREE.Material[];
|
|
46
|
+
mesh: THREE.Mesh;
|
|
47
|
+
castShadow: boolean;
|
|
48
|
+
receiveShadow: boolean;
|
|
49
|
+
private particles;
|
|
50
|
+
private trails;
|
|
51
|
+
private elapsedTime;
|
|
52
|
+
constructor(options?: Partial<TrailRendererOptions>);
|
|
53
|
+
setup(system: ParticleSystem): void;
|
|
54
|
+
_update(particles: Particle[], system: ParticleSystem, deltaTime: number): void;
|
|
55
|
+
destroy(): void;
|
|
56
|
+
private updateParticleTrails;
|
|
57
|
+
private addTrailPoint;
|
|
58
|
+
private getPaths;
|
|
59
|
+
private getParticlePaths;
|
|
60
|
+
private getRibbonPaths;
|
|
61
|
+
private rebuildGeometry;
|
|
62
|
+
private setEmptyGeometry;
|
|
63
|
+
private appendPathGeometry;
|
|
64
|
+
private getTangent;
|
|
65
|
+
private getPerpendicular;
|
|
66
|
+
private getTextureU;
|
|
67
|
+
private getParticleSize;
|
|
68
|
+
private particleHasTrail;
|
|
69
|
+
private preprocessMaterial;
|
|
70
|
+
}
|
|
71
|
+
export default TrailRenderer;
|