@godot-scene-web/canvas-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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tomás Fox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,409 @@
1
+ import { InstanceBuffer, ParticleRenderConfig, ParticleSystemState } from "@godot-scene-web/effects/particles";
2
+ import { GodotBlendMode, ShaderUniform } from "@godot-scene-web/effects/shaders";
3
+
4
+ //#region src/particle-webgl.d.ts
5
+ /** A borrowed GL context and quad. Core never creates or owns either resource. */
6
+ interface ParticleGl {
7
+ gl: WebGL2RenderingContext;
8
+ quad: WebGLBuffer;
9
+ }
10
+ /** Release one portable buffer's WebGL allocation on its owning borrowed context. */
11
+ declare function disposeParticleInstanceBuffer(gl: WebGL2RenderingContext, instances: InstanceBuffer): void;
12
+ /** Context-loss path: forget driver names without issuing GL commands. */
13
+ declare function invalidateParticleInstanceBuffer(gl: WebGL2RenderingContext, instances: InstanceBuffer): void;
14
+ interface AccumTarget {
15
+ fbo: WebGLFramebuffer;
16
+ texture: WebGLTexture;
17
+ width: number;
18
+ height: number;
19
+ }
20
+ interface ParticleProgram {
21
+ program: WebGLProgram;
22
+ cornerBuffer: WebGLBuffer;
23
+ uViewport: WebGLUniformLocation | null;
24
+ uHframes: WebGLUniformLocation | null;
25
+ uVframes: WebGLUniformLocation | null;
26
+ uTexture: WebGLUniformLocation | null;
27
+ uLutTex: WebGLUniformLocation | null;
28
+ uMaskTex: WebGLUniformLocation | null;
29
+ uTextured: WebGLUniformLocation | null;
30
+ uLut: WebGLUniformLocation | null;
31
+ uAdditive: WebGLUniformLocation | null;
32
+ uAlphaFromRed: WebGLUniformLocation | null;
33
+ uErode: WebGLUniformLocation | null;
34
+ uErodeFactors: WebGLUniformLocation | null;
35
+ uMask: WebGLUniformLocation | null;
36
+ uUvPolar: WebGLUniformLocation | null;
37
+ /** Additive resolve pass (normalize summed light -> straight color + coverage). */
38
+ resolveProgram: WebGLProgram;
39
+ uAccum: WebGLUniformLocation | null;
40
+ accum: AccumTarget | null;
41
+ }
42
+ declare function getParticleProgram(gl: WebGL2RenderingContext): ParticleProgram | null;
43
+ interface DrawParticlesOptions {
44
+ texture: WebGLTexture | null;
45
+ textured: boolean;
46
+ /**
47
+ * Baked per-texel color LUT (1px-tall RGBA ramp) bound on texture unit 1, or null.
48
+ * Present => the fragment shader replaces each texel's RGB with `lut(texel.r)`, keeping
49
+ * the source alpha. See `ParticleSpecConfig.colorLut`.
50
+ */
51
+ lutTexture?: WebGLTexture | null;
52
+ /**
53
+ * Quad-shaped coverage mask bound on texture unit 2, or null. Present => the fragment multiplies coverage by
54
+ * its RED channel (`ParticleSpecConfig.maskUrl`). A still-loading texture is the shared 1x1 TRANSPARENT
55
+ * placeholder, so the system stays invisible until it decodes — the same "no mask, no particle" the game shows.
56
+ */
57
+ maskTexture?: WebGLTexture | null;
58
+ hframes: number;
59
+ vframes: number;
60
+ blendMode: number;
61
+ viewportW: number;
62
+ viewportH: number;
63
+ /** The rect the pixels actually LAND in (≤ viewportW/H): the caller's clamped `gl.viewport`
64
+ * when the shared drawing buffer couldn't hold the full viewportW×H (see
65
+ * `ensureSharedDrawSize`). `viewportW/H` stay the px coordinate DOMAIN (the vertex NDC
66
+ * mapping divides by them), so a smaller target scales the draw down; the caller's blit
67
+ * scales it back up. Defaults to viewportW/H — a healthy buffer changes nothing. */
68
+ targetW?: number;
69
+ targetH?: number;
70
+ /** Non-default destination for a borrowed-stage additive resolve. */
71
+ targetFramebuffer?: WebGLFramebuffer | null;
72
+ /**
73
+ * Add the resolved light into an already-painted destination rather than
74
+ * overwriting a freshly cleared particle surface. This is required when an
75
+ * additive system is an ordered pass in a shared canvas framebuffer.
76
+ */
77
+ additiveResolveIntoExisting?: boolean;
78
+ /** `ParticleSpecConfig.alphaFromRed`: coverage from the source RED channel, pre-LUT. */
79
+ alphaFromRed?: boolean;
80
+ /** `ParticleSpecConfig.alphaErode`: constant-erosion smoothstep applied to coverage. */
81
+ erode?: {
82
+ threshold: number;
83
+ softness: number;
84
+ } | null;
85
+ /** `ParticleSpecConfig.uvPolar`: sample the sheet through Godot's polar_coordinates remap. */
86
+ uvPolar?: boolean;
87
+ }
88
+ /** Allocate additive accumulation storage before a caller mutates simulation state. */
89
+ declare function prepareParticleDraw(gl: WebGL2RenderingContext, program: ParticleProgram, opts: DrawParticlesOptions): boolean;
90
+ declare function blendFactorsFor(blendMode: number): [string, string, string, string];
91
+ declare function drawParticles(sharedGl: ParticleGl, program: ParticleProgram, buffer: InstanceBuffer, opts: DrawParticlesOptions): boolean;
92
+ //#endregion
93
+ //#region src/shader-webgl.d.ts
94
+ /** Allocate the shared clip-space quad used by full-surface shader draws. */
95
+ declare function createWebglFullscreenQuad(gl: WebGL2RenderingContext): WebGLBuffer | null;
96
+ declare function createWebglTexture(gl: WebGL2RenderingContext): WebGLTexture | null;
97
+ /** Upload bytes, an image, or a canvas with Godot's top-left UV convention. */
98
+ declare function uploadWebglTexture(gl: WebGL2RenderingContext, texture: WebGLTexture, source: TexImageSource | Uint8Array, width?: number, height?: number, opts?: {
99
+ repeat?: boolean;
100
+ nearest?: boolean;
101
+ }): void;
102
+ declare function createWebglPlaceholderTexture(gl: WebGL2RenderingContext, repeat: boolean): WebGLTexture | null;
103
+ interface PendingProgram {
104
+ ready(): boolean;
105
+ finish(): WebGLProgram | null;
106
+ }
107
+ /** Kick compilation and linking without synchronously asking the driver for status. */
108
+ declare function startProgram(gl: WebGL2RenderingContext, vertexSrc: string, fragmentSrc: string, beforeLink?: (program: WebGLProgram) => void): PendingProgram;
109
+ /** Compile and link synchronously for callers that cannot yield. */
110
+ declare function compileProgram(gl: WebGL2RenderingContext, vertexSrc: string, fragmentSrc: string, beforeLink?: (program: WebGLProgram) => void): WebGLProgram | null;
111
+ /** Finish when the parallel-compile extension says its status query will not block. */
112
+ declare function compileProgramAsync(gl: WebGL2RenderingContext, vertexSrc: string, fragmentSrc: string, beforeLink?: (program: WebGLProgram) => void): Promise<WebGLProgram | null>;
113
+ /** Fully precomputed GPU frame. HTML adapters calculate DOM geometry/captures first. */
114
+ interface WebglGodotShaderFrame {
115
+ readonly program: WebGLProgram;
116
+ readonly locations: ReadonlyMap<string, WebGLUniformLocation | null>;
117
+ readonly uniforms: readonly ShaderUniform[];
118
+ readonly quad: WebGLBuffer;
119
+ readonly width: number;
120
+ readonly height: number;
121
+ readonly texture: WebGLTexture | null;
122
+ readonly time?: number;
123
+ readonly texturePixelSize?: readonly [number, number];
124
+ readonly modulate: readonly [number, number, number, number];
125
+ readonly uvFit: readonly [number, number];
126
+ readonly uvWindow: readonly [number, number, number, number];
127
+ readonly screenOrigin?: readonly [number, number];
128
+ readonly screenSize?: readonly [number, number];
129
+ readonly screenTexture?: WebGLTexture;
130
+ readonly screenTextureUnit?: number;
131
+ readonly screenPixelSize?: readonly [number, number];
132
+ readonly samplers: readonly {
133
+ name: string;
134
+ unit: number;
135
+ texture: WebGLTexture | null;
136
+ }[];
137
+ readonly params: Readonly<Record<string, number | readonly number[]>>;
138
+ readonly paramKinds: Readonly<Record<string, string>>;
139
+ }
140
+ /** Execute one Godot shader frame in a borrowed context; no DOM, scheduling, or capture work. */
141
+ declare function drawGodotWebglShaderFrame(gl: WebGL2RenderingContext, frame: WebglGodotShaderFrame): void;
142
+ /** Exact Godot scalar/vector/array upload rules. Callers retain their own binding model. */
143
+ declare function uploadGodotShaderUniform(gl: WebGL2RenderingContext, location: WebGLUniformLocation | null, uniform: ShaderUniform, raw: number | readonly number[] | undefined, paramKind?: string): void;
144
+ /** Clear a supplied framebuffer's draw region; callers control its lifetime and binding. */
145
+ declare function clearWebglSurface(gl: WebGL2RenderingContext, width: number, height: number, scissorToViewport?: boolean): void;
146
+ /** Release an owned texture. Borrowed texture handles must not be passed here. */
147
+ declare function deleteWebglTexture(gl: WebGL2RenderingContext, texture: WebGLTexture | null): void;
148
+ //#endregion
149
+ //#region src/webgl.d.ts
150
+ type HeadlessEffectDiagnosticCode = "CONTEXT_LOST" | "DISPOSED" | "INVALID_DIMENSIONS" | "INVALID_RENDER_INPUT" | "RESOURCE_ALLOCATION_FAILED" | "FRAMEBUFFER_INCOMPLETE" | "SHADER_COMPILE_FAILED" | "UNSUPPORTED_SHADER_FEATURE" | "UNSUPPORTED_PARTICLE_FEATURE" | "SCREEN_TEXTURE_REQUIRED" | "FOREIGN_TARGET";
151
+ interface HeadlessEffectDiagnostic {
152
+ readonly code: HeadlessEffectDiagnosticCode;
153
+ readonly message: string;
154
+ /** The exact requested capability where a typed producer declines it. */
155
+ readonly feature?: string;
156
+ }
157
+ type HeadlessEffectResult<T> = {
158
+ readonly ok: true;
159
+ readonly value: T;
160
+ } | {
161
+ readonly ok: false;
162
+ readonly diagnostic: HeadlessEffectDiagnostic;
163
+ };
164
+ /** An RGBA8 texture/FBO pair owned by one {@link HeadlessEffectsStage}. */
165
+ interface HeadlessEffectTarget {
166
+ readonly texture: WebGLTexture | null;
167
+ readonly framebuffer: WebGLFramebuffer | null;
168
+ readonly width: number;
169
+ readonly height: number;
170
+ }
171
+ /** A same-context read-only source. Borrowed cache textures are never deleted by this stage. */
172
+ /** A live texture from this WebGL context. Resource decoding stays with the host. */
173
+ interface WebglTextureInput {
174
+ readonly texture: WebGLTexture;
175
+ readonly width: number;
176
+ readonly height: number;
177
+ }
178
+ type HeadlessTextureInput = HeadlessEffectTarget | WebglTextureInput;
179
+ /**
180
+ * The framebuffer supplied by a host at a precise painter position. This is a
181
+ * GPU contract, deliberately free of DrawList and HTML binding objects.
182
+ */
183
+ interface WebglEffectTargetContext {
184
+ readonly framebuffer: WebGLFramebuffer | null;
185
+ readonly width: number;
186
+ readonly height: number;
187
+ readonly damage?: unknown;
188
+ readonly scissor: Readonly<{
189
+ x: number;
190
+ y: number;
191
+ width: number;
192
+ height: number;
193
+ }>;
194
+ }
195
+ type HeadlessShaderFeature = "screen-texture" | "time" | "delta" | "seed" | "external-textures" | "multiple-render-targets" | "transform-feedback" | "godot-source";
196
+ type HeadlessUniformValue = number | readonly [number, number] | readonly [number, number, number] | readonly [number, number, number, number];
197
+ /**
198
+ * A complete GLSL ES 3 fragment pass. It receives `v_uv`; optional uniforms
199
+ * are `u_time`, `u_delta`, `u_seed`, `u_resolution`, and (when declared in
200
+ * `features`) `u_screenTexture`. Application uniforms are numeric scalars or
201
+ * vec2/3/4 values. Other textures and Godot shader-language translation are
202
+ * intentionally refused rather than guessed.
203
+ */
204
+ interface HeadlessShaderPass {
205
+ /** Fragment output MUST be premultiplied RGBA, matching the canvas stage contract. */
206
+ readonly fragmentSource: string;
207
+ readonly features?: readonly HeadlessShaderFeature[];
208
+ readonly uniforms?: Readonly<Record<string, HeadlessUniformValue>>;
209
+ }
210
+ interface HeadlessShaderRenderInput {
211
+ readonly time: number;
212
+ readonly delta: number;
213
+ readonly seed?: number;
214
+ /** Snapshot of the accumulated painter target at this exact caller-selected position. */
215
+ readonly screenTexture?: HeadlessEffectTarget;
216
+ }
217
+ interface HeadlessShaderProducer {
218
+ readonly target: HeadlessEffectTarget;
219
+ /** Compile and cache the GPU pass before the caller’s frame-critical path. */
220
+ warmUp(): HeadlessEffectResult<void>;
221
+ resize(width: number, height: number): HeadlessEffectResult<void>;
222
+ render(input: HeadlessShaderRenderInput): HeadlessEffectResult<HeadlessEffectTarget>;
223
+ /** Execute by snapshotting an executor's current framebuffer, then replace it. */
224
+ renderScreen(input: HeadlessShaderRenderInput, context: WebglEffectTargetContext): HeadlessEffectResult<void>;
225
+ /** Delete ordinary live-context resources; the producer remains reusable. */
226
+ invalidate(): void;
227
+ /** Context-loss only: discard names without issuing GL calls. */
228
+ invalidateContextLoss(): void;
229
+ dispose(): void;
230
+ }
231
+ /** Numeric values accepted by the existing Godot shader compiler. */
232
+ type HeadlessGodotShaderValue = number | readonly number[];
233
+ /**
234
+ * DOM-free inputs for the same canvas_item compiler used by the HTML runtime.
235
+ * Textures deliberately name stage targets, never URLs: loading/decoding is an
236
+ * HTML concern and an unresolved source is a typed refusal instead of a blank
237
+ * approximation.
238
+ */
239
+ interface HeadlessGodotShaderPass {
240
+ readonly source: string;
241
+ readonly texture?: HeadlessTextureInput;
242
+ readonly samplers?: Readonly<Record<string, HeadlessTextureInput>>;
243
+ readonly uniforms?: Readonly<Record<string, HeadlessGodotShaderValue>>;
244
+ readonly modulate?: readonly [number, number, number, number];
245
+ readonly uvFit?: readonly [number, number];
246
+ readonly uvWindow?: readonly [number, number, number, number];
247
+ }
248
+ interface HeadlessGodotShaderRenderInput extends HeadlessShaderRenderInput {
249
+ /** Node rect in normalized stage coordinates, for SCREEN_UV. */
250
+ readonly screenRect?: readonly [number, number, number, number];
251
+ }
252
+ interface HeadlessGodotShaderProducer {
253
+ readonly target: HeadlessEffectTarget;
254
+ /** The source render_mode blend, for the caller's surrounding canvas draw. */
255
+ readonly blend: GodotBlendMode;
256
+ warmUp(): HeadlessEffectResult<void>;
257
+ resize(width: number, height: number): HeadlessEffectResult<void>;
258
+ render(input: HeadlessGodotShaderRenderInput): HeadlessEffectResult<HeadlessEffectTarget>;
259
+ renderScreen(input: HeadlessGodotShaderRenderInput, context: WebglEffectTargetContext): HeadlessEffectResult<void>;
260
+ invalidate(): void;
261
+ invalidateContextLoss(): void;
262
+ dispose(): void;
263
+ }
264
+ interface HeadlessParticleFeatures {
265
+ /** Only a point emitter is implemented in this first reusable GPU path. */
266
+ readonly emissionShape?: "point" | "box" | "circle";
267
+ readonly collision?: boolean;
268
+ readonly attractors?: boolean;
269
+ readonly textureAtlas?: boolean;
270
+ }
271
+ /** Deterministic, stateless procedural point-particle subset. */
272
+ interface HeadlessParticleParameters {
273
+ readonly maxParticles: number;
274
+ readonly emissionRate: number;
275
+ readonly lifetimeSeconds: number;
276
+ readonly position: readonly [number, number];
277
+ readonly directionRadians: number;
278
+ readonly spreadRadians: number;
279
+ readonly speedMin: number;
280
+ readonly speedMax: number;
281
+ readonly gravity: readonly [number, number];
282
+ /** Straight RGBA 0..1; the GPU pass premultiplies before writing to its target. */
283
+ readonly startColor: readonly [number, number, number, number];
284
+ /** Straight RGBA 0..1; the GPU pass premultiplies before writing to its target. */
285
+ readonly endColor: readonly [number, number, number, number];
286
+ readonly startSizePx: number;
287
+ readonly endSizePx: number;
288
+ readonly features?: HeadlessParticleFeatures;
289
+ }
290
+ interface HeadlessParticleRenderInput {
291
+ readonly time: number;
292
+ readonly delta: number;
293
+ readonly seed: number;
294
+ }
295
+ interface HeadlessParticleProducer {
296
+ readonly target: HeadlessEffectTarget;
297
+ /** Compile and cache the GPU pass before the caller’s frame-critical path. */
298
+ warmUp(): HeadlessEffectResult<void>;
299
+ resize(width: number, height: number): HeadlessEffectResult<void>;
300
+ /** Re-evaluates from explicit inputs; it owns neither stateful simulation nor a timer. */
301
+ render(input: HeadlessParticleRenderInput): HeadlessEffectResult<HeadlessEffectTarget>;
302
+ invalidate(): void;
303
+ invalidateContextLoss(): void;
304
+ dispose(): void;
305
+ }
306
+ /** Caller-owned semantic storage. Supplying this keeps particle state and bytes reusable across producers. */
307
+ interface GodotParticleScratch {
308
+ /** Render-only fields intentionally live beside the portable simulation state. */
309
+ readonly config: ParticleRenderConfig;
310
+ readonly state: ParticleSystemState;
311
+ readonly instances: InstanceBuffer;
312
+ }
313
+ /** Allocate reusable, DOM-free simulation and instance storage for a normalized Godot particle spec. */
314
+ declare function createGodotParticleScratch(config: ParticleRenderConfig | Partial<ParticleRenderConfig>, maxInstances?: number): GodotParticleScratch;
315
+ /** Explicit live stage textures; no URL decoding, loading, or foreign GL texture ownership is accepted. */
316
+ interface HeadlessGodotParticlePass {
317
+ /** Omit when scratch is supplied: then scratch owns the normalized config. */
318
+ readonly config?: ParticleRenderConfig | Partial<ParticleRenderConfig>;
319
+ readonly spriteTexture?: HeadlessTextureInput;
320
+ readonly lutTexture?: HeadlessTextureInput;
321
+ readonly maskTexture?: HeadlessTextureInput;
322
+ /** Declared material capabilities are refused rather than silently approximated. */
323
+ readonly features?: Readonly<{
324
+ collision?: boolean;
325
+ attractors?: boolean;
326
+ trails?: boolean;
327
+ customMaterial?: boolean;
328
+ }>;
329
+ readonly scratch?: GodotParticleScratch;
330
+ }
331
+ interface HeadlessGodotParticleRenderInput {
332
+ /** Renderer-selected local emitter placement; never part of simulation state. */
333
+ readonly origin?: readonly [number, number];
334
+ readonly time: number;
335
+ readonly delta: number;
336
+ readonly emitting: boolean;
337
+ /** Reset state at this exact caller-selected frame; no producer clock is consulted. */
338
+ readonly restart?: boolean;
339
+ }
340
+ /**
341
+ * Per-draw local-to-framebuffer similarity transform in Godot Transform2D
342
+ * order `[xx, xy, yx, yy, originX, originY]`. Omit for identity. A direct
343
+ * particle pass refuses skew and non-uniform scale rather than deforming a
344
+ * sprite whose renderer only has scalar rotation and independent local size.
345
+ */
346
+ interface HeadlessGodotParticleDirectRenderInput extends HeadlessGodotParticleRenderInput {
347
+ readonly transform?: readonly [number, number, number, number, number, number];
348
+ /**
349
+ * Straight inherited CanvasItem RGBA. Each component multiplies the matching
350
+ * particle instance component before the shared renderer premultiplies it.
351
+ */
352
+ readonly modulate?: readonly [number, number, number, number];
353
+ }
354
+ interface HeadlessGodotParticleProducer {
355
+ readonly target: HeadlessEffectTarget;
356
+ readonly scratch: GodotParticleScratch;
357
+ warmUp(): HeadlessEffectResult<void>;
358
+ resize(width: number, height: number): HeadlessEffectResult<void>;
359
+ render(input: HeadlessGodotParticleRenderInput): HeadlessEffectResult<HeadlessEffectTarget>;
360
+ invalidate(): void;
361
+ invalidateContextLoss(): void;
362
+ dispose(): void;
363
+ }
364
+ /**
365
+ * A Godot-particle producer that paints into the canvas executor's live target.
366
+ * It allocates no per-system target texture or compositor FBO.
367
+ */
368
+ interface HeadlessGodotParticleDirectPass {
369
+ readonly scratch: GodotParticleScratch;
370
+ warmUp(): HeadlessEffectResult<void>;
371
+ draw(input: HeadlessGodotParticleDirectRenderInput, context: WebglEffectTargetContext): HeadlessEffectResult<void>;
372
+ invalidate(): void;
373
+ invalidateContextLoss(): void;
374
+ dispose(): void;
375
+ }
376
+ /** Explicit painter-position copy of an accumulated target. */
377
+ interface HeadlessScreenSampleCommand {
378
+ readonly source: HeadlessEffectTarget;
379
+ readonly destination: HeadlessEffectTarget;
380
+ readonly filter?: "nearest" | "linear";
381
+ }
382
+ interface HeadlessEffectsStage {
383
+ readonly gl: WebGL2RenderingContext;
384
+ createShaderProducer(pass: HeadlessShaderPass, width: number, height: number): HeadlessEffectResult<HeadlessShaderProducer>;
385
+ /** Compile the shared Godot canvas_item semantic engine without DOM ownership. */
386
+ createGodotShaderProducer(pass: HeadlessGodotShaderPass, width: number, height: number): HeadlessEffectResult<HeadlessGodotShaderProducer>;
387
+ createParticleProducer(parameters: HeadlessParticleParameters, width: number, height: number): HeadlessEffectResult<HeadlessParticleProducer>;
388
+ createGodotParticleProducer(pass: HeadlessGodotParticlePass, width: number, height: number): HeadlessEffectResult<HeadlessGodotParticleProducer>;
389
+ /** Create a direct painter pass; it never creates a system target or copy surface. */
390
+ createGodotParticleDirectPass(pass: HeadlessGodotParticlePass): HeadlessEffectResult<HeadlessGodotParticleDirectPass>;
391
+ /**
392
+ * Execute a copy at the call site’s draw-list position. A same-target copy is
393
+ * routed through a stage-owned snapshot, never a read/write feedback loop.
394
+ */
395
+ executeScreenSample(command: HeadlessScreenSampleCommand): HeadlessEffectResult<void>;
396
+ /** Delete ordinary live-context resources; producers remain reusable. */
397
+ invalidate(): void;
398
+ /** Drop dead GL handles after context loss without issuing delete calls. */
399
+ invalidateContextLoss(): void;
400
+ /** Delete every stage-owned GL handle while the context is live. */
401
+ dispose(): void;
402
+ }
403
+ /** Safe ceiling for the stateless point-particle subset. Larger systems are refused. */
404
+ declare const MAX_HEADLESS_PARTICLES = 16384;
405
+ /** Create a DOM-free owner for effect FBOs and their ordered GPU passes. */
406
+ declare function createHeadlessEffectsStage(gl: WebGL2RenderingContext): HeadlessEffectsStage;
407
+ //#endregion
408
+ export { GodotParticleScratch, HeadlessEffectDiagnostic, HeadlessEffectDiagnosticCode, HeadlessEffectResult, HeadlessEffectTarget, HeadlessEffectsStage, HeadlessGodotParticleDirectPass, HeadlessGodotParticleDirectRenderInput, HeadlessGodotParticlePass, HeadlessGodotParticleProducer, HeadlessGodotParticleRenderInput, HeadlessGodotShaderPass, HeadlessGodotShaderProducer, HeadlessGodotShaderRenderInput, HeadlessGodotShaderValue, HeadlessParticleFeatures, HeadlessParticleParameters, HeadlessParticleProducer, HeadlessParticleRenderInput, HeadlessScreenSampleCommand, HeadlessShaderFeature, HeadlessShaderPass, HeadlessShaderProducer, HeadlessShaderRenderInput, HeadlessTextureInput, HeadlessUniformValue, MAX_HEADLESS_PARTICLES, type PendingProgram, WebglEffectTargetContext, type WebglGodotShaderFrame, WebglTextureInput, blendFactorsFor, clearWebglSurface, compileProgram, compileProgramAsync, createGodotParticleScratch, createHeadlessEffectsStage, createWebglFullscreenQuad, createWebglPlaceholderTexture, createWebglTexture, deleteWebglTexture, disposeParticleInstanceBuffer, drawGodotWebglShaderFrame, drawParticles, getParticleProgram, invalidateParticleInstanceBuffer, prepareParticleDraw, startProgram, uploadGodotShaderUniform, uploadWebglTexture };
409
+ //# sourceMappingURL=webgl.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgl.d.mts","names":[],"sources":["../src/particle-webgl.ts","../src/shader-webgl.ts","../src/webgl.ts"],"mappings":"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"}