@solidrt/flux-types 0.0.38 → 0.0.40
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 +190 -18
- package/package.json +1 -1
package/gui/gpu.d.ts
CHANGED
|
@@ -1,20 +1,60 @@
|
|
|
1
|
-
// Low-level GPU textures and
|
|
2
|
-
// imperative primitive; @solidrt/core's gpu helpers add reactive auto-cleanup
|
|
3
|
-
// top.
|
|
4
|
-
//
|
|
1
|
+
// Low-level GPU textures and shaders (gui-enabled runtime only). The
|
|
2
|
+
// imperative primitive; @solidrt/core's gpu helpers add reactive auto-cleanup
|
|
3
|
+
// on top. Three id spaces, each destroyed by its own destroyer: texture ids
|
|
4
|
+
// (the public token used as `<texture src>` and sampler inputs ->
|
|
5
|
+
// destroyTexture), buffer ids (-> destroyBuffer), and the raw shading layer's
|
|
6
|
+
// shader-stage ids (-> destroyShader) and program ids (-> destroyProgram).
|
|
7
|
+
// Layering: compileShader/linkProgram are the raw GL primitives (complete
|
|
8
|
+
// sources, explicit header opt-in); createShader/createPipeline are fused
|
|
9
|
+
// conveniences (compile + link + target in one call, curated preamble).
|
|
10
|
+
//
|
|
11
|
+
// Sampling is a per-texture property declared at creation: every create path
|
|
12
|
+
// accepts `{ filter?, wrap? }` ("linear"/"nearest", "clamp"/"repeat";
|
|
13
|
+
// defaults linear + clamp for every origin). The state follows the id
|
|
14
|
+
// everywhere it is sampled - shader passes and `<texture>` display alike -
|
|
15
|
+
// and survives id-stable resizes. It cannot be changed after creation. No
|
|
16
|
+
// mipmaps exist.
|
|
17
|
+
//
|
|
18
|
+
// Compositing several targets is a render-tree job, not a shader one: stack
|
|
19
|
+
// `<texture>` elements and set their `blendMode` (the full Skia set, e.g.
|
|
20
|
+
// "plus" for an additive pass over a base pass) instead of writing a pass that
|
|
21
|
+
// samples both. WITHIN one pipeline draw, `blend: "add"` accumulates
|
|
22
|
+
// overlapping geometry additively; anything else (a fragment target, or a
|
|
23
|
+
// pipeline without the option) draws with GL blending disabled and overwrites.
|
|
5
24
|
|
|
6
25
|
declare module "flux:gpu" {
|
|
26
|
+
/**
|
|
27
|
+
* Shader uniform values by name. A number drives a scalar uniform (`float`,
|
|
28
|
+
* or `int`/`bool`, truncated); a flat number array drives a typed uniform
|
|
29
|
+
* whose declared GLSL type sets the expected length: 2/3/4 for
|
|
30
|
+
* `vec2`/`vec3`/`vec4`, 16 (column-major) for `mat4`. Dispatch follows the
|
|
31
|
+
* shader's own declaration; a value whose length does not fit it is skipped
|
|
32
|
+
* with a runtime warning, as is a name with no active uniform.
|
|
33
|
+
*/
|
|
34
|
+
export type ShaderParams = Record<string, number | number[]>
|
|
35
|
+
/** Magnification/minification filter; "linear" (default) or hard-pixel "nearest". */
|
|
36
|
+
export type FilterMode = "linear" | "nearest"
|
|
37
|
+
/** Sampling outside 0..1: "clamp" (default, extend edge pixels) or "repeat" (tile). */
|
|
38
|
+
export type WrapMode = "clamp" | "repeat"
|
|
39
|
+
/**
|
|
40
|
+
* Per-texture sampling, declared at creation and fixed for the id's
|
|
41
|
+
* lifetime. Applies wherever the texture is sampled: shader/pipeline
|
|
42
|
+
* sampler2D inputs AND `<texture src>` display (a "nearest" texture
|
|
43
|
+
* upscales with hard pixels on screen - the pixel-art path). `wrap` only
|
|
44
|
+
* matters to shaders sampling outside 0..1; the display draw never tiles.
|
|
45
|
+
*/
|
|
46
|
+
export type SamplerOptions = { filter?: FilterMode; wrap?: WrapMode }
|
|
7
47
|
/**
|
|
8
48
|
* Create an immutable texture from an RGBA8 pixel buffer (exactly
|
|
9
49
|
* width*height*4 bytes). Returns the texture id.
|
|
10
50
|
*/
|
|
11
|
-
export function createTexture(data: Uint8Array, width: number, height: number): number
|
|
51
|
+
export function createTexture(data: Uint8Array, width: number, height: number, opts?: SamplerOptions): number
|
|
12
52
|
/**
|
|
13
53
|
* Create a texture intended to be updated later via {@link uploadTexture}. The
|
|
14
54
|
* seed buffer must hold at least one frame (width*height*4 bytes) and may hold
|
|
15
55
|
* more (uploadTexture selects a frame by offset).
|
|
16
56
|
*/
|
|
17
|
-
export function createMutableTexture(data: Uint8Array, width: number, height: number): number
|
|
57
|
+
export function createMutableTexture(data: Uint8Array, width: number, height: number, opts?: SamplerOptions): number
|
|
18
58
|
/**
|
|
19
59
|
* Replace a mutable texture's pixels. `data` may hold several frames; `offset`
|
|
20
60
|
* (default 0) selects which frame to upload.
|
|
@@ -40,26 +80,118 @@ declare module "flux:gpu" {
|
|
|
40
80
|
export function destroyTexture(id: number): void
|
|
41
81
|
/**
|
|
42
82
|
* Compile a GLSL ES fragment shader into an offscreen texture of the given
|
|
43
|
-
* size. `params` sets
|
|
44
|
-
* uniforms to texture ids
|
|
83
|
+
* size. `params` sets uniforms by name (see {@link ShaderParams} for the
|
|
84
|
+
* value shapes); `textures` binds sampler2D uniforms to texture ids - any
|
|
85
|
+
* texture id, including another shader/pipeline target's output. Bound
|
|
86
|
+
* targets are live dependencies: when a source re-renders (its params,
|
|
87
|
+
* geometry, or data change), every target sampling it re-renders too,
|
|
88
|
+
* transitively through chains, before the next frame or readback - no
|
|
89
|
+
* per-frame uniform write is needed to keep a chain current. Returns the resulting texture id. The fused
|
|
90
|
+
* convenience: one call compiles a program and creates a target over it,
|
|
91
|
+
* and the program lives and dies with the target. To share one compile
|
|
92
|
+
* across targets (or hold a program with no target yet), use the raw layer:
|
|
93
|
+
* {@link compileShader} + {@link linkProgram} + {@link createShaderTarget}.
|
|
94
|
+
*
|
|
95
|
+
* The preamble (`#version 300 es`, precision, `vUV`, `iResolution`, `iTime`,
|
|
96
|
+
* `fragColor`) is injected only into sources that do not declare their own
|
|
97
|
+
* `#version` line. A source that starts with `#version 300 es` is compiled
|
|
98
|
+
* exactly as written, so a shader with its own uniform names (a port from
|
|
99
|
+
* elsewhere) needs no rewriting and no drop to the raw layer. The built-in
|
|
100
|
+
* vertex stage still supplies `vUV` to a complete source; declare
|
|
101
|
+
* `in vec2 vUV;` yourself to read it. Same rule on {@link createPipeline}.
|
|
102
|
+
* A complete source may also declare `iResolution` as vec3 (the Shadertoy
|
|
103
|
+
* shape); it is then filled as `(w, h, 1.0)`.
|
|
45
104
|
*/
|
|
46
105
|
export function createShader(
|
|
47
106
|
fragmentSrc: string,
|
|
48
107
|
width: number,
|
|
49
108
|
height: number,
|
|
50
|
-
params?:
|
|
109
|
+
params?: ShaderParams,
|
|
51
110
|
textures?: Record<string, number>,
|
|
111
|
+
opts?: SamplerOptions,
|
|
112
|
+
): number
|
|
113
|
+
/**
|
|
114
|
+
* Compile a single shader stage from raw GLSL ES: the primitive under
|
|
115
|
+
* {@link linkProgram}, GL's own model (a "shader" is one stage; linking
|
|
116
|
+
* stages yields a program). The source is complete - it declares its own
|
|
117
|
+
* `#version 300 es`, precision, varyings and uniforms; nothing is injected.
|
|
118
|
+
* With `header: true` the standard header is prepended explicitly: `#version
|
|
119
|
+
* 300 es`, `precision highp float;`, `uniform vec2 iResolution;`, `uniform
|
|
120
|
+
* float iTime;`, plus `out vec4 fragColor;` for a fragment stage (the same
|
|
121
|
+
* text {@link createPipeline} injects). Do not combine `header` with your
|
|
122
|
+
* own `#version` line. Returns a shader (stage) id in its own id space;
|
|
123
|
+
* compile errors throw here, synchronously, at a call site the app chose.
|
|
124
|
+
* Free with {@link destroyShader}.
|
|
125
|
+
*/
|
|
126
|
+
export function compileShader(
|
|
127
|
+
stage: "vertex" | "fragment",
|
|
128
|
+
source: string,
|
|
129
|
+
opts?: { header?: boolean },
|
|
130
|
+
): number
|
|
131
|
+
/**
|
|
132
|
+
* Link a compiled vertex and fragment stage into a program, returning a
|
|
133
|
+
* program id (its own id space, like buffers - not a texture id). Link
|
|
134
|
+
* errors throw here. The stages remain usable for further links (mix one
|
|
135
|
+
* vertex stage with many fragment stages and vice versa), and may be
|
|
136
|
+
* destroyed right after: a linked program keeps its own compiled copies.
|
|
137
|
+
* Creating targets from the returned handle compiles nothing. Free with
|
|
138
|
+
* {@link destroyProgram}.
|
|
139
|
+
*/
|
|
140
|
+
export function linkProgram(vertexShader: number, fragmentShader: number): number
|
|
141
|
+
/**
|
|
142
|
+
* Destroy a compiled stage by id. Programs linked from it are unaffected.
|
|
143
|
+
*/
|
|
144
|
+
export function destroyShader(id: number): void
|
|
145
|
+
/**
|
|
146
|
+
* Create a render target over a linked program and render it once: the
|
|
147
|
+
* target half of {@link createPipeline}. Returns a texture id exactly like
|
|
148
|
+
* createShader/createPipeline do (drive uniforms via the `params` prop or
|
|
149
|
+
* {@link setShaderParams}, resize with {@link setShaderSize}, destroy with
|
|
150
|
+
* {@link destroyTexture}). Many targets may share one program. A raw-linked
|
|
151
|
+
* program carries its own vertex stage, so the mesh options apply:
|
|
152
|
+
* `attributes`/`buffer` for vertex input (omit for attributeless rendering
|
|
153
|
+
* via gl_VertexID - a fullscreen pass is `vertexCount: 3` with a
|
|
154
|
+
* covering-triangle vertex stage), `topology`, `vertexCount`, `depth`,
|
|
155
|
+
* `clearColor`, all as in {@link createPipeline}.
|
|
156
|
+
*/
|
|
157
|
+
export function createShaderTarget(
|
|
158
|
+
program: number,
|
|
159
|
+
width: number,
|
|
160
|
+
height: number,
|
|
161
|
+
opts?: {
|
|
162
|
+
params?: ShaderParams
|
|
163
|
+
textures?: Record<string, number>
|
|
164
|
+
attributes?: VertexAttribute[]
|
|
165
|
+
buffer?: number
|
|
166
|
+
topology?: Topology
|
|
167
|
+
vertexCount?: number
|
|
168
|
+
depth?: boolean
|
|
169
|
+
depthWrite?: boolean
|
|
170
|
+
blend?: BlendMode
|
|
171
|
+
clearColor?: [number, number, number, number]
|
|
172
|
+
} & SamplerOptions,
|
|
52
173
|
): number
|
|
53
|
-
/**
|
|
54
|
-
|
|
174
|
+
/**
|
|
175
|
+
* Destroy a linked program by id. Targets created from it are unaffected:
|
|
176
|
+
* each holds the program until it is itself destroyed, so either
|
|
177
|
+
* destruction order is safe. The id stops being usable for new targets
|
|
178
|
+
* immediately.
|
|
179
|
+
*/
|
|
180
|
+
export function destroyProgram(id: number): void
|
|
181
|
+
/**
|
|
182
|
+
* Update a shader texture's uniforms by name and re-render it (see
|
|
183
|
+
* {@link ShaderParams} for the value shapes).
|
|
184
|
+
*/
|
|
185
|
+
export function setShaderParams(id: number, params: ShaderParams): void
|
|
55
186
|
/**
|
|
56
187
|
* Rebind a shader texture's sampler2D inputs by uniform name and re-render
|
|
57
188
|
* it with its last-applied params - the sampler analog of
|
|
58
189
|
* {@link setShaderParams}. Bindings not named keep their current source, so
|
|
59
190
|
* a single input can be retargeted (post-process source swap, ping-pong
|
|
60
191
|
* between two data textures) without recompiling the shader. Throws if the
|
|
61
|
-
* shader or a source texture id is unknown, or a
|
|
62
|
-
* shader's own target
|
|
192
|
+
* shader or a source texture id is unknown, or a binding would create a
|
|
193
|
+
* sampling cycle among targets (binding a shader's own target is the
|
|
194
|
+
* shortest case).
|
|
63
195
|
*/
|
|
64
196
|
export function setShaderTextures(id: number, textures: Record<string, number>): void
|
|
65
197
|
/**
|
|
@@ -71,6 +203,17 @@ declare module "flux:gpu" {
|
|
|
71
203
|
export function setShaderSize(id: number, width: number, height: number): void
|
|
72
204
|
|
|
73
205
|
export type Topology = "points" | "lines" | "line-strip" | "triangles" | "triangle-strip"
|
|
206
|
+
/**
|
|
207
|
+
* Blending for a pipeline's own draw. "none" (default) overwrites:
|
|
208
|
+
* overlapping geometry resolves by depth or draw order. "add" accumulates
|
|
209
|
+
* (glBlendFunc(ONE, ONE)): order-independent, so geometry needs no sorting
|
|
210
|
+
* - the additive half of translucency (point splats, glow passes). A
|
|
211
|
+
* depth-tested additive pass usually pairs with `depthWrite: false`; with
|
|
212
|
+
* writes on, unsorted geometry depth-rejects its own later fragments and
|
|
213
|
+
* accumulation becomes draw-order-dependent. That pairing is the app's to
|
|
214
|
+
* state - neither option implies the other.
|
|
215
|
+
*/
|
|
216
|
+
export type BlendMode = "none" | "add"
|
|
74
217
|
/**
|
|
75
218
|
* One float attribute of an interleaved vertex. The attribute list's order
|
|
76
219
|
* defines the byte layout; locations are resolved by name against the
|
|
@@ -86,8 +229,13 @@ declare module "flux:gpu" {
|
|
|
86
229
|
* `buffer` (a {@link createBuffer} id); omit both for attributeless
|
|
87
230
|
* rendering via gl_VertexID. `vertexCount` defaults to the whole buffer
|
|
88
231
|
* (buffer size / vertex stride). With `depth: true` the pipeline gets a
|
|
89
|
-
* private depth buffer, cleared and tested on every render
|
|
90
|
-
*
|
|
232
|
+
* private depth buffer, cleared and tested on every render; `depthWrite:
|
|
233
|
+
* false` (requires `depth: true`) keeps the test but stops the draw from
|
|
234
|
+
* writing depth. `blend` sets the draw's own blending (see
|
|
235
|
+
* {@link BlendMode}); an additive pass over a depth buffer is
|
|
236
|
+
* `{ depth: true, blend: "add", depthWrite: false }`, stated explicitly.
|
|
237
|
+
* The target is cleared to `clearColor` (default transparent black) before
|
|
238
|
+
* each draw.
|
|
91
239
|
* Returns a texture id: display it with `<texture src>`, drive uniforms via
|
|
92
240
|
* the `params` prop or {@link setShaderParams}, destroy with
|
|
93
241
|
* {@link destroyTexture}.
|
|
@@ -98,15 +246,17 @@ declare module "flux:gpu" {
|
|
|
98
246
|
width: number,
|
|
99
247
|
height: number,
|
|
100
248
|
opts?: {
|
|
101
|
-
params?:
|
|
249
|
+
params?: ShaderParams
|
|
102
250
|
textures?: Record<string, number>
|
|
103
251
|
attributes?: VertexAttribute[]
|
|
104
252
|
buffer?: number
|
|
105
253
|
topology?: Topology
|
|
106
254
|
vertexCount?: number
|
|
107
255
|
depth?: boolean
|
|
256
|
+
depthWrite?: boolean
|
|
257
|
+
blend?: BlendMode
|
|
108
258
|
clearColor?: [number, number, number, number]
|
|
109
|
-
},
|
|
259
|
+
} & SamplerOptions,
|
|
110
260
|
): number
|
|
111
261
|
|
|
112
262
|
/**
|
|
@@ -131,12 +281,34 @@ declare module "flux:gpu" {
|
|
|
131
281
|
/**
|
|
132
282
|
* Capture a render-tree node's subtree into a new GPU texture, resolving once
|
|
133
283
|
* it has been rendered on the next paint pass. The node must be attached to
|
|
134
|
-
* the live tree (
|
|
284
|
+
* the live tree (an unmounted node is never painted, so its capture rejects)
|
|
285
|
+
* and paint a non-zero box. A laid-out node captures its layout box. A `d-*`
|
|
286
|
+
* node has no layout box - that is what detached means - so it captures its
|
|
287
|
+
* painted box instead: its own `w`/`h` when set, else the nearest laid-out
|
|
288
|
+
* ancestor's box (the same box the render tree reports for it), with its
|
|
289
|
+
* `x`/`y` paint offset mapped to the texture origin.
|
|
135
290
|
* Rendered at the current display scale, so `width`/`height` are the texture's
|
|
136
291
|
* actual pixel dimensions (ceil(logicalSize * displayScale)), not logical
|
|
137
292
|
* points. Each call returns an independent id you must {@link destroyTexture}
|
|
138
293
|
* when done. Use the returned id anywhere a texture id is accepted
|
|
139
294
|
* (`<texture src>`, a shader sampler input, {@link readTexture}).
|
|
295
|
+
*
|
|
296
|
+
* Intended for one-shot bakes and inspection: turning something the engine
|
|
297
|
+
* can draw but the app cannot compute - shaped text, an SVG, a themed view -
|
|
298
|
+
* into pixels, usually to hand to {@link readTexture} and process on the CPU.
|
|
299
|
+
* Baking a glyph atlas by laying out cells, capturing them and keeping the
|
|
300
|
+
* coverage channel is the worked example. Tests and freeze-frames are the
|
|
301
|
+
* same shape.
|
|
302
|
+
*
|
|
303
|
+
* Not a rendering primitive. Every call rasterizes the subtree into a fresh
|
|
304
|
+
* offscreen MSAA target, reads the pixels back to the CPU and uploads them
|
|
305
|
+
* again as a new texture: a full GPU -> CPU -> GPU round trip plus a paint
|
|
306
|
+
* pass of latency, per call, with nothing incremental about it. Batch what
|
|
307
|
+
* you capture (many nodes captured together are serviced by one paint pass),
|
|
308
|
+
* and do not drive it per frame or reach for it to feed live content into a
|
|
309
|
+
* shader - an effect over what is beneath it, a backdrop filter. Content that
|
|
310
|
+
* must stay current has to come from a source that updates in place: another
|
|
311
|
+
* pipeline's render target, a camera texture, a mutable texture.
|
|
140
312
|
*/
|
|
141
313
|
export function captureSnapshot(nodeId: number): Promise<{ id: number; width: number; height: number }>
|
|
142
314
|
/**
|