@godot-scene-web/effects 0.1.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/LICENSE +21 -0
- package/dist/easing/index.d.ts +2 -0
- package/dist/easing/index.js +2 -0
- package/dist/easing-BH-VRsXl.js +237 -0
- package/dist/easing-BH-VRsXl.js.map +1 -0
- package/dist/index-CeKMJryT.d.ts +31 -0
- package/dist/index-CeKMJryT.d.ts.map +1 -0
- package/dist/index-pM1LimTu.d.ts +372 -0
- package/dist/index-pM1LimTu.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/particles/index.d.ts +2 -0
- package/dist/particles/index.js +2 -0
- package/dist/particles-CQC9BFSI.js +757 -0
- package/dist/particles-CQC9BFSI.js.map +1 -0
- package/dist/shaders/index.d.ts +255 -0
- package/dist/shaders/index.d.ts.map +1 -0
- package/dist/shaders/index.js +1664 -0
- package/dist/shaders/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
//#region src/particles/godot-renderer.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Which Godot rendering backend a browser render should imitate.
|
|
4
|
+
*
|
|
5
|
+
* Named after the CAUSE rather than after the correction: the two RendererRD backends
|
|
6
|
+
* behave one way and Compatibility the other, and the option says which engine produced
|
|
7
|
+
* the pixels the browser is being asked to match.
|
|
8
|
+
*
|
|
9
|
+
* Defaults to `"forward_plus"` — Godot's own default `rendering/renderer/rendering_method`
|
|
10
|
+
* for a new project, and what a capture is overwhelmingly likely to have come from.
|
|
11
|
+
*/
|
|
12
|
+
type GodotRendererBackend = "forward_plus" | "mobile" | "gl_compatibility";
|
|
13
|
+
/** The default backend: Godot's own default for a new project. */
|
|
14
|
+
declare const DEFAULT_GODOT_RENDERER: GodotRendererBackend;
|
|
15
|
+
/** Coerce an untrusted value (a hand-authored spec blob, a consumer option) to a backend. */
|
|
16
|
+
declare function normalizeGodotRenderer(value: unknown): GodotRendererBackend;
|
|
17
|
+
/**
|
|
18
|
+
* True when the backend runs `ParticleProcessMaterial.color` through
|
|
19
|
+
* `Color::srgb_to_linear()` at UBO-upload time. Both RendererRD backends do;
|
|
20
|
+
* Compatibility/GLES3 does not.
|
|
21
|
+
*/
|
|
22
|
+
declare function linearizesParticleColor(renderer: GodotRendererBackend): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Godot's `Color::srgb_to_linear()`, one channel — `core/math/color.h:191-197`:
|
|
25
|
+
*
|
|
26
|
+
* ```cpp
|
|
27
|
+
* r < 0.04045f ? r * (1.0f / 12.92f)
|
|
28
|
+
* : Math::pow(float((r + 0.055) * (1.0 / (1.0 + 0.055))), 2.4f)
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* The piecewise IEC 61966-2-1 curve with exponent **2.4**, not a `pow(x, 2.2)`
|
|
32
|
+
* approximation, and the threshold comparison is strict `<`. Written here the way Godot
|
|
33
|
+
* writes it — reciprocal multiplies rather than divides — so the two read the same;
|
|
34
|
+
* Godot evaluates the inner expression in double and then narrows to float before
|
|
35
|
+
* `pow`, while JS stays in double throughout, a difference orders of magnitude below
|
|
36
|
+
* the 1/255 the comparison is made at.
|
|
37
|
+
*
|
|
38
|
+
* Note the fixed point at both ends: `srgbToLinear(0) === 0` and `srgbToLinear(1) === 1`.
|
|
39
|
+
* A fully saturated channel is where this curve is the identity, which is why it is the
|
|
40
|
+
* per-channel regression check on the parity fixture (see `docs/parity.md`).
|
|
41
|
+
*/
|
|
42
|
+
declare function srgbToLinear(value: number): number;
|
|
43
|
+
/**
|
|
44
|
+
* A particle system's base colour as the given backend uploads it: RGB through
|
|
45
|
+
* {@link srgbToLinear} on the RendererRD backends, returned unchanged on
|
|
46
|
+
* Compatibility/GLES3.
|
|
47
|
+
*
|
|
48
|
+
* `fromProcessMaterial` is the scope gate. Only `ParticleProcessMaterial.color` — a
|
|
49
|
+
* `GPUParticles2D` with a process material — rides the UBO path that linearizes. When the
|
|
50
|
+
* base colour instead came from `CPUParticles2D.color` or the node's `modulate`, it reaches
|
|
51
|
+
* the canvas by a route Godot leaves in sRGB whatever the backend, and this returns it
|
|
52
|
+
* untouched.
|
|
53
|
+
*
|
|
54
|
+
* **ALPHA IS NEVER TOUCHED.** `Color::srgb_to_linear()` passes `a` straight through
|
|
55
|
+
* (`color.h:196`), so the coverage the blend algebra runs on is the authored value on
|
|
56
|
+
* every backend and every path.
|
|
57
|
+
*
|
|
58
|
+
* Always returns a fresh tuple, so callers never alias the raw colour they passed in.
|
|
59
|
+
*/
|
|
60
|
+
declare function linearizeParticleBaseColor(color: readonly [number, number, number, number], renderer: GodotRendererBackend, fromProcessMaterial: boolean): [number, number, number, number];
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/particles/sampling.d.ts
|
|
63
|
+
/** Renderer-neutral ramp and curve values used by particle state and texture bakers. */
|
|
64
|
+
interface ParticleGradientStop {
|
|
65
|
+
offset: number;
|
|
66
|
+
color: [number, number, number, number];
|
|
67
|
+
}
|
|
68
|
+
interface ParticleCurvePoint {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
}
|
|
72
|
+
/** Godot-style endpoint-clamped gradient sampling. */
|
|
73
|
+
declare function sampleParticleGradient(stops: readonly ParticleGradientStop[], t: number, interpolationMode?: number): [number, number, number, number];
|
|
74
|
+
/** Allocation-free gradient sampling for simulation hot paths. */
|
|
75
|
+
declare function sampleParticleGradientInto(stops: readonly ParticleGradientStop[], t: number, out: [number, number, number, number], interpolationMode?: number): void;
|
|
76
|
+
/** Godot-style endpoint-clamped linear curve sampling. */
|
|
77
|
+
declare function sampleParticleCurve(points: readonly ParticleCurvePoint[], t: number): number;
|
|
78
|
+
declare function normalizeParticleCurve(points: readonly ParticleCurvePoint[] | undefined): ParticleCurvePoint[] | undefined;
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/particles/config.d.ts
|
|
81
|
+
/** Renderer-neutral particle simulation contract. */
|
|
82
|
+
interface ParticleConfig {
|
|
83
|
+
kind: "CPUParticles2D" | "GPUParticles2D";
|
|
84
|
+
/**
|
|
85
|
+
* Which Godot backend the browser render is imitating (`GodotHtmlRenderOptions.godotRenderer`,
|
|
86
|
+
* default `"forward_plus"`). Its ONLY effect is `baseColorRender` below — see
|
|
87
|
+
* `./godot-renderer.ts`.
|
|
88
|
+
*/
|
|
89
|
+
godotRenderer: GodotRendererBackend;
|
|
90
|
+
amount: number;
|
|
91
|
+
amountRatio: number;
|
|
92
|
+
lifetime: number;
|
|
93
|
+
lifetimeRandomness: number;
|
|
94
|
+
oneShot: boolean;
|
|
95
|
+
emitting: boolean;
|
|
96
|
+
explosiveness: number;
|
|
97
|
+
randomness: number;
|
|
98
|
+
preprocess: number;
|
|
99
|
+
speedScale: number;
|
|
100
|
+
/** 0 => use 1/30 fixed step. */
|
|
101
|
+
fixedFps: number;
|
|
102
|
+
localCoords: boolean;
|
|
103
|
+
/** 0 = index, 1 = lifetime, 2 = reverse-lifetime (affects draw order only). */
|
|
104
|
+
drawOrder: number;
|
|
105
|
+
seed: number;
|
|
106
|
+
/** 0 point, 1 sphere(disk), 2 sphere-surface(ring), 3 box, 4 points, 6 ring. */
|
|
107
|
+
emissionShape: number;
|
|
108
|
+
emissionOffset: [number, number];
|
|
109
|
+
emissionScale: [number, number];
|
|
110
|
+
emissionSphereRadius: number;
|
|
111
|
+
emissionRingRadius: number;
|
|
112
|
+
emissionRingInnerRadius: number;
|
|
113
|
+
emissionRingHeight: number;
|
|
114
|
+
emissionBoxExtents: [number, number];
|
|
115
|
+
direction: [number, number];
|
|
116
|
+
/** Half-angle, degrees. */
|
|
117
|
+
spread: number;
|
|
118
|
+
initialVelocityMin: number;
|
|
119
|
+
initialVelocityMax: number;
|
|
120
|
+
/** Degrees. */
|
|
121
|
+
angleMin: number;
|
|
122
|
+
angleMax: number;
|
|
123
|
+
/** Degrees / second. */
|
|
124
|
+
angularVelocityMin: number;
|
|
125
|
+
angularVelocityMax: number;
|
|
126
|
+
gravity: [number, number];
|
|
127
|
+
linearAccelMin: number;
|
|
128
|
+
linearAccelMax: number;
|
|
129
|
+
radialAccelMin: number;
|
|
130
|
+
radialAccelMax: number;
|
|
131
|
+
tangentialAccelMin: number;
|
|
132
|
+
tangentialAccelMax: number;
|
|
133
|
+
dampingMin: number;
|
|
134
|
+
dampingMax: number;
|
|
135
|
+
dampingAsFriction: boolean;
|
|
136
|
+
/** Revolutions / second. */
|
|
137
|
+
orbitVelocityMin: number;
|
|
138
|
+
orbitVelocityMax: number;
|
|
139
|
+
scaleMin: number;
|
|
140
|
+
scaleMax: number;
|
|
141
|
+
hueVariationMin: number;
|
|
142
|
+
hueVariationMax: number;
|
|
143
|
+
alignY: boolean;
|
|
144
|
+
/** The system's base colour exactly as Godot serialized it — raw sRGB, never converted. */
|
|
145
|
+
baseColor: [number, number, number, number];
|
|
146
|
+
/**
|
|
147
|
+
* Whether `baseColor` came from `ParticleProcessMaterial.color` rather than from
|
|
148
|
+
* `CPUParticles2D.color` or the node's `modulate`. Gates the `godotRenderer` correction:
|
|
149
|
+
* only the process material rides the UBO path Godot linearizes. Defaults (when a
|
|
150
|
+
* hand-authored blob omits it) to `kind === "GPUParticles2D"`.
|
|
151
|
+
*/
|
|
152
|
+
baseColorFromProcessMaterial: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* `baseColor` as `godotRenderer` uploads it to the GPU: RGB through
|
|
155
|
+
* `Color::srgb_to_linear()` on `forward_plus`/`mobile` when
|
|
156
|
+
* `baseColorFromProcessMaterial`, IDENTICAL to `baseColor` otherwise. Alpha is never
|
|
157
|
+
* converted on any backend. This is the field the simulation multiplies (`simulate.ts`);
|
|
158
|
+
* `baseColor` is kept beside it as the authored value.
|
|
159
|
+
*
|
|
160
|
+
* DERIVED: `normalizeParticleConfig` always RECOMPUTES it from `baseColor`,
|
|
161
|
+
* `godotRenderer` and `baseColorFromProcessMaterial`, so the serialized value cannot go
|
|
162
|
+
* stale or lie. Deriving it rather
|
|
163
|
+
* than overwriting `baseColor` in place is what keeps normalization IDEMPOTENT —
|
|
164
|
+
* `normalizeParticleConfig(normalizeParticleConfig(x))` would otherwise apply the curve
|
|
165
|
+
* twice, and several call sites do re-normalize an already-normalized config.
|
|
166
|
+
*/
|
|
167
|
+
baseColorRender: [number, number, number, number];
|
|
168
|
+
hframes: number;
|
|
169
|
+
vframes: number;
|
|
170
|
+
frameCount?: number;
|
|
171
|
+
animLoop: boolean;
|
|
172
|
+
animSpeedMin: number;
|
|
173
|
+
animSpeedMax: number;
|
|
174
|
+
animOffsetMin: number;
|
|
175
|
+
animOffsetMax: number;
|
|
176
|
+
colorRamp?: ParticleGradientStop[];
|
|
177
|
+
colorInitialRamp?: ParticleGradientStop[];
|
|
178
|
+
scaleCurve?: ParticleCurvePoint[];
|
|
179
|
+
scaleCurveX?: ParticleCurvePoint[];
|
|
180
|
+
scaleCurveY?: ParticleCurvePoint[];
|
|
181
|
+
alphaCurve?: ParticleCurvePoint[];
|
|
182
|
+
hueCurve?: ParticleCurvePoint[];
|
|
183
|
+
}
|
|
184
|
+
/** Renderer-facing particle fields that remain portable (no URLs or DOM placement). */
|
|
185
|
+
interface ParticleRenderConfig extends ParticleConfig {
|
|
186
|
+
textureWidth: number;
|
|
187
|
+
textureHeight: number;
|
|
188
|
+
flipbookCropOnly?: boolean;
|
|
189
|
+
blendMode: number;
|
|
190
|
+
colorLut?: ParticleGradientStop[];
|
|
191
|
+
colorLutInterpolation?: number;
|
|
192
|
+
alphaFromRed?: boolean;
|
|
193
|
+
alphaErode?: {
|
|
194
|
+
threshold: number;
|
|
195
|
+
softness: number;
|
|
196
|
+
} | null;
|
|
197
|
+
uvPolar?: boolean;
|
|
198
|
+
}
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/particles/instance-buffer.d.ts
|
|
201
|
+
/** Floats per particle render instance: center.xy, scale.xy, rotation, color.rgba, frame. */
|
|
202
|
+
declare const INSTANCE_STRIDE = 10;
|
|
203
|
+
/**
|
|
204
|
+
* CPU-owned packed particle instances. This class deliberately knows nothing about
|
|
205
|
+
* WebGL, WebGPU, a canvas, or a device lifecycle; render adapters own residency.
|
|
206
|
+
*/
|
|
207
|
+
declare class InstanceBuffer {
|
|
208
|
+
data: Float32Array;
|
|
209
|
+
/** Number of instances written since the last reset. */
|
|
210
|
+
count: number;
|
|
211
|
+
private capacity;
|
|
212
|
+
constructor(initialCapacity?: number);
|
|
213
|
+
reset(): void;
|
|
214
|
+
push(x: number, y: number, scaleX: number, scaleY: number, rotation: number, r: number, g: number, b: number, a: number, frame: number): void;
|
|
215
|
+
ensureCapacity(instances: number): void;
|
|
216
|
+
}
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region src/particles/state.d.ts
|
|
219
|
+
interface Particle {
|
|
220
|
+
active: boolean;
|
|
221
|
+
/** Age in seconds. */
|
|
222
|
+
time: number;
|
|
223
|
+
/** This particle's randomized lifetime (seconds). */
|
|
224
|
+
lifetime: number;
|
|
225
|
+
/** Position in node-local pixels. */
|
|
226
|
+
x: number;
|
|
227
|
+
y: number;
|
|
228
|
+
/** Velocity in px/s. */
|
|
229
|
+
vx: number;
|
|
230
|
+
vy: number;
|
|
231
|
+
/** Rotation in radians. */
|
|
232
|
+
rotation: number;
|
|
233
|
+
/** Per-frame force RNG seed (stable per particle). */
|
|
234
|
+
seed: number;
|
|
235
|
+
angleRand: number;
|
|
236
|
+
scaleRand: number;
|
|
237
|
+
hueRand: number;
|
|
238
|
+
animOffsetRand: number;
|
|
239
|
+
/** color_initial_ramp sampled once at spawn (or white). */
|
|
240
|
+
startColor: [number, number, number, number];
|
|
241
|
+
scaleX: number;
|
|
242
|
+
scaleY: number;
|
|
243
|
+
r: number;
|
|
244
|
+
g: number;
|
|
245
|
+
b: number;
|
|
246
|
+
a: number;
|
|
247
|
+
/** Flipbook frame index. */
|
|
248
|
+
frame: number;
|
|
249
|
+
}
|
|
250
|
+
interface ParticleSystemState {
|
|
251
|
+
config: ParticleConfig;
|
|
252
|
+
particles: Particle[];
|
|
253
|
+
/** System time within the current cycle, wrapped to [0, lifetime). */
|
|
254
|
+
time: number;
|
|
255
|
+
/** Number of completed lifetime cycles (drives spawn timing + one-shot end). */
|
|
256
|
+
cycle: number;
|
|
257
|
+
/** Live emit flag — starts at `config.emitting`, cleared after a one-shot cycle. */
|
|
258
|
+
emitting: boolean;
|
|
259
|
+
/** Fixed-step remainder accumulator. */
|
|
260
|
+
remainder: number;
|
|
261
|
+
/** Effective particle count after the maxInstances clamp. */
|
|
262
|
+
count: number;
|
|
263
|
+
}
|
|
264
|
+
declare function createParticleState(config: ParticleConfig, maxInstances?: number): ParticleSystemState;
|
|
265
|
+
/** Whether the system still needs simulating (live particles or still emitting). */
|
|
266
|
+
declare function particlesAreLive(state: ParticleSystemState): boolean;
|
|
267
|
+
declare function normalizeParticleConfig(raw: Partial<ParticleConfig> | null | undefined): ParticleConfig;
|
|
268
|
+
/** Normalize portable renderer inputs without admitting HTML URL or placement fields. */
|
|
269
|
+
declare function normalizeParticleRenderConfig(raw: Partial<ParticleRenderConfig> | null | undefined): ParticleRenderConfig;
|
|
270
|
+
//#endregion
|
|
271
|
+
//#region src/particles/pack-instances.d.ts
|
|
272
|
+
interface ParticleInstanceTransform {
|
|
273
|
+
readonly xx: number;
|
|
274
|
+
readonly xy: number;
|
|
275
|
+
readonly yx: number;
|
|
276
|
+
readonly yy: number;
|
|
277
|
+
readonly originX: number;
|
|
278
|
+
readonly originY: number;
|
|
279
|
+
readonly scale?: number;
|
|
280
|
+
readonly rotation?: number;
|
|
281
|
+
}
|
|
282
|
+
interface ParticleInstancePackInput {
|
|
283
|
+
readonly state: ParticleSystemState;
|
|
284
|
+
readonly config: Pick<ParticleRenderConfig, "hframes" | "vframes" | "flipbookCropOnly">;
|
|
285
|
+
readonly instances: InstanceBuffer;
|
|
286
|
+
readonly textureWidth: number;
|
|
287
|
+
readonly textureHeight: number;
|
|
288
|
+
readonly origin?: readonly [number, number];
|
|
289
|
+
readonly transform?: ParticleInstanceTransform;
|
|
290
|
+
readonly modulate?: readonly [number, number, number, number];
|
|
291
|
+
}
|
|
292
|
+
/** The sprite-sheet grid used for a texture; untextured particles always have one frame. */
|
|
293
|
+
declare function frameGridFor(textured: boolean, hframes: number, vframes: number): [number, number];
|
|
294
|
+
/** Pack live particle state into a caller-owned, reusable GPU instance buffer. */
|
|
295
|
+
declare function packParticleInstances(input: ParticleInstancePackInput): number;
|
|
296
|
+
//#endregion
|
|
297
|
+
//#region src/particles/simulate.d.ts
|
|
298
|
+
/**
|
|
299
|
+
* Advance the system by `dt` seconds (real time), stepping the simulation in fixed
|
|
300
|
+
* `1/fixed_fps` (or 1/30) chunks so the look is frame-rate independent. Mutates
|
|
301
|
+
* `state` in place. `maxSteps` bounds the loop (warm-up / tab-switch spikes).
|
|
302
|
+
*
|
|
303
|
+
* Returns the number of fixed sub-steps it actually executed — the unit of work this function
|
|
304
|
+
* does, and the only honest denominator for its cost: one display frame can run zero steps (a
|
|
305
|
+
* fast display under a 30Hz `fixed_fps`, or `speed_scale: 0`) or many (a long dt, a warm-up), so
|
|
306
|
+
* a profiler that divided wall-clock by FRAMES would be measuring the display, not the sim (see
|
|
307
|
+
* `ParticleProfile.simSteps` in `./runtime`). Purely additive: every caller may ignore it, and
|
|
308
|
+
* this function stays pure of any clock.
|
|
309
|
+
*/
|
|
310
|
+
declare function simulateParticles(state: ParticleSystemState, dt: number, maxSteps?: number): number;
|
|
311
|
+
/**
|
|
312
|
+
* Warm-start a freshly created system by its `preprocess` time (Godot pre-simulates
|
|
313
|
+
* that much before first draw, so a long-lived ambient — fog with preprocess=100 —
|
|
314
|
+
* appears mid-drift instead of empty/bursty). A REPEATING system reaches its steady
|
|
315
|
+
* state within two lifetime cycles (a particle's look depends on its age, not absolute
|
|
316
|
+
* time), so simulating `min(preprocess, 2 x lifetime)` is visually identical to the
|
|
317
|
+
* full preprocess at bounded cost; a one-shot's whole life fits in that window too.
|
|
318
|
+
* Steps are sized to cover the window (the default `maxSteps` caps at ~33s), and the
|
|
319
|
+
* sub-step remainder is dropped so the leftover doesn't fast-forward the first live
|
|
320
|
+
* frames at ~1000 steps per tick.
|
|
321
|
+
*/
|
|
322
|
+
declare function preprocessParticles(state: ParticleSystemState): void;
|
|
323
|
+
/**
|
|
324
|
+
* Warm a system to a representative FROZEN state for the runtime's static/particles mode. Reuses the authored
|
|
325
|
+
* `preprocess` (an ambient emitter with preprocess>0 reaches its steady drift — identical to `preprocessParticles`),
|
|
326
|
+
* and for a system that would otherwise sit at spawn (preprocess<=0, e.g. a one-shot burst or an un-preprocessed
|
|
327
|
+
* emitter) advances a representative slice of a lifetime so the frozen frame is populated. Mutates `state`; the
|
|
328
|
+
* caller draws once and then stops simulating (see the particle runtime's static mode).
|
|
329
|
+
*
|
|
330
|
+
* This warm has no notion of the burst ENDING — it is a single representative frame, so a one-shot warmed here
|
|
331
|
+
* would otherwise be drawn as mid-flight forever. `staticOneShotExpired` is what retires it.
|
|
332
|
+
*/
|
|
333
|
+
declare function warmStaticParticles(state: ParticleSystemState): void;
|
|
334
|
+
/**
|
|
335
|
+
* Godot's own ACTIVE WINDOW for one one-shot cycle, in seconds: `lifetime * (2 - explosiveness)`
|
|
336
|
+
* (particles.cpp `active_time`). At explosiveness 1 every particle is born at t=0, so the cycle is one
|
|
337
|
+
* lifetime; at 0 the births are spread over a full lifetime, so the last particle dies at 2x lifetime.
|
|
338
|
+
*
|
|
339
|
+
* This is the SAME law the game-side mod uses to schedule a frozen one-shot's synthesized end-of-burst
|
|
340
|
+
* (`CouchCoopHeadlessVisualSuspender.FinishNudgeDelaySeconds`), deliberately: the two sides have to agree on
|
|
341
|
+
* when a burst is over, or one of them keeps drawing/reporting it after the other has stopped. No clamp and no
|
|
342
|
+
* margin here — the mod's margin exists so its removal delta lands AFTER the client's tail, and this side IS
|
|
343
|
+
* that tail. `normalizeParticleConfig` already guarantees a finite `lifetime >= 0.01` and `explosiveness` in
|
|
344
|
+
* [0,1], so the result is finite and positive.
|
|
345
|
+
*
|
|
346
|
+
* `speedScale` is deliberately NOT folded in, for the same reason: the mod's law does not either, and a
|
|
347
|
+
* disagreement would be worse than the (rare, small) inaccuracy of a re-timed burst.
|
|
348
|
+
*/
|
|
349
|
+
declare function oneShotBurstSeconds(cfg: ParticleConfig): number;
|
|
350
|
+
/**
|
|
351
|
+
* FROZEN-MODE expiry decision: has a one-shot burst the client has been drawing statically outlived its own
|
|
352
|
+
* active window, so the runtime should stop drawing it? Pure (no clock, no DOM) — the caller supplies the
|
|
353
|
+
* seconds elapsed since IT first saw this system emitting.
|
|
354
|
+
*
|
|
355
|
+
* WHY THIS EXISTS. In frozen/static mode a system is warmed to a representative mid-flight frame and that frame
|
|
356
|
+
* is parked forever — which is right for an ambient emitter (it really does emit forever) and wrong for a
|
|
357
|
+
* one-shot (it is a BURST; it ends). Nothing else can retire it: the frozen runtime never simulates, so the
|
|
358
|
+
* sim's own end-of-cycle never runs, and the only other input is the host's `emitting` flag — which a host can
|
|
359
|
+
* get stuck on (the live case: a game-side freeze left `Emitting` latched true on every energy-counter VFX, so
|
|
360
|
+
* the mirror drew a permanent "energy ring" over a counter the game was showing bare).
|
|
361
|
+
*
|
|
362
|
+
* WHY "since FIRST SIGHT". The client cannot know when the game started the burst — it sees only "this spec
|
|
363
|
+
* says emitting". One full active window from first sight is exactly what the burst itself would do, so a
|
|
364
|
+
* legitimate transient (a hit spark, a card-play flourish) still shows for its natural life; only a burst that
|
|
365
|
+
* outlives its own window — i.e. one nothing ever turned off — is dropped.
|
|
366
|
+
*/
|
|
367
|
+
declare function staticOneShotExpired(cfg: ParticleConfig, secondsSinceFirstEmitting: number): boolean;
|
|
368
|
+
/** Live particle count (for tests / draw). */
|
|
369
|
+
declare function activeParticleCount(state: ParticleSystemState): number;
|
|
370
|
+
//#endregion
|
|
371
|
+
export { linearizesParticleColor as A, normalizeParticleCurve as C, DEFAULT_GODOT_RENDERER as D, sampleParticleGradientInto as E, srgbToLinear as M, GodotRendererBackend as O, ParticleGradientStop as S, sampleParticleGradient as T, INSTANCE_STRIDE as _, staticOneShotExpired as a, ParticleRenderConfig as b, ParticleInstanceTransform as c, Particle as d, ParticleSystemState as f, particlesAreLive as g, normalizeParticleRenderConfig as h, simulateParticles as i, normalizeGodotRenderer as j, linearizeParticleBaseColor as k, frameGridFor as l, normalizeParticleConfig as m, oneShotBurstSeconds as n, warmStaticParticles as o, createParticleState as p, preprocessParticles as r, ParticleInstancePackInput as s, activeParticleCount as t, packParticleInstances as u, InstanceBuffer as v, sampleParticleCurve as w, ParticleCurvePoint as x, ParticleConfig as y };
|
|
372
|
+
//# sourceMappingURL=index-pM1LimTu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-pM1LimTu.d.ts","names":[],"sources":["../src/particles/godot-renderer.ts","../src/particles/sampling.ts","../src/particles/config.ts","../src/particles/instance-buffer.ts","../src/particles/state.ts","../src/particles/pack-instances.ts","../src/particles/simulate.ts"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { n as godotEaseSample, t as createEaseSampler } from "./index-CeKMJryT.js";
|
|
2
|
+
import { A as linearizesParticleColor, C as normalizeParticleCurve, D as DEFAULT_GODOT_RENDERER, E as sampleParticleGradientInto, M as srgbToLinear, O as GodotRendererBackend, S as ParticleGradientStop, T as sampleParticleGradient, _ as INSTANCE_STRIDE, a as staticOneShotExpired, b as ParticleRenderConfig, c as ParticleInstanceTransform, d as Particle, f as ParticleSystemState, g as particlesAreLive, h as normalizeParticleRenderConfig, i as simulateParticles, j as normalizeGodotRenderer, k as linearizeParticleBaseColor, l as frameGridFor, m as normalizeParticleConfig, n as oneShotBurstSeconds, o as warmStaticParticles, p as createParticleState, r as preprocessParticles, s as ParticleInstancePackInput, t as activeParticleCount, u as packParticleInstances, v as InstanceBuffer, w as sampleParticleCurve, x as ParticleCurvePoint, y as ParticleConfig } from "./index-pM1LimTu.js";
|
|
3
|
+
import { GodotBlendMode, ParsedShader, ShaderAnalysis, ShaderSampler, ShaderUniform, ShaderVarying, ShaderVaryingHoist, TranspiledShader, TranspiledWgslShader, UnsupportedShaderError, UnsupportedWgslShaderError, WgslBindings, WgslBuiltinOffsets, WgslStructField, WgslStructLayout, WgslStructMember, WgslUniformField, analyzeShader, expandGodotShaderIncludes, extractFunction, hasToken, matchBrace, parseShader, promoteIntLiterals, rejectUnsupported, replaceToken, sanitizeReservedIdentifiers, shaderLogic, stripComments, transpileGodotShader, transpileGodotShaderWgsl, unwrapShaderResource, wgslStructLayout } from "./shaders/index.js";
|
|
4
|
+
export { DEFAULT_GODOT_RENDERER, GodotBlendMode, type GodotRendererBackend, INSTANCE_STRIDE, InstanceBuffer, ParsedShader, type Particle, type ParticleConfig, type ParticleCurvePoint, type ParticleGradientStop, type ParticleInstancePackInput, type ParticleInstanceTransform, type ParticleRenderConfig, type ParticleSystemState, ShaderAnalysis, ShaderSampler, ShaderUniform, ShaderVarying, ShaderVaryingHoist, TranspiledShader, TranspiledWgslShader, UnsupportedShaderError, UnsupportedWgslShaderError, WgslBindings, WgslBuiltinOffsets, WgslStructField, WgslStructLayout, WgslStructMember, WgslUniformField, activeParticleCount, analyzeShader, createEaseSampler, createParticleState, expandGodotShaderIncludes, extractFunction, frameGridFor, godotEaseSample, hasToken, linearizeParticleBaseColor, linearizesParticleColor, matchBrace, normalizeGodotRenderer, normalizeParticleConfig, normalizeParticleCurve, normalizeParticleRenderConfig, oneShotBurstSeconds, packParticleInstances, parseShader, particlesAreLive, preprocessParticles, promoteIntLiterals, rejectUnsupported, replaceToken, sampleParticleCurve, sampleParticleGradient, sampleParticleGradientInto, sanitizeReservedIdentifiers, shaderLogic, simulateParticles, srgbToLinear, staticOneShotExpired, stripComments, transpileGodotShader, transpileGodotShaderWgsl, unwrapShaderResource, warmStaticParticles, wgslStructLayout };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { n as godotEaseSample, t as createEaseSampler } from "./easing-BH-VRsXl.js";
|
|
2
|
+
import { C as srgbToLinear, S as normalizeGodotRenderer, _ as INSTANCE_STRIDE, a as activeParticleCount, b as linearizeParticleBaseColor, c as simulateParticles, d as normalizeParticleCurve, f as sampleParticleCurve, g as packParticleInstances, h as frameGridFor, i as particlesAreLive, l as staticOneShotExpired, m as sampleParticleGradientInto, n as normalizeParticleConfig, o as oneShotBurstSeconds, p as sampleParticleGradient, r as normalizeParticleRenderConfig, s as preprocessParticles, t as createParticleState, u as warmStaticParticles, v as InstanceBuffer, x as linearizesParticleColor, y as DEFAULT_GODOT_RENDERER } from "./particles-CQC9BFSI.js";
|
|
3
|
+
import { UnsupportedShaderError, UnsupportedWgslShaderError, analyzeShader, expandGodotShaderIncludes, extractFunction, hasToken, matchBrace, parseShader, promoteIntLiterals, rejectUnsupported, replaceToken, sanitizeReservedIdentifiers, shaderLogic, stripComments, transpileGodotShader, transpileGodotShaderWgsl, unwrapShaderResource, wgslStructLayout } from "./shaders/index.js";
|
|
4
|
+
export { DEFAULT_GODOT_RENDERER, INSTANCE_STRIDE, InstanceBuffer, UnsupportedShaderError, UnsupportedWgslShaderError, activeParticleCount, analyzeShader, createEaseSampler, createParticleState, expandGodotShaderIncludes, extractFunction, frameGridFor, godotEaseSample, hasToken, linearizeParticleBaseColor, linearizesParticleColor, matchBrace, normalizeGodotRenderer, normalizeParticleConfig, normalizeParticleCurve, normalizeParticleRenderConfig, oneShotBurstSeconds, packParticleInstances, parseShader, particlesAreLive, preprocessParticles, promoteIntLiterals, rejectUnsupported, replaceToken, sampleParticleCurve, sampleParticleGradient, sampleParticleGradientInto, sanitizeReservedIdentifiers, shaderLogic, simulateParticles, srgbToLinear, staticOneShotExpired, stripComments, transpileGodotShader, transpileGodotShaderWgsl, unwrapShaderResource, warmStaticParticles, wgslStructLayout };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { A as linearizesParticleColor, C as normalizeParticleCurve, D as DEFAULT_GODOT_RENDERER, E as sampleParticleGradientInto, M as srgbToLinear, O as GodotRendererBackend, S as ParticleGradientStop, T as sampleParticleGradient, _ as INSTANCE_STRIDE, a as staticOneShotExpired, b as ParticleRenderConfig, c as ParticleInstanceTransform, d as Particle, f as ParticleSystemState, g as particlesAreLive, h as normalizeParticleRenderConfig, i as simulateParticles, j as normalizeGodotRenderer, k as linearizeParticleBaseColor, l as frameGridFor, m as normalizeParticleConfig, n as oneShotBurstSeconds, o as warmStaticParticles, p as createParticleState, r as preprocessParticles, s as ParticleInstancePackInput, t as activeParticleCount, u as packParticleInstances, v as InstanceBuffer, w as sampleParticleCurve, x as ParticleCurvePoint, y as ParticleConfig } from "../index-pM1LimTu.js";
|
|
2
|
+
export { DEFAULT_GODOT_RENDERER, type GodotRendererBackend, INSTANCE_STRIDE, InstanceBuffer, type Particle, type ParticleConfig, type ParticleCurvePoint, type ParticleGradientStop, type ParticleInstancePackInput, type ParticleInstanceTransform, type ParticleRenderConfig, type ParticleSystemState, activeParticleCount, createParticleState, frameGridFor, linearizeParticleBaseColor, linearizesParticleColor, normalizeGodotRenderer, normalizeParticleConfig, normalizeParticleCurve, normalizeParticleRenderConfig, oneShotBurstSeconds, packParticleInstances, particlesAreLive, preprocessParticles, sampleParticleCurve, sampleParticleGradient, sampleParticleGradientInto, simulateParticles, srgbToLinear, staticOneShotExpired, warmStaticParticles };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { C as srgbToLinear, S as normalizeGodotRenderer, _ as INSTANCE_STRIDE, a as activeParticleCount, b as linearizeParticleBaseColor, c as simulateParticles, d as normalizeParticleCurve, f as sampleParticleCurve, g as packParticleInstances, h as frameGridFor, i as particlesAreLive, l as staticOneShotExpired, m as sampleParticleGradientInto, n as normalizeParticleConfig, o as oneShotBurstSeconds, p as sampleParticleGradient, r as normalizeParticleRenderConfig, s as preprocessParticles, t as createParticleState, u as warmStaticParticles, v as InstanceBuffer, x as linearizesParticleColor, y as DEFAULT_GODOT_RENDERER } from "../particles-CQC9BFSI.js";
|
|
2
|
+
export { DEFAULT_GODOT_RENDERER, INSTANCE_STRIDE, InstanceBuffer, activeParticleCount, createParticleState, frameGridFor, linearizeParticleBaseColor, linearizesParticleColor, normalizeGodotRenderer, normalizeParticleConfig, normalizeParticleCurve, normalizeParticleRenderConfig, oneShotBurstSeconds, packParticleInstances, particlesAreLive, preprocessParticles, sampleParticleCurve, sampleParticleGradient, sampleParticleGradientInto, simulateParticles, srgbToLinear, staticOneShotExpired, warmStaticParticles };
|