@solidrt/flux-types 0.0.44 → 0.0.46
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/gui/gpu.d.ts +317 -73
- package/index.d.ts +1 -0
- package/modules/image.d.ts +24 -0
- package/modules/process.d.ts +4 -2
- package/package.json +1 -1
package/gui/gpu.d.ts
CHANGED
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
// ids (-> destroyRenderPipeline).
|
|
8
8
|
// Layering: compileShader/linkProgram are the raw GL primitives (complete
|
|
9
9
|
// sources, explicit header opt-in); createRenderPipeline pairs a program with
|
|
10
|
-
// draw state (topology, blend, depth, vertex layout - how it draws);
|
|
10
|
+
// draw state (topology, blend, cull, depth, vertex layout - how it draws);
|
|
11
11
|
// createShaderTarget builds a texture-backed target over a pipeline (size,
|
|
12
|
-
// buffer, uniforms, clear - where it draws)
|
|
13
|
-
//
|
|
14
|
-
//
|
|
12
|
+
// buffer, uniforms, clear - where it draws); createDrawTarget holds an
|
|
13
|
+
// ordered, mutable LIST of such draws in one target (addDraw/removeDraw +
|
|
14
|
+
// per-entry setters, sharing one depth buffer) - the multi-pass render pass.
|
|
15
|
+
// createShaderTexture/createPipelineTexture are fused conveniences (compile +
|
|
16
|
+
// link + pipeline + target in one call, curated preamble) - named for what
|
|
17
|
+
// they return.
|
|
15
18
|
//
|
|
16
19
|
// Sampling is a per-texture property declared at creation: every create path
|
|
17
20
|
// accepts `{ filter?, wrap? }` ("linear"/"nearest", "clamp"/"repeat";
|
|
@@ -81,6 +84,13 @@ declare module "flux:gpu" {
|
|
|
81
84
|
export type ProgramId = number & { readonly __program: unique symbol }
|
|
82
85
|
/** The render-pipeline id space ({@link createRenderPipeline}); see {@link TextureId} for the brand model. */
|
|
83
86
|
export type RenderPipelineId = number & { readonly __renderPipeline: unique symbol }
|
|
87
|
+
/**
|
|
88
|
+
* A draw-entry handle on a draw target ({@link addDraw}); see
|
|
89
|
+
* {@link TextureId} for the brand model. Target-scoped and stable: an id
|
|
90
|
+
* keeps naming its entry across other adds and removes (never an index),
|
|
91
|
+
* and a removed entry's id errors from then on rather than aliasing.
|
|
92
|
+
*/
|
|
93
|
+
export type DrawId = number & { readonly __draw: unique symbol }
|
|
84
94
|
/**
|
|
85
95
|
* Shader uniform values by name. A number drives a scalar uniform (`float`,
|
|
86
96
|
* or `int`/`bool`, truncated); a flat number array drives a typed uniform
|
|
@@ -113,7 +123,7 @@ declare module "flux:gpu" {
|
|
|
113
123
|
* messages, so a chain of targets reads as "bloom-h samples particle-verts"
|
|
114
124
|
* instead of anonymous ids. Not unique, never interpreted; set at create,
|
|
115
125
|
* kept across id-stable resizes ({@link resizeTexture},
|
|
116
|
-
* {@link
|
|
126
|
+
* {@link setTargetSize}).
|
|
117
127
|
*/
|
|
118
128
|
export type LabelOption = { label?: string }
|
|
119
129
|
/**
|
|
@@ -176,8 +186,8 @@ declare module "flux:gpu" {
|
|
|
176
186
|
* working, and shaders sampling the texture re-render. `data` seeds the new
|
|
177
187
|
* contents and, like {@link createMutableTexture}, must hold at least one
|
|
178
188
|
* frame at the id's format (which survives the resize, like the sampler
|
|
179
|
-
* state).
|
|
180
|
-
* {@link
|
|
189
|
+
* state). Render target ids are rejected - resize those with
|
|
190
|
+
* {@link setTargetSize}.
|
|
181
191
|
*/
|
|
182
192
|
export function resizeTexture(id: TextureId, data: Uint8Array, width: number, height: number): void
|
|
183
193
|
/**
|
|
@@ -195,7 +205,7 @@ declare module "flux:gpu" {
|
|
|
195
205
|
* for the value shapes and the validation contract - a typo'd name throws
|
|
196
206
|
* here, at the create). It is its own argument, not an option, because it
|
|
197
207
|
* is the initial value of a live channel - the same values the `<texture
|
|
198
|
-
* params>` prop and {@link
|
|
208
|
+
* params>` prop and {@link setTargetParams} drive later; pass `null` (or
|
|
199
209
|
* omit it) for a shader with none. `opts.textures` binds sampler2D
|
|
200
210
|
* uniforms to texture ids - any texture id, including another
|
|
201
211
|
* shader/pipeline target's output, under a name that must be an active
|
|
@@ -273,19 +283,36 @@ declare module "flux:gpu" {
|
|
|
273
283
|
* (its own id space, like programs and buffers - not a texture id): the
|
|
274
284
|
* pipeline state object of every modern GPU API. The pipeline owns HOW its
|
|
275
285
|
* targets draw - `attributes` (the interleaved vertex layout; omit for
|
|
276
|
-
* attributeless rendering via gl_VertexID), `
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
286
|
+
* attributeless rendering via gl_VertexID), `instanceAttributes` (the
|
|
287
|
+
* per-instance layout, fetched from each entry's `instanceBuffer` - see
|
|
288
|
+
* the option's doc), `topology`, `blend`, `cull`, `depth`, `depthWrite`
|
|
289
|
+
* (`false` requires `depth: true`) - while each target brings its own
|
|
290
|
+
* size, buffers, uniforms, and clear. Both layouts share one attribute
|
|
291
|
+
* namespace (each name is one `in` of the vertex stage), so a name in
|
|
292
|
+
* both lists throws. Creating a pipeline compiles nothing, and many
|
|
293
|
+
* pipelines may share one program. The vocabulary is validated here, so a
|
|
294
|
+
* bad word throws at this call site. Free with
|
|
281
295
|
* {@link destroyRenderPipeline}; the program is yours and outlives it.
|
|
282
296
|
*/
|
|
283
297
|
export function createRenderPipeline(
|
|
284
298
|
program: ProgramId,
|
|
285
299
|
opts?: {
|
|
286
300
|
attributes?: VertexAttribute[]
|
|
301
|
+
/**
|
|
302
|
+
* One interleaved record per INSTANCE (WebGPU's `stepMode:
|
|
303
|
+
* "instance"`): these attributes read from the entry's
|
|
304
|
+
* `instanceBuffer` and advance per instance instead of per vertex, so
|
|
305
|
+
* every vertex of instance N sees record N - real per-instance state
|
|
306
|
+
* (offsets, colors, a packed transform) with no `gl_InstanceID`
|
|
307
|
+
* arithmetic. Declaring any makes `instanceBuffer` required on every
|
|
308
|
+
* entry drawn with this pipeline. A mat4 per instance is its four
|
|
309
|
+
* vec4 columns, reassembled in the shader (attributes have no matrix
|
|
310
|
+
* formats, as in WebGPU).
|
|
311
|
+
*/
|
|
312
|
+
instanceAttributes?: VertexAttribute[]
|
|
287
313
|
topology?: Topology
|
|
288
314
|
blend?: BlendMode
|
|
315
|
+
cull?: CullMode
|
|
289
316
|
depth?: boolean
|
|
290
317
|
depthWrite?: boolean
|
|
291
318
|
} & LabelOption,
|
|
@@ -301,17 +328,19 @@ declare module "flux:gpu" {
|
|
|
301
328
|
* Create a render target over a {@link createRenderPipeline} pipeline and
|
|
302
329
|
* render it once: the target half of {@link createPipelineTexture}. Returns
|
|
303
330
|
* a texture id exactly like the fused creates do (drive uniforms
|
|
304
|
-
* via the `params` prop or {@link
|
|
305
|
-
* {@link
|
|
331
|
+
* via the `params` prop or {@link setTargetParams}, resize with
|
|
332
|
+
* {@link setTargetSize}, destroy with {@link destroyTexture}). Many targets
|
|
306
333
|
* may share one pipeline, and creating a target compiles nothing. `buffer`
|
|
307
334
|
* supplies the concrete vertex buffer the pipeline's attribute layout
|
|
308
|
-
* describes (required when the pipeline declares attributes)
|
|
309
|
-
*
|
|
335
|
+
* describes (required when the pipeline declares attributes), and
|
|
336
|
+
* `instanceBuffer` the per-instance records its `instanceAttributes`
|
|
337
|
+
* describe (required exactly when it declares any); the
|
|
338
|
+
* {@link DrawRange} keys pick what is drawn from them - `vertexCount`
|
|
310
339
|
* defaults to the rest of the buffer from `firstVertex` on,
|
|
311
|
-
* `instanceCount`
|
|
312
|
-
* buffer's end throws here. A fullscreen
|
|
313
|
-
* pipeline is `vertexCount: 3` with a
|
|
314
|
-
* Draw-state keys
|
|
340
|
+
* `instanceCount` to one instance per instance-buffer record (1 without
|
|
341
|
+
* one) - and a fetch past either buffer's end throws here. A fullscreen
|
|
342
|
+
* pass over an attributeless pipeline is `vertexCount: 3` with a
|
|
343
|
+
* covering-triangle vertex stage. Draw-state keys
|
|
315
344
|
* (`attributes`, `topology`, `blend`, `depth`, `depthWrite`) belong to the
|
|
316
345
|
* pipeline and throw here. `params` and `textures` are validated against
|
|
317
346
|
* the pipeline's program (see {@link ShaderParams}).
|
|
@@ -341,10 +370,11 @@ declare module "flux:gpu" {
|
|
|
341
370
|
opts?: {
|
|
342
371
|
textures?: Record<string, TextureId>
|
|
343
372
|
buffer?: BufferId
|
|
373
|
+
instanceBuffer?: BufferId
|
|
344
374
|
clearColor?: [number, number, number, number]
|
|
345
375
|
render?: "auto" | "manual"
|
|
346
376
|
loadOp?: "clear" | "load"
|
|
347
|
-
} & DrawRange &
|
|
377
|
+
} & (DrawRange | (IndexBinding & IndexRange)) &
|
|
348
378
|
SamplerOptions &
|
|
349
379
|
LabelOption,
|
|
350
380
|
): TextureId
|
|
@@ -355,36 +385,6 @@ declare module "flux:gpu" {
|
|
|
355
385
|
* immediately.
|
|
356
386
|
*/
|
|
357
387
|
export function destroyProgram(id: ProgramId): void
|
|
358
|
-
/**
|
|
359
|
-
* Update a shader texture's uniforms by name and re-render it (see
|
|
360
|
-
* {@link ShaderParams} for the value shapes and the validation contract -
|
|
361
|
-
* an unknown name or a mismatched length throws here, on the line that
|
|
362
|
-
* wrote it). On a manual target nothing renders here; the values apply at
|
|
363
|
-
* its next {@link renderTarget}.
|
|
364
|
-
*/
|
|
365
|
-
export function setShaderParams(id: TextureId, params: ShaderParams): void
|
|
366
|
-
/**
|
|
367
|
-
* Rebind a shader texture's sampler2D inputs by uniform name and re-render
|
|
368
|
-
* it with its last-applied params - the sampler analog of
|
|
369
|
-
* {@link setShaderParams}. Bindings not named keep their current source, so
|
|
370
|
-
* a single input can be retargeted (post-process source swap, ping-pong
|
|
371
|
-
* between two data textures) without recompiling the shader. Throws if the
|
|
372
|
-
* shader or a source texture id is unknown, if a binding names anything
|
|
373
|
-
* but an active `sampler2D` uniform, if it names the shader's own target
|
|
374
|
-
* (same-pass feedback), or if it would close a sampling cycle among
|
|
375
|
-
* runtime-rendered targets. A cycle through a
|
|
376
|
-
* `render: "manual"` target is legal - the runtime never renders one, so
|
|
377
|
-
* the loop only steps when the app calls {@link renderTarget}.
|
|
378
|
-
*/
|
|
379
|
-
export function setShaderTextures(id: TextureId, textures: Record<string, TextureId>): void
|
|
380
|
-
/**
|
|
381
|
-
* Resize a shader or pipeline target texture in place and re-render it: the
|
|
382
|
-
* id, compiled program, last-applied params, and sampler bindings all carry
|
|
383
|
-
* over; only the output size changes. The setDraw analog for output
|
|
384
|
-
* size.
|
|
385
|
-
*/
|
|
386
|
-
export function setShaderSize(id: TextureId, width: number, height: number): void
|
|
387
|
-
|
|
388
388
|
export type Topology = "points" | "lines" | "line-strip" | "triangles" | "triangle-strip"
|
|
389
389
|
/**
|
|
390
390
|
* Blending for a pipeline's own draw. "none" (default) overwrites:
|
|
@@ -398,24 +398,75 @@ declare module "flux:gpu" {
|
|
|
398
398
|
*/
|
|
399
399
|
export type BlendMode = "none" | "add"
|
|
400
400
|
/**
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
401
|
+
* Face culling for a pipeline's draws. "none" (default) rasters both faces
|
|
402
|
+
* - the two-sided fallback open surfaces need. "back" discards faces wound
|
|
403
|
+
* away from the camera, halving a closed mesh's fragment work; "front"
|
|
404
|
+
* discards the other set (shadow and inside-out tricks). The winding rule
|
|
405
|
+
* is WebGPU's, fixed: counter-clockwise AS DISPLAYED (screen coordinates,
|
|
406
|
+
* y down) = front. Measured after every flip, so it just works: a mesh
|
|
407
|
+
* exported counter-clockwise-front for a y-up world, drawn through a
|
|
408
|
+
* standard right-handed camera (looking down -z) with the usual y
|
|
409
|
+
* negation for display, culls correctly with "back". If "back" shows you
|
|
410
|
+
* the mesh's inside anyway, the winding reaching the screen is mirrored -
|
|
411
|
+
* either the exporter winds clockwise, or the hand-rolled projection is
|
|
412
|
+
* left-handed (the classic: camera looking toward +z without mirroring
|
|
413
|
+
* x). Fix the rig, flip the exporter, or use "front".
|
|
414
|
+
*/
|
|
415
|
+
export type CullMode = "none" | "back" | "front"
|
|
416
|
+
/**
|
|
417
|
+
* One float attribute of an interleaved record - a vertex of `attributes`
|
|
418
|
+
* or an instance record of `instanceAttributes`. The list's order defines
|
|
419
|
+
* the byte layout; locations are resolved by name against the vertex
|
|
420
|
+
* shader's `in` declarations.
|
|
404
421
|
*/
|
|
405
422
|
export type VertexAttribute = { name: string; format: "f32" | "vec2" | "vec3" | "vec4" }
|
|
406
423
|
/**
|
|
407
424
|
* A pipeline target's draw as data, WebGPU-style: `firstVertex` +
|
|
408
425
|
* `vertexCount` pick the vertex range `[firstVertex, firstVertex +
|
|
409
426
|
* vertexCount)` of the buffer, `instanceCount` draws that range as N
|
|
410
|
-
* instances (`glDrawArraysInstanced`) told apart by `gl_InstanceID
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
427
|
+
* instances (`glDrawArraysInstanced`) told apart by `gl_InstanceID` (and
|
|
428
|
+
* by their `instanceAttributes` records, when the pipeline declares any).
|
|
429
|
+
* All keys optional: at create, `firstVertex` defaults to 0, `vertexCount`
|
|
430
|
+
* to the rest of the buffer, and `instanceCount` to one instance per
|
|
431
|
+
* record of the entry's `instanceBuffer` - 1 without one, the plain draw;
|
|
432
|
+
* in {@link setDraw}, absent keys keep their current value.
|
|
433
|
+
* `instanceCount: 0` draws nothing - a cheap off switch. With an instance
|
|
434
|
+
* buffer bound, `instanceCount` is bounds-checked against it like every
|
|
435
|
+
* fetch (instances 0..N-1 each read one record). Two GL facts worth
|
|
436
|
+
* knowing: `gl_VertexID` includes `firstVertex` (as in WebGPU), and
|
|
437
|
+
* `gl_InstanceID` always counts from 0 - ES 3.0 has no base instance.
|
|
417
438
|
*/
|
|
418
439
|
export type DrawRange = { firstVertex?: number; vertexCount?: number; instanceCount?: number }
|
|
440
|
+
/**
|
|
441
|
+
* The element type of an index buffer: "uint16" halves index bandwidth and
|
|
442
|
+
* addresses meshes up to 65535 vertices, "uint32" covers the rest -
|
|
443
|
+
* WebGPU's two formats exactly.
|
|
444
|
+
*/
|
|
445
|
+
export type IndexFormat = "uint16" | "uint32"
|
|
446
|
+
/**
|
|
447
|
+
* An entry's index binding: any {@link createBuffer} buffer plus its
|
|
448
|
+
* element type (the buffer is typeless bytes, so the format must be
|
|
449
|
+
* declared - as WebGPU does at setIndexBuffer). One buffer kind serves
|
|
450
|
+
* both roles; there is no separate index-buffer create. With a binding
|
|
451
|
+
* present the draw is `glDrawElements`: vertices are fetched through the
|
|
452
|
+
* index VALUES, so shared vertices are stored (and shaded) once, and the
|
|
453
|
+
* range speaks {@link IndexRange} instead of {@link DrawRange}. The
|
|
454
|
+
* index-buffer fetch is bounds-checked like every range; the index values
|
|
455
|
+
* themselves are not checked against the vertex buffer (that would mean
|
|
456
|
+
* reading them back) - an out-of-range index is the same undefined fetch
|
|
457
|
+
* raw GL gives you.
|
|
458
|
+
*/
|
|
459
|
+
export type IndexBinding = { indexBuffer: BufferId; indexFormat: IndexFormat }
|
|
460
|
+
/**
|
|
461
|
+
* The index-counted spelling of a draw range, for indexed entries
|
|
462
|
+
* (WebGPU's drawIndexed vocabulary): `firstIndex` + `indexCount` pick the
|
|
463
|
+
* range of the INDEX buffer, `instanceCount` as in {@link DrawRange}.
|
|
464
|
+
* Same defaults and merge rules; the vertex-named keys throw on an
|
|
465
|
+
* indexed entry (and these throw on a plain one), so a range never
|
|
466
|
+
* silently counts the wrong thing. `gl_VertexID` reads the index value;
|
|
467
|
+
* there is no base vertex (ES 3.0, like ES 3.0's missing base instance).
|
|
468
|
+
*/
|
|
469
|
+
export type IndexRange = { firstIndex?: number; indexCount?: number; instanceCount?: number }
|
|
419
470
|
|
|
420
471
|
/**
|
|
421
472
|
* Compile a GLSL ES vertex+fragment pipeline into an offscreen texture of
|
|
@@ -426,11 +477,14 @@ declare module "flux:gpu" {
|
|
|
426
477
|
* row of the target and +1 the bottom, so camera-up geometry must negate y
|
|
427
478
|
* (or fold the flip into its projection) to display up. `attributes`
|
|
428
479
|
* describes one interleaved vertex in `buffer` (a {@link createBuffer} id);
|
|
429
|
-
* omit both for attributeless rendering via gl_VertexID.
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
* the buffer
|
|
480
|
+
* omit both for attributeless rendering via gl_VertexID.
|
|
481
|
+
* `instanceAttributes` describes one per-instance record in
|
|
482
|
+
* `instanceBuffer` (see {@link createRenderPipeline}; declare both or
|
|
483
|
+
* neither). The {@link DrawRange} keys pick what is drawn: `vertexCount`
|
|
484
|
+
* defaults to the rest of the buffer from `firstVertex` on,
|
|
485
|
+
* `instanceCount` draws the range as N instances told apart by
|
|
486
|
+
* `gl_InstanceID` and defaults to one per instance-buffer record; a fetch
|
|
487
|
+
* past either buffer's end throws. With
|
|
434
488
|
* `depth: true` the pipeline gets a private depth buffer, cleared and tested
|
|
435
489
|
* on every render; `depthWrite: false` (requires `depth: true`) keeps the
|
|
436
490
|
* test but stops the draw from writing depth. `blend` sets the draw's own blending (see
|
|
@@ -442,7 +496,7 @@ declare module "flux:gpu" {
|
|
|
442
496
|
* {@link renderTarget}, and `loadOp: "load"` (manual-only) keeps the
|
|
443
497
|
* previous contents under each draw.
|
|
444
498
|
* Returns a texture id: display it with `<texture src>`, drive uniforms via
|
|
445
|
-
* the `params` prop or {@link
|
|
499
|
+
* the `params` prop or {@link setTargetParams}, destroy with
|
|
446
500
|
* {@link destroyTexture}.
|
|
447
501
|
*/
|
|
448
502
|
export function createPipelineTexture(
|
|
@@ -455,14 +509,18 @@ declare module "flux:gpu" {
|
|
|
455
509
|
textures?: Record<string, TextureId>
|
|
456
510
|
attributes?: VertexAttribute[]
|
|
457
511
|
buffer?: BufferId
|
|
512
|
+
/** See {@link createRenderPipeline}'s `instanceAttributes`. */
|
|
513
|
+
instanceAttributes?: VertexAttribute[]
|
|
514
|
+
instanceBuffer?: BufferId
|
|
458
515
|
topology?: Topology
|
|
459
516
|
depth?: boolean
|
|
460
517
|
depthWrite?: boolean
|
|
461
518
|
blend?: BlendMode
|
|
519
|
+
cull?: CullMode
|
|
462
520
|
clearColor?: [number, number, number, number]
|
|
463
521
|
render?: "auto" | "manual"
|
|
464
522
|
loadOp?: "clear" | "load"
|
|
465
|
-
} & DrawRange &
|
|
523
|
+
} & (DrawRange | (IndexBinding & IndexRange)) &
|
|
466
524
|
SamplerOptions &
|
|
467
525
|
LabelOption,
|
|
468
526
|
): TextureId
|
|
@@ -496,12 +554,198 @@ declare module "flux:gpu" {
|
|
|
496
554
|
* buffer size) - the out-of-bounds draw GL itself never checks; a target
|
|
497
555
|
* without vertex fetch (attributeless) accepts any non-negative range.
|
|
498
556
|
* (On a manual target nothing renders here; the range applies at its next
|
|
499
|
-
* {@link renderTarget}.)
|
|
500
|
-
|
|
501
|
-
|
|
557
|
+
* {@link renderTarget}.) An indexed target takes the {@link IndexRange}
|
|
558
|
+
* spelling instead, bounds-checked against its index buffer; the pair
|
|
559
|
+
* that does not match the target's mode throws.
|
|
560
|
+
*/
|
|
561
|
+
export function setDraw(id: TextureId, draw: DrawRange | IndexRange): void
|
|
562
|
+
/**
|
|
563
|
+
* Create a draw target: a render target whose contents are an ordered,
|
|
564
|
+
* mutable LIST of draws - one render clears once, then executes every
|
|
565
|
+
* entry in list order into the same storage. The multi-pass shape of every
|
|
566
|
+
* 3D API (N meshes, N pipelines, one shared depth buffer), retained: where
|
|
567
|
+
* WebGPU re-encodes a render pass every frame, this target holds the pass
|
|
568
|
+
* as state and re-renders on demand. Entries are added and removed at any
|
|
569
|
+
* time ({@link addDraw}/{@link removeDraw}) and updated per entry
|
|
570
|
+
* ({@link setDrawParams}, {@link setDrawTextures}, {@link setDrawRange}).
|
|
571
|
+
*
|
|
572
|
+
* `depth: true` gives the target its own depth storage, shared by every
|
|
573
|
+
* entry and cleared once per render - this is what makes cross-entry
|
|
574
|
+
* occlusion work. It is the storage half of the depth story; whether an
|
|
575
|
+
* entry tests/writes depth is its pipeline's `depth`/`depthWrite` state,
|
|
576
|
+
* and adding a depth-testing pipeline to a target without storage throws.
|
|
577
|
+
*
|
|
578
|
+
* `params` seeds the target's SHARED params - the target-level values
|
|
579
|
+
* every entry reads, the same live channel {@link setTargetParams} drives
|
|
580
|
+
* later (positional like every create's params; see there for the
|
|
581
|
+
* precedence and validation contract). `opts.textures` seeds the shared
|
|
582
|
+
* sampler bindings the same way, the channel {@link setTargetTextures}
|
|
583
|
+
* drives (in opts like every create's textures). At creation there are no
|
|
584
|
+
* entries to validate against, so names are accepted as-is and simply
|
|
585
|
+
* apply to whichever later entries' programs declare them.
|
|
586
|
+
*
|
|
587
|
+
* The render contract is unchanged: the list is input data like params, so
|
|
588
|
+
* "render twice = render once" still holds and the default `render:
|
|
589
|
+
* "auto"` target re-renders exactly when its entries or their inputs
|
|
590
|
+
* change - a static scene costs zero passes, however many entries it
|
|
591
|
+
* holds, and one render is ONE pass however many entries it draws.
|
|
592
|
+
* `render: "manual"` and `loadOp: "load"` compose exactly as on
|
|
593
|
+
* {@link createShaderTarget}. With no entries a render is the clear alone.
|
|
594
|
+
* Returns a texture id (display, resize, destroy like any target; entries
|
|
595
|
+
* die with it).
|
|
596
|
+
*/
|
|
597
|
+
export function createDrawTarget(
|
|
598
|
+
width: number,
|
|
599
|
+
height: number,
|
|
600
|
+
params?: ShaderParams | null,
|
|
601
|
+
opts?: {
|
|
602
|
+
depth?: boolean
|
|
603
|
+
textures?: Record<string, TextureId>
|
|
604
|
+
clearColor?: [number, number, number, number]
|
|
605
|
+
render?: "auto" | "manual"
|
|
606
|
+
loadOp?: "clear" | "load"
|
|
607
|
+
} & SamplerOptions &
|
|
608
|
+
LabelOption,
|
|
609
|
+
): TextureId
|
|
610
|
+
/**
|
|
611
|
+
* Append a draw entry to a draw target: `pipeline` draws `opts.buffer`
|
|
612
|
+
* (required when the pipeline declares attributes) with its own `params`
|
|
613
|
+
* and `textures`, last in list order - the same per-entry shape
|
|
614
|
+
* {@link createShaderTarget} takes, addressed to one entry of the list.
|
|
615
|
+
* Returns the entry's {@link DrawId}, the handle every per-entry update
|
|
616
|
+
* takes. Everything validates here at the call site: unknown ids, depth
|
|
617
|
+
* compatibility (see {@link createDrawTarget}), uniform names and arities,
|
|
618
|
+
* the vertex-fetch bound, per-entry texture-unit count, and sampling
|
|
619
|
+
* cycles. List order is draw order - later entries land over earlier ones
|
|
620
|
+
* where depth does not decide - so painter-style layering is append order,
|
|
621
|
+
* and per-entry `params` is where per-object state (a model matrix) lives.
|
|
622
|
+
* `before` inserts the entry immediately before an existing one instead
|
|
623
|
+
* of appending (it must name a live entry); for wholesale reordering use
|
|
624
|
+
* {@link setDrawOrder}. An {@link IndexBinding} makes the entry draw
|
|
625
|
+
* indexed - real meshes share most vertices, and indexing stores and
|
|
626
|
+
* shades each one once - with the range in {@link IndexRange} spelling.
|
|
627
|
+
* `instanceBuffer` supplies the per-instance records the pipeline's
|
|
628
|
+
* `instanceAttributes` describe (required exactly when it declares any);
|
|
629
|
+
* `instanceCount` then defaults to one instance per record.
|
|
630
|
+
*
|
|
631
|
+
* Seed every uniform the entry's program declares - here, via the
|
|
632
|
+
* target's shared params, or with a later write. GL uniform state lives
|
|
633
|
+
* on the program object, so a declared name nothing writes holds
|
|
634
|
+
* whatever the last draw through that program applied, from any entry
|
|
635
|
+
* or target sharing it - not zero (only a freshly linked program reads
|
|
636
|
+
* the link-time zero). Coverage is deliberately not validated here:
|
|
637
|
+
* adding entries first and setting shared values after is legal.
|
|
638
|
+
*/
|
|
639
|
+
export function addDraw(
|
|
640
|
+
target: TextureId,
|
|
641
|
+
pipeline: RenderPipelineId,
|
|
642
|
+
params?: ShaderParams | null,
|
|
643
|
+
opts?: {
|
|
644
|
+
textures?: Record<string, TextureId>
|
|
645
|
+
buffer?: BufferId
|
|
646
|
+
instanceBuffer?: BufferId
|
|
647
|
+
before?: DrawId
|
|
648
|
+
} & (DrawRange | (IndexBinding & IndexRange)),
|
|
649
|
+
): DrawId
|
|
650
|
+
/**
|
|
651
|
+
* Remove a draw entry from a draw target. Remaining entries keep their
|
|
652
|
+
* order and ids; the removed id errors from then on (ids are never
|
|
653
|
+
* reused). The entry's pipeline and buffer are yours and unaffected.
|
|
654
|
+
*/
|
|
655
|
+
export function removeDraw(target: TextureId, draw: DrawId): void
|
|
656
|
+
/**
|
|
657
|
+
* Update one draw entry's uniforms by name: {@link setTargetParams}
|
|
658
|
+
* addressed to a single entry, same merge and validation contract. The
|
|
659
|
+
* per-object hot path - a moved mesh is one setDrawParams with its new
|
|
660
|
+
* model matrix.
|
|
661
|
+
*/
|
|
662
|
+
export function setDrawParams(target: TextureId, draw: DrawId, params: ShaderParams): void
|
|
663
|
+
/**
|
|
664
|
+
* Update a target's target-level uniforms by name, on any target kind,
|
|
665
|
+
* with the usual merge-by-name (see {@link ShaderParams} for value shapes;
|
|
666
|
+
* a bad name or a mismatched length throws here, on the line that wrote
|
|
667
|
+
* it). On a single-program target (a fragment texture or a pipeline
|
|
668
|
+
* target) the target level IS its one pass: every name validates against
|
|
669
|
+
* that program and the target re-renders. On a manual target nothing
|
|
670
|
+
* renders here; the values apply at its next {@link renderTarget}.
|
|
671
|
+
*
|
|
672
|
+
* On a draw target these are the SHARED params: values every entry reads
|
|
673
|
+
* - a camera's view-projection above all - written once per target
|
|
674
|
+
* instead of once per entry. Shared values apply at render before each
|
|
675
|
+
* entry's own params, so an entry naming the same uniform overrides the
|
|
676
|
+
* shared value (specific beats general), and they are target state: entry
|
|
677
|
+
* add/remove/rebuild cannot lose them. A draw target legitimately mixes
|
|
678
|
+
* material classes, so coverage may be partial: a name only some entries'
|
|
679
|
+
* programs declare is applied where declared and skipped elsewhere.
|
|
680
|
+
* Validation follows: each name must be an active settable uniform of at
|
|
681
|
+
* least ONE current entry's program (with the matching arity everywhere it
|
|
682
|
+
* is declared) - a name no entry declares throws. With no entries yet,
|
|
683
|
+
* names are accepted as-is; an entry added later whose program lacks an
|
|
684
|
+
* already-set name is never a retroactive error, the value just skips it.
|
|
685
|
+
*/
|
|
686
|
+
export function setTargetParams(target: TextureId, params: ShaderParams): void
|
|
687
|
+
/**
|
|
688
|
+
* Rebind a target's target-level sampler2D inputs by uniform name, on any
|
|
689
|
+
* target kind - {@link setTargetParams}'s sampler analog. Bindings not
|
|
690
|
+
* named keep their current source, so a single input can be retargeted
|
|
691
|
+
* (post-process source swap, ping-pong between two data textures) without
|
|
692
|
+
* recompiling anything. Bound sources are live dependencies: the target
|
|
693
|
+
* re-renders when one changes. Every path throws if the target or a
|
|
694
|
+
* source texture id is unknown, if a binding names the target's own
|
|
695
|
+
* texture (same-pass feedback), or if it would close a sampling cycle
|
|
696
|
+
* among runtime-rendered targets; a cycle through a `render: "manual"`
|
|
697
|
+
* target is legal - the runtime never renders one, so the loop only steps
|
|
698
|
+
* when the app calls {@link renderTarget}. On a single-program target each
|
|
699
|
+
* name must be an active `sampler2D` of its one program.
|
|
700
|
+
*
|
|
701
|
+
* On a draw target these are the SHARED bindings: sources every entry
|
|
702
|
+
* reads - an environment map, a shadow map, a LUT - bound once per
|
|
703
|
+
* target, with the shared-params rules throughout: an entry's own binding
|
|
704
|
+
* for the same name wins; a name only some entries' programs declare
|
|
705
|
+
* binds where declared and is skipped elsewhere; shared bindings are
|
|
706
|
+
* target state that entry add/remove/rebuild cannot lose. Each name must
|
|
707
|
+
* be an active sampler2D of at least ONE current entry's program (with no
|
|
708
|
+
* entries yet names are accepted as-is, and a later entry never
|
|
709
|
+
* retroactively errors), and each entry's effective inputs (its own plus
|
|
710
|
+
* the applicable shared ones) must fit the device's texture units.
|
|
711
|
+
*/
|
|
712
|
+
export function setTargetTextures(target: TextureId, textures: Record<string, TextureId>): void
|
|
713
|
+
/**
|
|
714
|
+
* Resize a render target of any kind in place and re-render it: the id,
|
|
715
|
+
* compiled programs, last-applied params, sampler bindings, and draw
|
|
716
|
+
* state all carry over; only the output size changes. The setDraw analog
|
|
717
|
+
* for output size. (Pixel textures resize with {@link resizeTexture},
|
|
718
|
+
* which carries seed pixels instead.)
|
|
719
|
+
*/
|
|
720
|
+
export function setTargetSize(id: TextureId, width: number, height: number): void
|
|
721
|
+
/**
|
|
722
|
+
* Rebind one draw entry's sampler2D inputs by uniform name:
|
|
723
|
+
* {@link setTargetTextures} addressed to a single entry, same merge,
|
|
724
|
+
* validation, and cycle rules. Entries bind independently - two entries
|
|
725
|
+
* may bind the same uniform name to different sources.
|
|
726
|
+
*/
|
|
727
|
+
export function setDrawTextures(target: TextureId, draw: DrawId, textures: Record<string, TextureId>): void
|
|
728
|
+
/**
|
|
729
|
+
* Update one draw entry's draw range: {@link setDraw} addressed to a
|
|
730
|
+
* single entry, same partial merge, bounds validation, and vocabulary
|
|
731
|
+
* rule (an indexed entry speaks {@link IndexRange}).
|
|
732
|
+
*/
|
|
733
|
+
export function setDrawRange(target: TextureId, draw: DrawId, update: DrawRange | IndexRange): void
|
|
734
|
+
/**
|
|
735
|
+
* Reorder a draw target's list. `order` must name every current entry
|
|
736
|
+
* exactly once - a full permutation of the live {@link DrawId}s; a
|
|
737
|
+
* missing, duplicate, or unknown id throws, naming the problem. List
|
|
738
|
+
* order is draw order, which makes this the sorting verb: sort opaque
|
|
739
|
+
* entries front-to-back (early depth rejection) and transparent ones
|
|
740
|
+
* back-to-front, and re-issue the order when the camera moves. Entry
|
|
741
|
+
* state (params, textures, ranges) rides along untouched; ids are
|
|
742
|
+
* unaffected. Like every draw-list write it re-renders an auto target
|
|
743
|
+
* once at the next flush, and folds silently on a manual one.
|
|
744
|
+
*/
|
|
745
|
+
export function setDrawOrder(target: TextureId, order: DrawId[]): void
|
|
502
746
|
/**
|
|
503
747
|
* Render a `render: "manual"` target once, now. Renders land in call order
|
|
504
|
-
* relative to every other GPU call: a `
|
|
748
|
+
* relative to every other GPU call: a `setTargetParams`/`writeBuffer`
|
|
505
749
|
* issued before is visible to the pass, a {@link readTexture} issued after
|
|
506
750
|
* observes it, and two renders run the pass twice in order. Inputs are
|
|
507
751
|
* fresh: pending runtime-driven renders of sampled targets resolve first.
|
package/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
/// <reference path="./modules/sqlite.d.ts" />
|
|
6
6
|
/// <reference path="./modules/subprocess.d.ts" />
|
|
7
7
|
/// <reference path="./modules/svg.d.ts" />
|
|
8
|
+
/// <reference path="./modules/image.d.ts" />
|
|
8
9
|
/// <reference path="./modules/p2p.d.ts" />
|
|
9
10
|
/// <reference path="./modules/net.d.ts" />
|
|
10
11
|
/// <reference path="./modules/mdns.d.ts" />
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare module "flux:image" {
|
|
2
|
+
/** Decoded pixels: tightly-packed RGBA8 plus the pixel dimensions. */
|
|
3
|
+
export type DecodedImage = {
|
|
4
|
+
data: Uint8Array
|
|
5
|
+
width: number
|
|
6
|
+
height: number
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Decodes encoded image bytes (png, jpeg, webp, gif, bmp, ico) into raw
|
|
11
|
+
* RGBA8 pixels plus the decoded dimensions. Synchronous, pure CPU. Throws
|
|
12
|
+
* when the bytes are not a decodable image.
|
|
13
|
+
*/
|
|
14
|
+
export function decodeImage(bytes: Uint8Array): DecodedImage
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Encodes raw RGBA8 pixels into an image file, the reverse of `decodeImage`
|
|
18
|
+
* (`encodeImage(decodeImage(bytes))` round-trips). `format` defaults to
|
|
19
|
+
* `"png"` (lossless, keeps alpha); `"jpeg"` drops the alpha channel and
|
|
20
|
+
* takes `quality` in 0..1 (default 0.9, ignored for png). Throws when
|
|
21
|
+
* `data.length` does not match `width * height * 4`.
|
|
22
|
+
*/
|
|
23
|
+
export function encodeImage(img: DecodedImage, options?: { format?: "png" | "jpeg"; quality?: number }): Uint8Array
|
|
24
|
+
}
|
package/modules/process.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
declare module "flux:process" {
|
|
2
2
|
/**
|
|
3
|
-
* The
|
|
4
|
-
*
|
|
3
|
+
* The arguments the app was started with; empty when there are none.
|
|
4
|
+
* App arguments only: no executable path, no script path (deliberately
|
|
5
|
+
* simpler than Node/Bun's two leading entries), so `argv[0]` is the first
|
|
6
|
+
* argument.
|
|
5
7
|
*/
|
|
6
8
|
export let argv: string[]
|
|
7
9
|
/** The host OS: "darwin", "win32", "linux", "android", ... */
|