@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.
@@ -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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"}
@@ -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 };