@frapx/core 0.8.0 → 0.9.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/CHANGELOG.md +7 -0
- package/dist/index.d.ts +39 -6
- package/dist/index.js +93 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0 - 2026-10-31
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- 3D data textures: a texture input `{ data, size: [nx, ny, nz], format: "r8" | "r16f" | "r32f", filter?, wrap? }` uploads a single-channel `TEXTURE_3D` (WebGL2 only; a WebGL1 context fails with `TextureLoadError`). `data` is x-fastest; its array type and length are checked against `format` and `size`. `u_<name>Size` is a vec3 for these (`getTextureSizeUniform()`). `r32f` falls back to nearest filtering without `OES_texture_float_linear` and reports it through the new `createTextureSet(inputs, { warn })` option. New types `DataTextureFormat`, `DataTextureOptions`, `TextureSetOptions`, `TextureWarn`.
|
|
8
|
+
- `LoadedTexture` has `target` (`TEXTURE_2D` or `TEXTURE_3D`) and `depth` (`null` for 2D).
|
|
9
|
+
|
|
3
10
|
## 0.8.0 - 2026-10-30
|
|
4
11
|
|
|
5
12
|
### Changed
|
package/dist/index.d.ts
CHANGED
|
@@ -27,7 +27,28 @@ type TextureOptions = {
|
|
|
27
27
|
filter?: "nearest" | "linear";
|
|
28
28
|
flipY?: boolean;
|
|
29
29
|
};
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Storage format of a 3D data texture: one channel, read as `.r`. `r16f` data
|
|
32
|
+
* holds half-float bits in a `Uint16Array`.
|
|
33
|
+
*/
|
|
34
|
+
type DataTextureFormat = "r8" | "r16f" | "r32f";
|
|
35
|
+
/**
|
|
36
|
+
* A 3D texture uploaded from raw data, sampled as `sampler3D`. WebGL2 only.
|
|
37
|
+
* `data` is x-fastest (`[z][y][x]`) and holds `nx * ny * nz` values:
|
|
38
|
+
* `Uint8Array` for `r8`, `Uint16Array` for `r16f`, `Float32Array` for `r32f`.
|
|
39
|
+
* `u_<name>Size` is a vec3 `[nx, ny, nz]`. `r32f` is sampled with nearest
|
|
40
|
+
* filtering unless `OES_texture_float_linear` is available.
|
|
41
|
+
*/
|
|
42
|
+
type DataTextureOptions = {
|
|
43
|
+
data: Uint8Array | Uint16Array | Float32Array;
|
|
44
|
+
size: readonly [number, number, number];
|
|
45
|
+
format: DataTextureFormat;
|
|
46
|
+
/** Defaults to `"linear"`. */
|
|
47
|
+
filter?: "nearest" | "linear";
|
|
48
|
+
/** Defaults to `"clamp"`. */
|
|
49
|
+
wrap?: "clamp" | "repeat" | "mirror";
|
|
50
|
+
};
|
|
51
|
+
type TextureInput = TextureSource | TextureOptions | DataTextureOptions;
|
|
31
52
|
type TextureMap = Record<string, TextureInput>;
|
|
32
53
|
type UniformScalar = number;
|
|
33
54
|
type UniformVec2 = [number, number] | readonly [number, number];
|
|
@@ -386,10 +407,18 @@ type LoadedTexture = {
|
|
|
386
407
|
uniformName: string;
|
|
387
408
|
sizeUniformName: string;
|
|
388
409
|
texture: WebGLTexture;
|
|
410
|
+
/** `TEXTURE_2D` for images, `TEXTURE_3D` for data textures. */
|
|
411
|
+
target: number;
|
|
389
412
|
width: number;
|
|
390
413
|
height: number;
|
|
414
|
+
/** Depth of a 3D data texture; `null` for 2D textures. */
|
|
415
|
+
depth: number | null;
|
|
391
416
|
};
|
|
392
|
-
|
|
417
|
+
/** Called with a message when a texture is loaded differently than asked. */
|
|
418
|
+
type TextureWarn = (message: string) => void;
|
|
419
|
+
declare const loadTexture: (gl: GLContext, name: string, input: TextureInput, unit: number, warn?: TextureWarn) => Promise<LoadedTexture>;
|
|
420
|
+
/** The `u_<name>Size` uniform: vec2 for 2D textures, vec3 for 3D ones. */
|
|
421
|
+
declare const getTextureSizeUniform: (texture: LoadedTexture) => NormalizedUniform;
|
|
393
422
|
|
|
394
423
|
type TextureSet = {
|
|
395
424
|
/** The textures loaded so far, by name. */
|
|
@@ -422,11 +451,15 @@ type TextureSet = {
|
|
|
422
451
|
/** Deletes every loaded texture. */
|
|
423
452
|
dispose(gl: GLContext): void;
|
|
424
453
|
};
|
|
454
|
+
type TextureSetOptions = {
|
|
455
|
+
/** Receives warnings about textures loaded differently than asked. */
|
|
456
|
+
warn?: TextureWarn;
|
|
457
|
+
};
|
|
425
458
|
/**
|
|
426
|
-
* Tracks named image textures and the texture units they occupy, for
|
|
427
|
-
* runtime that binds them to one or more programs.
|
|
459
|
+
* Tracks named image and data textures and the texture units they occupy, for
|
|
460
|
+
* a runtime that binds them to one or more programs.
|
|
428
461
|
*/
|
|
429
|
-
declare const createTextureSet: (inputs?: TextureMap) => TextureSet;
|
|
462
|
+
declare const createTextureSet: (inputs?: TextureMap, options?: TextureSetOptions) => TextureSet;
|
|
430
463
|
|
|
431
464
|
type FullscreenProgram = {
|
|
432
465
|
readonly program: WebGLProgram;
|
|
@@ -497,4 +530,4 @@ declare const createRenderTarget: (gl: GLContext, width: number, height: number,
|
|
|
497
530
|
*/
|
|
498
531
|
declare const createPingPong: (gl: GLContext, width: number, height: number, options?: RenderTargetOptions) => PingPong;
|
|
499
532
|
|
|
500
|
-
export { type Blitter, type CaptureFormat, type CaptureOptions, type CaptureResult, type ClockMode, DestroyedError, type DomSetup, type DprOption, type Ease, type ExplicitUniformInput, type FullscreenProgram, type GLContext, type HostFrameState, type HostPointer, type Keyframe, type KeyframeOptions, type KeyframeTrack, type KeyframeValue, type LoadedTexture, type NormalizedUniform, type PingPong, type RenderMode, type RenderTarget, type RenderTargetFormat, type RenderTargetOptions, type Resolution, type RuntimeHostInstance, type RuntimeHostOptions, type SetupCanvasOptions, ShaderCompileError, ShaderError, type ShaderErrorLine, type ShaderLayer, type ShaderStage, type ShaderStatus, TargetNotFoundError, type TextureInput, TextureLoadError, type TextureMap, type TextureOptions, type TextureSet, type TextureSource, type TimeSource, type UniformBindings, type UniformInput, type UniformInputMap, type UniformRuntimeValue, type UniformScalar, type UniformSource, type UniformType, type UniformVec2, type UniformVec3, type UniformVec4, UnsupportedError, applyProgramUniform, applyUniform, applyUniforms, collectUniformLocations, createBlitter, createFullscreenBuffer, createFullscreenProgram, createPingPong, createProgram, createRenderTarget, createRuntimeHost, createTextureSet, createUniformBindings, createUniformCache, defaultVertexShader, defaultVertexShader300, fromUniformName, isGLSL300, isWebGL2Context, keyframes, loadTexture, normalizeUniform, parseShaderLog, resizeCanvasToTarget, resolveDpr, resolveElement, resolveRenderTargetFormat, setupCanvas, supportsRenderTargetFormat, toUniformName, waitForGpu };
|
|
533
|
+
export { type Blitter, type CaptureFormat, type CaptureOptions, type CaptureResult, type ClockMode, type DataTextureFormat, type DataTextureOptions, DestroyedError, type DomSetup, type DprOption, type Ease, type ExplicitUniformInput, type FullscreenProgram, type GLContext, type HostFrameState, type HostPointer, type Keyframe, type KeyframeOptions, type KeyframeTrack, type KeyframeValue, type LoadedTexture, type NormalizedUniform, type PingPong, type RenderMode, type RenderTarget, type RenderTargetFormat, type RenderTargetOptions, type Resolution, type RuntimeHostInstance, type RuntimeHostOptions, type SetupCanvasOptions, ShaderCompileError, ShaderError, type ShaderErrorLine, type ShaderLayer, type ShaderStage, type ShaderStatus, TargetNotFoundError, type TextureInput, TextureLoadError, type TextureMap, type TextureOptions, type TextureSet, type TextureSetOptions, type TextureSource, type TextureWarn, type TimeSource, type UniformBindings, type UniformInput, type UniformInputMap, type UniformRuntimeValue, type UniformScalar, type UniformSource, type UniformType, type UniformVec2, type UniformVec3, type UniformVec4, UnsupportedError, applyProgramUniform, applyUniform, applyUniforms, collectUniformLocations, createBlitter, createFullscreenBuffer, createFullscreenProgram, createPingPong, createProgram, createRenderTarget, createRuntimeHost, createTextureSet, createUniformBindings, createUniformCache, defaultVertexShader, defaultVertexShader300, fromUniformName, getTextureSizeUniform, isGLSL300, isWebGL2Context, keyframes, loadTexture, normalizeUniform, parseShaderLog, resizeCanvasToTarget, resolveDpr, resolveElement, resolveRenderTargetFormat, setupCanvas, supportsRenderTargetFormat, toUniformName, waitForGpu };
|
package/dist/index.js
CHANGED
|
@@ -1220,7 +1220,10 @@ var keyframes = (tracks, options = {}) => {
|
|
|
1220
1220
|
};
|
|
1221
1221
|
|
|
1222
1222
|
// src/internal/textures.ts
|
|
1223
|
-
var loadTexture = async (gl, name, input, unit) => {
|
|
1223
|
+
var loadTexture = async (gl, name, input, unit, warn) => {
|
|
1224
|
+
if (isDataTextureOptions(input)) {
|
|
1225
|
+
return loadDataTexture(gl, name, input, unit, warn);
|
|
1226
|
+
}
|
|
1224
1227
|
const options = normalizeTextureInput(input);
|
|
1225
1228
|
const source = await resolveSource(options.source);
|
|
1226
1229
|
const texture = gl.createTexture();
|
|
@@ -1242,10 +1245,93 @@ var loadTexture = async (gl, name, input, unit) => {
|
|
|
1242
1245
|
uniformName: toUniformName(name),
|
|
1243
1246
|
sizeUniformName: toUniformName(`${name}Size`),
|
|
1244
1247
|
texture,
|
|
1248
|
+
target: gl.TEXTURE_2D,
|
|
1245
1249
|
width: getSourceWidth(source),
|
|
1246
|
-
height: getSourceHeight(source)
|
|
1250
|
+
height: getSourceHeight(source),
|
|
1251
|
+
depth: null
|
|
1252
|
+
};
|
|
1253
|
+
};
|
|
1254
|
+
var getTextureSizeUniform = (texture) => texture.depth === null ? { type: "vec2", value: [texture.width, texture.height] } : { type: "vec3", value: [texture.width, texture.height, texture.depth] };
|
|
1255
|
+
var DATA_FORMATS = {
|
|
1256
|
+
r8: {
|
|
1257
|
+
array: "Uint8Array",
|
|
1258
|
+
matches: (data) => data instanceof Uint8Array,
|
|
1259
|
+
upload: (gl) => ({ internal: gl.R8, type: gl.UNSIGNED_BYTE })
|
|
1260
|
+
},
|
|
1261
|
+
r16f: {
|
|
1262
|
+
array: "Uint16Array",
|
|
1263
|
+
matches: (data) => data instanceof Uint16Array,
|
|
1264
|
+
upload: (gl) => ({ internal: gl.R16F, type: gl.HALF_FLOAT })
|
|
1265
|
+
},
|
|
1266
|
+
r32f: {
|
|
1267
|
+
array: "Float32Array",
|
|
1268
|
+
matches: (data) => data instanceof Float32Array,
|
|
1269
|
+
upload: (gl) => ({ internal: gl.R32F, type: gl.FLOAT })
|
|
1270
|
+
}
|
|
1271
|
+
};
|
|
1272
|
+
var loadDataTexture = (gl, name, options, unit, warn) => {
|
|
1273
|
+
if (!isWebGL2Context(gl)) {
|
|
1274
|
+
throw new TextureLoadError(`3D textures need WebGL2: ${name}`);
|
|
1275
|
+
}
|
|
1276
|
+
const format = DATA_FORMATS[options.format];
|
|
1277
|
+
if (!format) {
|
|
1278
|
+
throw new TextureLoadError(
|
|
1279
|
+
`Unknown data texture format "${String(options.format)}": ${name}`
|
|
1280
|
+
);
|
|
1281
|
+
}
|
|
1282
|
+
const [nx, ny, nz] = options.size;
|
|
1283
|
+
if (![nx, ny, nz].every((n) => Number.isInteger(n) && n > 0)) {
|
|
1284
|
+
throw new TextureLoadError(
|
|
1285
|
+
`Data texture size must be three positive integers, got [${options.size.join(", ")}]: ${name}`
|
|
1286
|
+
);
|
|
1287
|
+
}
|
|
1288
|
+
if (!format.matches(options.data)) {
|
|
1289
|
+
throw new TextureLoadError(
|
|
1290
|
+
`Data texture format "${options.format}" needs a ${format.array}: ${name}`
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
if (options.data.length !== nx * ny * nz) {
|
|
1294
|
+
throw new TextureLoadError(
|
|
1295
|
+
`Data texture has ${options.data.length} values, size [${nx}, ${ny}, ${nz}] needs ${nx * ny * nz}: ${name}`
|
|
1296
|
+
);
|
|
1297
|
+
}
|
|
1298
|
+
let filterName = options.filter ?? "linear";
|
|
1299
|
+
if (options.format === "r32f" && filterName === "linear" && gl.getExtension("OES_texture_float_linear") === null) {
|
|
1300
|
+
filterName = "nearest";
|
|
1301
|
+
warn?.(
|
|
1302
|
+
`r32f texture "${name}" is sampled with nearest filtering: OES_texture_float_linear is unavailable.`
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
const texture = gl.createTexture();
|
|
1306
|
+
if (!texture) {
|
|
1307
|
+
throw new TextureLoadError(`Failed to create texture: ${name}`);
|
|
1308
|
+
}
|
|
1309
|
+
const { internal, type } = format.upload(gl);
|
|
1310
|
+
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
1311
|
+
gl.bindTexture(gl.TEXTURE_3D, texture);
|
|
1312
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
1313
|
+
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
|
1314
|
+
gl.texImage3D(gl.TEXTURE_3D, 0, internal, nx, ny, nz, 0, gl.RED, type, options.data);
|
|
1315
|
+
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
|
|
1316
|
+
const wrap = getWrap(gl, options.wrap ?? "clamp");
|
|
1317
|
+
const filter = getFilter(gl, filterName);
|
|
1318
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, wrap);
|
|
1319
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, wrap);
|
|
1320
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, wrap);
|
|
1321
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, filter);
|
|
1322
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, filter);
|
|
1323
|
+
return {
|
|
1324
|
+
name,
|
|
1325
|
+
uniformName: toUniformName(name),
|
|
1326
|
+
sizeUniformName: toUniformName(`${name}Size`),
|
|
1327
|
+
texture,
|
|
1328
|
+
target: gl.TEXTURE_3D,
|
|
1329
|
+
width: nx,
|
|
1330
|
+
height: ny,
|
|
1331
|
+
depth: nz
|
|
1247
1332
|
};
|
|
1248
1333
|
};
|
|
1334
|
+
var isDataTextureOptions = (input) => typeof input === "object" && "data" in input;
|
|
1249
1335
|
var normalizeTextureInput = (input) => {
|
|
1250
1336
|
if (typeof input === "string" || isTextureSource(input)) {
|
|
1251
1337
|
return { source: input };
|
|
@@ -1277,7 +1363,7 @@ var getSourceWidth = (source) => "naturalWidth" in source ? source.naturalWidth
|
|
|
1277
1363
|
var getSourceHeight = (source) => "naturalHeight" in source ? source.naturalHeight : source.height;
|
|
1278
1364
|
|
|
1279
1365
|
// src/internal/textureSet.ts
|
|
1280
|
-
var createTextureSet = (inputs = {}) => {
|
|
1366
|
+
var createTextureSet = (inputs = {}, options = {}) => {
|
|
1281
1367
|
const textureInputs = new Map(Object.entries(inputs));
|
|
1282
1368
|
let textures = /* @__PURE__ */ new Map();
|
|
1283
1369
|
const units = /* @__PURE__ */ new Map();
|
|
@@ -1310,7 +1396,7 @@ var createTextureSet = (inputs = {}) => {
|
|
|
1310
1396
|
for (const [name, input] of textureInputs) {
|
|
1311
1397
|
if (isCancelled()) break;
|
|
1312
1398
|
const unit = reserveUnit(gl, name);
|
|
1313
|
-
loaded.set(name, await loadTexture(gl, name, input, unit));
|
|
1399
|
+
loaded.set(name, await loadTexture(gl, name, input, unit, options.warn));
|
|
1314
1400
|
}
|
|
1315
1401
|
for (const texture of textures.values()) {
|
|
1316
1402
|
gl.deleteTexture(texture.texture);
|
|
@@ -1322,7 +1408,7 @@ var createTextureSet = (inputs = {}) => {
|
|
|
1322
1408
|
versions.set(name, version);
|
|
1323
1409
|
try {
|
|
1324
1410
|
const unit = reserveUnit(gl, name);
|
|
1325
|
-
const loaded = await loadTexture(gl, name, input, unit);
|
|
1411
|
+
const loaded = await loadTexture(gl, name, input, unit, options.warn);
|
|
1326
1412
|
if (isCancelled() || versions.get(name) !== version) {
|
|
1327
1413
|
gl.deleteTexture(loaded.texture);
|
|
1328
1414
|
return null;
|
|
@@ -1349,7 +1435,7 @@ var createTextureSet = (inputs = {}) => {
|
|
|
1349
1435
|
continue;
|
|
1350
1436
|
}
|
|
1351
1437
|
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
1352
|
-
gl.bindTexture(
|
|
1438
|
+
gl.bindTexture(texture.target, texture.texture);
|
|
1353
1439
|
gl.uniform1i(location, unit);
|
|
1354
1440
|
}
|
|
1355
1441
|
},
|
|
@@ -1633,6 +1719,7 @@ export {
|
|
|
1633
1719
|
defaultVertexShader,
|
|
1634
1720
|
defaultVertexShader300,
|
|
1635
1721
|
fromUniformName,
|
|
1722
|
+
getTextureSizeUniform,
|
|
1636
1723
|
glsl,
|
|
1637
1724
|
glslUtils,
|
|
1638
1725
|
hexToRgb,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/errors.ts","../src/internal/shaderLog.ts","../src/internal/webgl.ts","../src/internal/capture.ts","../src/internal/dom.ts","../src/host.ts","../src/internal/names.ts","../src/internal/uniforms.ts","../src/internal/bindings.ts","../src/internal/textures.ts","../src/internal/textureSet.ts","../src/internal/fullscreenProgram.ts","../src/internal/blit.ts","../src/internal/renderTarget.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** One line of a shader compile error, located in the source that was compiled. */\nexport type ShaderErrorLine = {\n /** 1-based line in the compiled source (after `glsl` template interpolation). */\n line: number;\n message: string;\n /** That line of the source, or \"\" when the log points past the end. */\n source: string;\n /** Up to two lines either side, with their numbers, the error line included. */\n context: ReadonlyArray<{ line: number; source: string }>;\n};\n\n/** `\"link\"` for program link errors, which carry no line numbers. */\nexport type ShaderStage = \"vertex\" | \"fragment\" | \"link\";\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {\n /** The stage that failed, or `null` for errors not tied to compiling a shader. */\n readonly stage: ShaderStage | null;\n /** Errors located in the source, parsed from the driver's info log. Empty when it had none. */\n readonly lines: readonly ShaderErrorLine[];\n\n constructor(\n message: string,\n details: { stage?: ShaderStage; lines?: readonly ShaderErrorLine[] } = {}\n ) {\n super(message);\n this.stage = details.stage ?? null;\n this.lines = details.lines ?? [];\n }\n}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { ShaderErrorLine } from \"./errors\";\n\n// Browsers translate shaders through ANGLE: \"ERROR: 0:12: 'x' : undeclared identifier\".\nconst ANGLE_STYLE = /^\\s*ERROR:\\s*\\d+:(\\d+):\\s*(.*)$/;\n// Native NVIDIA-style drivers: \"0(12) : error C1008: undefined variable\".\nconst NVIDIA_STYLE = /^\\s*\\d+\\((\\d+)\\)\\s*:\\s*error\\s*\\w*\\s*:\\s*(.*)$/i;\n// Follow-up noise after the real error.\nconst NOISE = /compilation terminated|^\\s*''\\s*:\\s*$/i;\n\nconst CONTEXT_LINES = 2;\n\n/**\n * Finds the errors in a shader info log and attaches the source lines they\n * point at. Lines the log does not locate are left out; the log itself stays\n * the error message.\n */\nexport const parseShaderLog = (log: string, source: string): ShaderErrorLine[] => {\n const sourceLines = source.split(/\\r?\\n/);\n const lineAt = (line: number) => sourceLines[line - 1] ?? \"\";\n const results: ShaderErrorLine[] = [];\n const seen = new Set<string>();\n\n for (const entry of log.split(/\\r?\\n/)) {\n const match = ANGLE_STYLE.exec(entry) ?? NVIDIA_STYLE.exec(entry);\n if (!match) continue;\n const line = Number(match[1]);\n const message = match[2]!.trim();\n if (!message || NOISE.test(message)) continue;\n const key = `${line}:${message}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const context: Array<{ line: number; source: string }> = [];\n const first = Math.max(1, line - CONTEXT_LINES);\n const last = Math.min(sourceLines.length, line + CONTEXT_LINES);\n for (let current = first; current <= last; current++) {\n context.push({ line: current, source: lineAt(current) });\n }\n results.push({ line, message, source: lineAt(line), context });\n }\n return results;\n};\n","import type { GLContext } from \"../types\";\nimport { ShaderCompileError } from \"./errors\";\nimport { parseShaderLog } from \"./shaderLog\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const defaultVertexShader300 = `#version 300 es\nin vec2 a_position;\nout vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const isGLSL300 = (src: string): boolean =>\n /^\\s*#version\\s+300\\s+es\\b/.test(src);\n\n// Duck-typed instead of `instanceof WebGL2RenderingContext` so this also works\n// against test mocks and other environments where the global constructor may\n// be unavailable.\nexport const isWebGL2Context = (gl: GLContext): gl is WebGL2RenderingContext =>\n typeof (gl as WebGL2RenderingContext).createVertexArray === \"function\";\n\nexport const createProgram = (\n gl: GLContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n let fragment: WebGLShader;\n try {\n fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n } catch (error) {\n gl.deleteShader(vertex);\n throw error;\n }\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log, { stage: \"link\" });\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: GLContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: GLContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log, {\n stage: type === gl.VERTEX_SHADER ? \"vertex\" : \"fragment\",\n lines: parseShaderLog(log, source)\n });\n }\n\n return shader;\n};\n","import type { GLContext } from \"../types\";\nimport { isWebGL2Context } from \"./webgl\";\n\n/**\n * Resolves once the GPU has finished every command submitted so far, polling\n * a fence between tasks. Waiting between heavy draws keeps each submission\n * short, so a long render never trips the browser's GPU watchdog and loses\n * the context. Resolves immediately on WebGL1.\n */\nexport const waitForGpu = (gl: GLContext): Promise<void> => {\n if (!isWebGL2Context(gl)) return Promise.resolve();\n const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);\n if (!sync) return Promise.resolve();\n gl.flush();\n return new Promise((resolve) => {\n const poll = () => {\n const status = gl.clientWaitSync(sync, 0, 0);\n if (status === gl.TIMEOUT_EXPIRED) {\n setTimeout(poll, 4);\n return;\n }\n gl.deleteSync(sync);\n resolve();\n };\n poll();\n });\n};\n\n/**\n * Reads RGBA pixels from `framebuffer` (or the drawing buffer when `null`) and\n * returns them top row first. Must run in the same task as the draw when\n * reading the drawing buffer, since it is not preserved.\n */\nexport const readPixels = <T extends \"rgba8\" | \"rgba16f\">(\n gl: GLContext,\n framebuffer: WebGLFramebuffer | null,\n width: number,\n height: number,\n format: T\n): T extends \"rgba16f\" ? Float32Array : Uint8Array => {\n const length = width * height * 4;\n const data =\n format === \"rgba16f\" ? new Float32Array(length) : new Uint8Array(length);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n // RGBA/FLOAT is the read combination EXT_color_buffer_float guarantees.\n gl.readPixels(\n 0,\n 0,\n width,\n height,\n gl.RGBA,\n format === \"rgba16f\" ? gl.FLOAT : gl.UNSIGNED_BYTE,\n data\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n flipRows(data, width * 4, height);\n return data as T extends \"rgba16f\" ? Float32Array : Uint8Array;\n};\n\n/** Encodes the canvas as PNG. The snapshot is taken synchronously. */\nexport const canvasToPng = (canvas: HTMLCanvasElement): Promise<Blob> =>\n new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error(\"Failed to encode the canvas as PNG.\"));\n }, \"image/png\");\n });\n\n// WebGL reads bottom-up; captures are top row first like images.\nconst flipRows = (\n data: Uint8Array | Float32Array,\n rowLength: number,\n rows: number\n): void => {\n const temp = data.slice(0, rowLength);\n for (let top = 0, bottom = rows - 1; top < bottom; top++, bottom--) {\n const topStart = top * rowLength;\n const bottomStart = bottom * rowLength;\n temp.set(data.subarray(topStart, topStart + rowLength));\n data.copyWithin(topStart, bottomStart, bottomStart + rowLength);\n data.set(temp, bottomStart);\n }\n};\n","import type { DprOption, Resolution, SetupCanvasOptions } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n /** True when the canvas was created without being attached to the document. */\n detached?: boolean;\n};\n\nexport type CanvasSize = {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (options: SetupCanvasOptions): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) {\n if (!options.detached) return null;\n canvas.dataset.frapxCanvas = \"\";\n return {\n target: canvas,\n canvas,\n createdCanvas: true,\n restoredPosition: null,\n detached: true\n };\n }\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\n/**\n * `\"auto\"` follows `devicePixelRatio`, capped by `maxDpr` (default 2). A\n * number or function is used as given and capped only when `maxDpr` is set.\n * Values below 1 are allowed; `<= 0` or non-finite throws `RangeError`.\n */\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n if (dpr === undefined || dpr === \"auto\") {\n const device =\n typeof window === \"undefined\" ? 1 : window.devicePixelRatio || 1;\n return Math.min(device, assertPositive(\"maxDpr\", maxDpr ?? 2));\n }\n\n const raw = assertPositive(\"dpr\", typeof dpr === \"function\" ? dpr() : dpr);\n return maxDpr === undefined ? raw : Math.min(raw, assertPositive(\"maxDpr\", maxDpr));\n};\n\n/** Checks the static parts of the dpr options; a `dpr` function is checked when it is called. */\nexport const assertDprOptions = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): void => {\n if (typeof dpr === \"number\") assertPositive(\"dpr\", dpr);\n if (maxDpr !== undefined) assertPositive(\"maxDpr\", maxDpr);\n};\n\nconst assertPositive = (name: string, value: number): number => {\n if (!Number.isFinite(value) || value <= 0) {\n throw new RangeError(`\\`${name}\\` must be a finite number above 0, got ${value}`);\n }\n return value;\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): CanvasSize => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\n/**\n * Sizes the canvas to a fixed internal resolution. The viewport size still\n * comes from the target so `u_viewportSize` reflects the displayed size; a\n * detached canvas has no layout, so its viewport equals the resolution.\n */\nexport const resizeCanvasToResolution = (\n canvas: HTMLCanvasElement,\n target: Element | null,\n resolution: Resolution\n): CanvasSize => {\n const [width, height] = resolution;\n let viewportWidth = width;\n let viewportHeight = height;\n\n if (target) {\n const rect = target.getBoundingClientRect();\n viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n }\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: SetupCanvasOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","import type {\n CaptureFormat,\n CaptureOptions,\n CaptureResult,\n ClockMode,\n GLContext,\n HostFrameState,\n HostPointer,\n Resolution,\n RuntimeHostInstance,\n RuntimeHostOptions,\n ShaderStatus,\n TimeSource\n} from \"./types\";\nimport { DestroyedError, TargetNotFoundError, UnsupportedError } from \"./internal/errors\";\nimport { canvasToPng, readPixels } from \"./internal/capture\";\nimport {\n assertDprOptions,\n resolveDpr,\n resizeCanvasToResolution,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\n// Manual clocks report a neutral pointer so output never depends on input.\nconst IDLE_POINTER: HostPointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n\nconst clampDelta = (delta: number): number =>\n Math.min(Math.max(delta, 0), MAX_DELTA_SECONDS);\n\ntype Gate = \"offscreen\" | \"hidden\" | \"reducedMotion\";\n\nexport const createRuntimeHost = (\n options: RuntimeHostOptions\n): RuntimeHostInstance => {\n return new RuntimeHost(options);\n};\n\nclass RuntimeHost implements RuntimeHostInstance {\n readonly ready: Promise<void>;\n\n private readonly options: RuntimeHostOptions;\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private context: GLContext | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private captureDrawing = false;\n private resizePending = false;\n private destroyed = false;\n private gates = new Set<Gate>();\n private reducedMotionActive = false;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n private statusBeforeLoss: ShaderStatus = \"idle\";\n private clockMode: ClockMode;\n private manualDelta = 0;\n private lastManualTime: number | null = null;\n private source: TimeSource | null;\n // The source's value at the previous loop frame; null restarts u_delta at 0.\n private lastSourceTime: number | null = null;\n private fixedResolution: Resolution | null;\n private objectFitRestore: string | null = null;\n // Letterbox offset (CSS px) of the contained canvas content inside the target.\n private contentOffsetX = 0;\n private contentOffsetY = 0;\n\n constructor(options: RuntimeHostOptions) {\n this.options = options;\n this.clockMode = options.clock ?? \"realtime\";\n this.source = options.timeSource ?? null;\n this.warnIfSourceUnread();\n assertDprOptions(options.dpr, options.maxDpr);\n this.fixedResolution = options.resolution\n ? normalizeResolution(options.resolution)\n : null;\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): GLContext | null {\n return this.context;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n get clock(): ClockMode {\n return this.clockMode;\n }\n\n /**\n * The time of the last frame drawn, before any `accumulation.loop`\n * wrapping: the value `setTime()` would need to reproduce that frame.\n * While gated it is the time the loop stopped at, and with a time source\n * it is the last value read from the source.\n */\n get time(): number {\n return this.elapsed;\n }\n\n get timeSource(): TimeSource | null {\n return this.source;\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n this.reconcile();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.setStatus(\"paused\");\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.context ||\n this.currentStatus === \"unsupported\" ||\n this.inRender\n )\n return;\n\n if (this.isManual) {\n // The caller decides when to draw; visibility gates do not apply.\n this.renderInternal(this.elapsed, this.manualDelta);\n return;\n }\n\n // Redraws at the last frame's time: refinement and reduced motion must\n // not chase a running source.\n if (this.hasVisibilityBlock) return;\n this.renderInternal(this.elapsed, 0);\n }\n\n setTime(seconds: number): void {\n if (!Number.isFinite(seconds)) {\n throw new RangeError(`setTime() expects a finite number, got ${seconds}`);\n }\n if (this.destroyed) return;\n\n if (this.isManual) {\n this.manualDelta =\n this.lastManualTime === null ? 0 : seconds - this.lastManualTime;\n this.lastManualTime = seconds;\n }\n this.elapsed = seconds;\n }\n\n setClock(clock: ClockMode): void {\n if (this.destroyed || clock === this.clockMode) return;\n this.clockMode = clock;\n this.manualDelta = 0;\n this.lastManualTime = null;\n // Gates kept tracking while manual, so this resumes against current state.\n this.reconcile();\n }\n\n setTimeSource(source: TimeSource | null): void {\n if (this.destroyed) return;\n this.source = source;\n this.lastSourceTime = null;\n this.warnIfSourceUnread();\n }\n\n // Only the realtime loop reads the source, and demand mode runs no loop.\n private warnIfSourceUnread(): void {\n if (this.source && this.options.renderMode === \"demand\") {\n this.debugWarn(\"`timeSource` is not read with renderMode \\\"demand\\\", which runs no frame loop. Call setTime() instead.\");\n }\n }\n\n setResolution(resolution: Resolution | null): void {\n if (this.destroyed) return;\n\n if (resolution === null) {\n if (this.isDetached) {\n throw new TypeError(\n \"A canvas without a target needs a fixed resolution.\"\n );\n }\n this.fixedResolution = null;\n } else {\n const next = normalizeResolution(resolution);\n if (this.context) assertWithinLimits(this.context, next);\n this.fixedResolution = next;\n }\n\n this.applyObjectFit();\n this.resize();\n }\n\n async captureFrame<F extends CaptureFormat = \"png\">(\n options: CaptureOptions<F> = {}\n ): Promise<CaptureResult<F>> {\n const format: CaptureFormat = options.format ?? \"png\";\n if (format !== \"png\" && format !== \"rgba8\" && format !== \"rgba16f\") {\n throw new RangeError(`Unknown capture format: ${String(format)}`);\n }\n\n await this.ready;\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n if (!this.dom || !this.context) {\n throw new UnsupportedError(\"Cannot capture without a WebGL context.\");\n }\n if (this.inRender) {\n throw new Error(\"captureFrame() cannot be called while a frame is drawing.\");\n }\n\n // Check before drawing so a rejected capture has no side effects.\n const sourceFormat = this.options.captureSource?.()?.format;\n if (format === \"rgba16f\" && sourceFormat !== \"rgba16f\" && sourceFormat !== \"rgba32f\") {\n throw new UnsupportedError(\n \"rgba16f capture needs a float render target, such as feedback with format rgba16f.\"\n );\n }\n options.signal?.throwIfAborted();\n\n const delta = this.isManual ? this.manualDelta : 0;\n const drawContext = this.context;\n if (!this.options.onCaptureDraw) {\n this.renderInternal(this.elapsed, delta);\n return this.readCapture(format, drawContext);\n }\n\n try {\n await this.renderForCapture(this.options.onCaptureDraw, delta, options.signal);\n return this.readCapture(format, drawContext);\n } finally {\n // Resizes requested while drawing apply once the frame is read.\n if (this.resizePending) {\n this.resizePending = false;\n this.resize();\n }\n }\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n // Keep the size an asynchronous capture draw started with until it is read.\n if (this.captureDrawing) {\n this.resizePending = true;\n return;\n }\n\n this.syncSize();\n\n if (this.shouldRenderOnDemand && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n this.context = null;\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n } else if (this.dom && this.objectFitRestore !== null) {\n this.dom.canvas.style.objectFit = this.objectFitRestore;\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n (dom.target as HTMLElement).style.position = dom.restoredPosition!;\n }\n\n this.setStatus(\"destroyed\");\n this.markReadyHandled();\n this.readyReject?.(new DestroyedError(\"Runtime host was destroyed.\"));\n }\n\n private get isManual(): boolean {\n return this.clockMode === \"manual\";\n }\n\n private get followsSource(): boolean {\n return this.source !== null && !this.isManual;\n }\n\n // A non-finite reading holds the previous time instead of throwing in a frame.\n private readSource(): number | null {\n if (!this.followsSource) return null;\n const now = this.source!();\n return Number.isFinite(now) ? now : null;\n }\n\n // The static frame takes the source's current time without a delta.\n private syncSourceTime(): void {\n const now = this.readSource();\n if (now !== null) this.elapsed = now;\n }\n\n // A loop frame under a source: time is the source's value, never clamped;\n // delta is the step from the previous frame, 0 when it went back.\n private advanceFromSource(): number {\n const now = this.readSource();\n if (now === null) return 0;\n const previous = this.lastSourceTime;\n this.lastSourceTime = now;\n this.elapsed = now;\n return previous === null ? 0 : clampDelta(now - previous);\n }\n\n private get isDetached(): boolean {\n if (this.dom) return this.dom.detached === true;\n return this.options.target === undefined && this.options.canvas === undefined;\n }\n\n // Demand mode re-renders on input changes, except under a manual clock where\n // only explicit render() calls draw.\n private get shouldRenderOnDemand(): boolean {\n return this.options.renderMode === \"demand\" && !this.isManual;\n }\n\n private get hasVisibilityBlock(): boolean {\n return this.gates.has(\"offscreen\") || this.gates.has(\"hidden\");\n }\n\n private get hasMotionBlock(): boolean {\n return (\n this.gates.has(\"reducedMotion\") && this.options.renderMode !== \"demand\"\n );\n }\n\n private setGate(gate: Gate, closed: boolean): void {\n if (closed === this.gates.has(gate)) return;\n if (closed) this.gates.add(gate);\n else this.gates.delete(gate);\n this.reconcile();\n }\n\n // `restoring` lets a restored context leave \"context-lost\" straight to what\n // the gates allow, so the status never passes through a stale value.\n private reconcile(restoring = false): void {\n if (\n this.destroyed ||\n this.currentStatus === \"unsupported\" ||\n this.currentStatus === \"error\" ||\n (this.currentStatus === \"context-lost\" && !restoring)\n ) {\n return;\n }\n\n if (this.isManual) {\n this.cancelFrame();\n this.setStatus(\"paused\");\n return;\n }\n\n if (this.running) {\n if (this.hasVisibilityBlock) {\n this.cancelFrame();\n this.setStatus(\"paused\");\n return;\n }\n\n if (this.hasMotionBlock) {\n this.cancelFrame();\n this.setStatus(\"paused\");\n this.renderStaticFrame();\n return;\n }\n\n this.setStatus(\"running\");\n if (this.options.renderMode === \"demand\") this.render();\n else this.scheduleFrame();\n return;\n }\n\n if (this.options.renderMode === \"demand\") this.render();\n }\n\n private renderStaticFrame(): void {\n if (this.hasVisibilityBlock) return;\n this.syncSourceTime();\n this.renderInternal(this.elapsed, 0);\n }\n\n private renderInternal(time: number, delta: number): void {\n // An asynchronous capture draw holds the lock across tasks.\n if (!this.dom || !this.context || this.inRender) return;\n const gl = this.context;\n\n this.inRender = true;\n try {\n this.syncSize();\n this.options.onDraw(this.createFrameState(time, delta, gl));\n this.frame++;\n } finally {\n this.inRender = false;\n }\n }\n\n // Holds the render lock across an asynchronous capture draw so no other\n // frame interleaves with it.\n private async renderForCapture(\n draw: NonNullable<RuntimeHostOptions[\"onCaptureDraw\"]>,\n delta: number,\n signal: AbortSignal | undefined\n ): Promise<void> {\n if (!this.dom || !this.context) return;\n this.inRender = true;\n this.captureDrawing = true;\n try {\n this.syncSize();\n await draw(this.createFrameState(this.elapsed, delta, this.context), signal);\n this.frame++;\n } finally {\n this.inRender = false;\n this.captureDrawing = false;\n }\n }\n\n // Reads the frame just drawn, in the task that drew it: the drawing buffer\n // is not preserved. Fails if the context drawn into is gone, including when\n // it was lost and restored while an asynchronous draw was pending.\n private readCapture<F extends CaptureFormat>(\n format: CaptureFormat,\n drawContext: GLContext | null\n ): Promise<CaptureResult<F>> | CaptureResult<F> {\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n const gl = this.context;\n if (!gl || gl !== drawContext || !this.dom) {\n throw new UnsupportedError(\"The WebGL context was lost while capturing.\");\n }\n\n if (format === \"png\") {\n return canvasToPng(this.dom.canvas) as Promise<CaptureResult<F>>;\n }\n if (format === \"rgba8\") {\n return readPixels(gl, null, this.width, this.height, \"rgba8\") as CaptureResult<F>;\n }\n const source = this.options.captureSource!()!;\n return readPixels(\n gl,\n source.framebuffer,\n source.width,\n source.height,\n \"rgba16f\"\n ) as CaptureResult<F>;\n }\n\n private createFrameState(\n time: number,\n delta: number,\n gl: GLContext = this.context!\n ): HostFrameState {\n return {\n gl,\n canvas: this.dom!.canvas,\n time,\n delta,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio,\n reducedMotion: this.isManual ? false : this.reducedMotionActive,\n pointer: this.isManual ? { ...IDLE_POINTER } : { ...this.pointer }\n };\n }\n\n /**\n * Measures the size and calls onResize if it changed. Frames measure too:\n * browsers run animation frames before resize observations, so in a running\n * loop a frame is usually the first to see a new size.\n */\n private syncSize(): void {\n const prevWidth = this.width;\n const prevHeight = this.height;\n const prevViewportWidth = this.viewportWidth;\n const prevViewportHeight = this.viewportHeight;\n\n this.measureSize();\n\n const sizeChanged =\n this.width !== prevWidth ||\n this.height !== prevHeight ||\n this.viewportWidth !== prevViewportWidth ||\n this.viewportHeight !== prevViewportHeight;\n\n if (sizeChanged && this.context) {\n this.options.onResize?.(this.createFrameState(this.elapsed, 0));\n }\n }\n\n private measureSize(): void {\n if (!this.dom) return;\n\n if (this.fixedResolution) {\n const size = resizeCanvasToResolution(\n this.dom.canvas,\n this.dom.detached ? null : this.dom.target,\n this.fixedResolution\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n // Internal pixels per displayed CSS pixel under object-fit: contain.\n this.pixelRatio = Math.max(\n size.width / size.viewportWidth,\n size.height / size.viewportHeight\n );\n this.contentOffsetX =\n (size.viewportWidth - size.width / this.pixelRatio) / 2;\n this.contentOffsetY =\n (size.viewportHeight - size.height / this.pixelRatio) / 2;\n return;\n }\n\n this.contentOffsetX = 0;\n this.contentOffsetY = 0;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n }\n\n // Letterbox the fixed-resolution canvas instead of stretching it.\n private applyObjectFit(): void {\n if (!this.dom) return;\n const style = this.dom.canvas.style;\n if (this.fixedResolution && this.objectFitRestore === null) {\n this.objectFitRestore = style.objectFit ?? \"\";\n style.objectFit = \"contain\";\n } else if (!this.fixedResolution && this.objectFitRestore !== null) {\n style.objectFit = this.objectFitRestore;\n this.objectFitRestore = null;\n }\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\" || this.isManual)\n return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n let delta: number;\n if (this.followsSource) {\n delta = this.advanceFromSource();\n } else {\n delta = this.lastTimestamp ? clampDelta(seconds - this.lastTimestamp) : 0;\n this.elapsed += delta;\n }\n this.lastTimestamp = seconds;\n this.renderInternal(this.elapsed, delta);\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n this.lastSourceTime = null;\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas({\n ...(this.options.target !== undefined && { target: this.options.target }),\n ...(this.options.canvas !== undefined && { canvas: this.options.canvas }),\n ...(this.options.layer !== undefined && { layer: this.options.layer }),\n ...(this.options.canvasClass !== undefined && { canvasClass: this.options.canvasClass }),\n ...(this.options.canvasStyle !== undefined && { canvasStyle: this.options.canvasStyle }),\n // Only a missing target/canvas may fall back to a detached canvas; a\n // target that fails to resolve must still report TargetNotFoundError.\n detached:\n this.fixedResolution !== null &&\n this.options.target === undefined &&\n this.options.canvas === undefined\n });\n\n if (!this.dom) {\n this.failUnsupported(\n new TargetNotFoundError(\n \"Target or canvas not found. Pass `resolution` to render without a target.\"\n )\n );\n return;\n }\n\n let gl: GLContext | null;\n try {\n gl = this.options.createContext(this.dom.canvas);\n } catch (error) {\n this.failUnsupported(\n error instanceof UnsupportedError\n ? error\n : new UnsupportedError(String(error))\n );\n return;\n }\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n if (this.fixedResolution) {\n try {\n assertWithinLimits(gl, this.fixedResolution);\n } catch (error) {\n this.failUnsupported(\n error instanceof Error ? error : new UnsupportedError(String(error))\n );\n return;\n }\n if (this.options.dpr !== undefined || this.options.maxDpr !== undefined) {\n this.debugWarn(\"`dpr` and `maxDpr` are ignored while `resolution` is set.\");\n }\n }\n\n this.context = gl;\n this.setStatus(\"loading\");\n // onStatusChange may have destroyed the host.\n if (this.destroyed) return;\n\n try {\n this.applyObjectFit();\n this.setupDomObservers();\n this.setupContextEvents();\n this.measureSize();\n await this.options.onInit(gl, this.width, this.height);\n if (this.destroyed) return;\n this.setStatus(\"ready\");\n if (this.destroyed) return;\n this.readyResolve?.();\n this.options.onReady?.();\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n } catch (error) {\n if (error instanceof UnsupportedError) this.failUnsupported(error);\n else this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n const detached = this.dom.detached === true;\n\n // A detached canvas has no layout: it can never be measured, scrolled into\n // view or pointed at, so only document-level observers apply.\n if (!detached && (this.options.autoResize ?? true)) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (!detached && (this.options.pauseWhenOffscreen ?? true)) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.setGate(\"offscreen\", !entry?.isIntersecting);\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenHidden ?? true) {\n if (document.hidden) this.gates.add(\"hidden\");\n const onVisibility = () => {\n this.setGate(\"hidden\", document.hidden);\n };\n document.addEventListener(\"visibilitychange\", onVisibility);\n this.removeListeners.push(() => {\n document.removeEventListener(\"visibilitychange\", onVisibility);\n });\n }\n\n this.setupMotionObserver();\n\n if (detached) return;\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left - this.contentOffsetX;\n const y = pointerEvent.clientY - rect.top - this.contentOffsetY;\n // Displayed content size in CSS px (smaller than rect when letterboxed).\n const contentWidth = this.fixedResolution\n ? this.width / this.pixelRatio\n : rect.width;\n const contentHeight = this.fixedResolution\n ? this.height / this.pixelRatio\n : rect.height;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (contentHeight - y) * this.pixelRatio;\n this.pointer.uvX = contentWidth > 0 ? x / contentWidth : 0;\n this.pointer.uvY = contentHeight > 0 ? 1 - y / contentHeight : 0;\n this.pointer.active = 1;\n\n if (this.shouldRenderOnDemand) this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.shouldRenderOnDemand) this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupMotionObserver(): void {\n if (typeof window.matchMedia !== \"function\") return;\n\n const query = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n this.reducedMotionActive = query.matches;\n if (this.options.respectReducedMotion && query.matches) {\n this.gates.add(\"reducedMotion\");\n }\n\n const onChange = (event: MediaQueryListEvent) => {\n this.reducedMotionActive = event.matches;\n if (this.options.respectReducedMotion) {\n this.setGate(\"reducedMotion\", event.matches);\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n };\n\n query.addEventListener(\"change\", onChange);\n this.removeListeners.push(() => {\n query.removeEventListener(\"change\", onChange);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.statusBeforeLoss = this.currentStatus;\n this.cancelFrame();\n this.context = null;\n this.setStatus(\"context-lost\");\n if (this.destroyed) return;\n this.options.onContextLost?.();\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.options.createContext(this.dom.canvas);\n if (!gl) return;\n this.context = gl;\n\n const afterRestore = async () => {\n try {\n await this.options.onContextRestored?.(gl, this.width, this.height);\n if (this.destroyed) return;\n if (this.contextRestoredShouldRun) {\n // Gates may have closed during the loss; report only their result.\n this.running = true;\n this.reconcile(true);\n return;\n }\n // A stopped or manual-clock instance would otherwise stay\n // \"context-lost\", and render() would refuse to draw.\n if (this.currentStatus === \"context-lost\") this.setStatus(this.statusBeforeLoss);\n if (!this.isManual) this.render();\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n void afterRestore();\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private failUnsupported(error: Error): void {\n this.setStatus(\"unsupported\");\n this.debugWarn(error.message);\n this.options.onError?.(error);\n // An unsupported environment is expected; a missing target stays loud.\n if (error instanceof UnsupportedError) this.markReadyHandled();\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.setStatus(\"error\");\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n // The only writer of currentStatus, so onStatusChange sees every change once.\n private setStatus(status: ShaderStatus): void {\n if (status === this.currentStatus) return;\n this.currentStatus = status;\n this.options.onStatusChange?.(status);\n }\n\n // Keeps an unawaited `ready` from surfacing as an unhandled rejection, e.g.\n // after a StrictMode cleanup or during SSR. Callers still see the rejection.\n private markReadyHandled(): void {\n this.ready.catch(() => {});\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/core] ${message}`);\n }\n }\n}\n\nconst normalizeResolution = (resolution: Resolution): Resolution => {\n const [width, height] = resolution;\n if (\n !Number.isFinite(width) ||\n !Number.isFinite(height) ||\n width < 1 ||\n height < 1\n ) {\n throw new RangeError(`Invalid resolution: ${width}x${height}`);\n }\n return [Math.round(width), Math.round(height)];\n};\n\nconst assertWithinLimits = (gl: GLContext, resolution: Resolution): void => {\n const [width, height] = resolution;\n const viewportDims = gl.getParameter(gl.MAX_VIEWPORT_DIMS) as\n | ArrayLike<number>\n | null;\n const renderbufferSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) as\n | number\n | null;\n const limit = (axis: 0 | 1): number =>\n Math.min(\n viewportDims?.[axis] ?? Number.POSITIVE_INFINITY,\n typeof renderbufferSize === \"number\"\n ? renderbufferSize\n : Number.POSITIVE_INFINITY\n );\n\n if (width > limit(0) || height > limit(1)) {\n throw new UnsupportedError(\n `Resolution ${width}x${height} exceeds this GPU's limit of ${limit(0)}x${limit(1)}.`\n );\n }\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { ExplicitUniformInput, GLContext, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: GLContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const applyProgramUniform = (\n gl: GLContext,\n program: WebGLProgram,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n gl.useProgram(program);\n applyUniform(gl, location, uniform);\n};\n\n/**\n * Uploads every cached uniform to the bound program. Calls `onMissing` with\n * the name of each uniform the program lacks or optimized out.\n */\nexport const applyUniforms = (\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n cache: ReadonlyMap<string, NormalizedUniform>,\n onMissing?: (name: string) => void\n): void => {\n for (const [name, uniform] of cache) {\n const location = locations.get(name);\n if (!location) {\n onMissing?.(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n};\n\nexport const collectUniformLocations = (\n gl: GLContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import type { UniformInput } from \"../types\";\nimport { toUniformName } from \"./names\";\nimport { normalizeUniform, type NormalizedUniform } from \"./uniforms\";\n\n/**\n * Supplies uniform values for a time, such as a keyframe timeline. Runtimes\n * call `get()` with the same time as `u_time` before drawing.\n */\nexport type UniformSource = {\n get(time: number): Readonly<Record<string, UniformInput>>;\n};\n\n/** Ordered sources whose values override the runtime's own uniforms. */\nexport type UniformBindings = {\n /** Adds `source`; a later source wins for the same name. Returns its removal. */\n add(source: UniformSource): () => void;\n readonly size: number;\n /** Merged, normalized values at `time`, keyed by uniform name (`u_` prefixed). */\n evaluate(time: number): Map<string, NormalizedUniform>;\n /** A stable string of the values at `time`, to notice when they change. */\n signature(time: number): string;\n};\n\nexport const createUniformBindings = (): UniformBindings => {\n const sources: UniformSource[] = [];\n\n const evaluate = (time: number): Map<string, NormalizedUniform> => {\n const merged = new Map<string, NormalizedUniform>();\n for (const source of sources) {\n for (const [name, value] of Object.entries(source.get(time))) {\n merged.set(toUniformName(name), normalizeUniform(value));\n }\n }\n return merged;\n };\n\n return {\n add(source) {\n sources.push(source);\n let removed = false;\n return () => {\n if (removed) return;\n removed = true;\n const index = sources.indexOf(source);\n if (index >= 0) sources.splice(index, 1);\n };\n },\n get size() {\n return sources.length;\n },\n evaluate,\n signature(time) {\n if (sources.length === 0) return \"\";\n let text = \"\";\n for (const [name, uniform] of evaluate(time)) {\n text += `${name}:${uniform.type}:${Array.from(uniform.value).join(\",\")};`;\n }\n return text;\n }\n };\n};\n\n// --- Keyframes -------------------------------------------------------------------\n\nexport type KeyframeValue =\n | number\n | readonly [number, number]\n | readonly [number, number, number]\n | readonly [number, number, number, number];\n\n/** `[time in seconds, value]`. */\nexport type Keyframe = readonly [number, KeyframeValue];\n\n/**\n * How a segment eases from one key to the next: `\"linear\"`, `\"smooth\"`\n * (smoothstep), `\"step\"` (hold the earlier key), or a function of the\n * segment's 0–1 progress.\n */\nexport type Ease = \"linear\" | \"smooth\" | \"step\" | ((t: number) => number);\n\nexport type KeyframeTrack = readonly Keyframe[] | { keys: readonly Keyframe[]; ease?: Ease };\n\nexport type KeyframeOptions = {\n /** Default ease for tracks that do not set their own. Defaults to `\"linear\"`. */\n ease?: Ease;\n};\n\nconst EASES: Record<Exclude<Ease, (t: number) => number>, (t: number) => number> = {\n linear: (t) => t,\n smooth: (t) => t * t * (3 - 2 * t),\n step: () => 0\n};\n\nconst toEaseFunction = (ease: Ease): ((t: number) => number) => {\n if (typeof ease === \"function\") return ease;\n const fn = EASES[ease];\n if (!fn) throw new RangeError(`Unknown ease: ${String(ease)}`);\n return fn;\n};\n\nconst componentsOf = (value: KeyframeValue): readonly number[] =>\n typeof value === \"number\" ? [value] : value;\n\ntype CompiledTrack = {\n times: number[];\n values: Array<readonly number[]>;\n scalar: boolean;\n ease: (t: number) => number;\n};\n\nconst isKeyList = (track: KeyframeTrack): track is readonly Keyframe[] => Array.isArray(track);\n\nconst compileTrack = (name: string, track: KeyframeTrack, fallback: Ease): CompiledTrack => {\n // Not `\"keys\" in track`: arrays have a keys() method.\n const list = isKeyList(track);\n const keys = list ? track : track.keys;\n const ease = toEaseFunction((list ? undefined : track.ease) ?? fallback);\n if (keys.length === 0) throw new TypeError(`Keyframe track ${name} has no keys.`);\n\n const sorted = [...keys].sort((a, b) => a[0] - b[0]);\n const scalar = typeof sorted[0]![1] === \"number\";\n const size = componentsOf(sorted[0]![1]).length;\n for (const [time, value] of sorted) {\n if (!Number.isFinite(time)) throw new TypeError(`Keyframe track ${name} has a non-finite time.`);\n const components = componentsOf(value);\n if ((typeof value === \"number\") !== scalar || components.length !== size) {\n throw new TypeError(`Keyframe track ${name} mixes values of different sizes.`);\n }\n if (!components.every(Number.isFinite)) {\n throw new TypeError(`Keyframe track ${name} has a non-finite value.`);\n }\n }\n return {\n times: sorted.map(([time]) => time),\n values: sorted.map(([, value]) => componentsOf(value)),\n scalar,\n ease\n };\n};\n\nconst sampleTrack = (track: CompiledTrack, time: number): UniformInput => {\n const { times, values } = track;\n const last = times.length - 1;\n let components: readonly number[];\n if (time <= times[0]!) {\n components = values[0]!;\n } else if (time >= times[last]!) {\n components = values[last]!;\n } else {\n // The last key at or before `time`.\n let low = 0;\n let high = last;\n while (high - low > 1) {\n const middle = (low + high) >> 1;\n if (times[middle]! <= time) low = middle;\n else high = middle;\n }\n const span = times[high]! - times[low]!;\n const t = span > 0 ? track.ease((time - times[low]!) / span) : 0;\n const from = values[low]!;\n const to = values[high]!;\n components = from.map((value, index) => value + (to[index]! - value) * t);\n }\n return track.scalar ? components[0]! : (Array.from(components) as UniformInput);\n};\n\n/**\n * A `UniformSource` that interpolates keyframes per component: floats and\n * vec2–vec4 as tuples. Keys may come in any order; times before the first key\n * or after the last hold that key's value.\n *\n * ```ts\n * fx.bindUniforms(keyframes({\n * camPos: [[0, [0, 1, 6]], [4, [3, 1.5, 2]]],\n * glow: { keys: [[0, 0], [2, 1]], ease: \"smooth\" }\n * }));\n * ```\n */\nexport const keyframes = (\n tracks: Readonly<Record<string, KeyframeTrack>>,\n options: KeyframeOptions = {}\n): UniformSource => {\n const fallback = options.ease ?? \"linear\";\n toEaseFunction(fallback);\n const compiled = Object.entries(tracks).map(\n ([name, track]) => [name, compileTrack(name, track, fallback)] as const\n );\n return {\n get(time) {\n const values: Record<string, UniformInput> = {};\n for (const [name, track] of compiled) values[name] = sampleTrack(track, time);\n return values;\n }\n };\n};\n","import type { GLContext, TextureInput, TextureOptions, TextureSource } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n width: number;\n height: number;\n};\n\nexport const loadTexture = async (\n gl: GLContext,\n name: string,\n input: TextureInput,\n unit: number\n): Promise<LoadedTexture> => {\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n width: getSourceWidth(source),\n height: getSourceHeight(source)\n };\n};\n\nconst normalizeTextureInput = (input: TextureInput): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: GLContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (\n input: unknown\n): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { GLContext, TextureInput, TextureMap } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { loadTexture, type LoadedTexture } from \"./textures\";\n\nexport type TextureSet = {\n /** The textures loaded so far, by name. */\n readonly textures: ReadonlyMap<string, LoadedTexture>;\n /** Whether `name` was given as an input, loaded or not. */\n hasInput(name: string): boolean;\n /**\n * Returns the texture unit for `name`, taking the lowest free unit on first\n * use. Runtimes reserve units for their own samplers (feedback, pass inputs)\n * here too, so they never collide with image textures.\n */\n reserveUnit(gl: GLContext, name: string): number;\n /**\n * Loads every input, then replaces the previously loaded textures. Used for\n * the initial load and after a context restore.\n */\n loadAll(gl: GLContext, isCancelled: () => boolean): Promise<void>;\n /**\n * Loads `input` as `name`. Resolves to the loaded texture, or `null` when a\n * later `set()` for the same name or `isCancelled()` superseded it (its\n * texture is deleted). On failure the unit is released if `name` is unused,\n * and the error is rethrown.\n */\n set(\n gl: GLContext,\n name: string,\n input: TextureInput,\n isCancelled: () => boolean\n ): Promise<LoadedTexture | null>;\n /**\n * Binds every loaded texture to its unit and points its sampler uniform at\n * it. Calls `onMissing` with the uniform name when the program lacks it.\n */\n bind(\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n onMissing?: (uniformName: string) => void\n ): void;\n /** Deletes every loaded texture. */\n dispose(gl: GLContext): void;\n};\n\n/**\n * Tracks named image textures and the texture units they occupy, for a\n * runtime that binds them to one or more programs.\n */\nexport const createTextureSet = (inputs: TextureMap = {}): TextureSet => {\n const textureInputs = new Map<string, TextureInput>(Object.entries(inputs));\n let textures = new Map<string, LoadedTexture>();\n const units = new Map<string, number>();\n const versions = new Map<string, number>();\n\n const reserveUnit = (gl: GLContext, name: string): number => {\n const existing = units.get(name);\n if (existing !== undefined) return existing;\n\n const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number;\n const used = new Set(units.values());\n for (let unit = 0; unit < maxUnits; unit += 1) {\n if (!used.has(unit)) {\n units.set(name, unit);\n return unit;\n }\n }\n\n throw new TextureLoadError(\n `Texture unit limit exceeded while loading texture: ${name}`\n );\n };\n\n return {\n get textures() {\n return textures;\n },\n\n hasInput(name) {\n return textureInputs.has(name);\n },\n\n reserveUnit,\n\n async loadAll(gl, isCancelled) {\n const loaded = new Map<string, LoadedTexture>();\n for (const [name, input] of textureInputs) {\n if (isCancelled()) break;\n const unit = reserveUnit(gl, name);\n loaded.set(name, await loadTexture(gl, name, input, unit));\n }\n\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n textures = loaded;\n },\n\n async set(gl, name, input, isCancelled) {\n const version = (versions.get(name) ?? 0) + 1;\n versions.set(name, version);\n\n try {\n const unit = reserveUnit(gl, name);\n const loaded = await loadTexture(gl, name, input, unit);\n\n if (isCancelled() || versions.get(name) !== version) {\n gl.deleteTexture(loaded.texture);\n return null;\n }\n\n const previous = textures.get(name);\n textureInputs.set(name, input);\n textures.set(name, loaded);\n if (previous) gl.deleteTexture(previous.texture);\n return loaded;\n } catch (error) {\n if (!textures.has(name) && !textureInputs.has(name)) {\n units.delete(name);\n }\n throw error;\n }\n },\n\n bind(gl, locations, onMissing) {\n for (const texture of textures.values()) {\n const unit = units.get(texture.name);\n if (unit === undefined) continue;\n const location = locations.get(texture.uniformName);\n if (!location) {\n onMissing?.(texture.uniformName);\n continue;\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.uniform1i(location, unit);\n }\n },\n\n dispose(gl) {\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport { collectUniformLocations } from \"./uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isGLSL300\n} from \"./webgl\";\n\nexport type FullscreenProgram = {\n readonly program: WebGLProgram;\n /** Active uniform locations by name, array uniforms without `[0]`. */\n readonly locations: ReadonlyMap<string, WebGLUniformLocation>;\n /**\n * Binds the program, its quad buffer and `a_position`, so a draw is correct\n * whatever GL state user hooks left behind.\n */\n use(): void;\n /** Draws the fullscreen quad with the current GL state. */\n draw(): void;\n dispose(): void;\n};\n\n/**\n * Compiles `fragment` with a fullscreen-quad vertex shader (the GLSL ES 3.00\n * one when `fragment` starts with `#version 300 es`, unless `vertex` is\n * given) and leaves it bound.\n */\nexport const createFullscreenProgram = (\n gl: GLContext,\n fragment: string,\n vertex?: string\n): FullscreenProgram => {\n const defaultVertex = isGLSL300(fragment)\n ? defaultVertexShader300\n : defaultVertexShader;\n const program = createProgram(gl, vertex ?? defaultVertex, fragment);\n gl.useProgram(program);\n const buffer = createFullscreenBuffer(gl, program);\n const attribLocation = gl.getAttribLocation(program, \"a_position\");\n const locations = collectUniformLocations(gl, program);\n\n return {\n program,\n locations,\n use() {\n gl.useProgram(program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n if (attribLocation >= 0) {\n gl.enableVertexAttribArray(attribLocation);\n gl.vertexAttribPointer(attribLocation, 2, gl.FLOAT, false, 0, 0);\n }\n },\n draw() {\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose() {\n gl.deleteBuffer(buffer);\n gl.deleteProgram(program);\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isWebGL2Context\n} from \"./webgl\";\n\nconst blitFragmentShader = `\nprecision mediump float;\nvarying vec2 v_uv;\nuniform sampler2D u_texture;\n\nvoid main() {\n gl_FragColor = texture2D(u_texture, v_uv);\n}\n`;\n\nconst blitFragmentShader300 = `#version 300 es\nprecision mediump float;\nin vec2 v_uv;\nuniform sampler2D u_texture;\nout vec4 fragColor;\n\nvoid main() {\n fragColor = texture(u_texture, v_uv);\n}\n`;\n\nexport type Blitter = {\n /**\n * Draws `texture` as a fullscreen quad into `target` (or the default\n * framebuffer when `target` is `null`), setting the viewport to\n * `width`/`height` first. Does not save or restore any other GL state.\n */\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void;\n /** Releases the GL resources owned by this blitter. */\n dispose(): void;\n};\n\n/**\n * Creates a reusable fullscreen-quad \"blit\" utility: draws a texture into a\n * framebuffer (or the canvas) using a minimal passthrough shader. Intended\n * for hand-rolled multi-pass/FBO pipelines; frapx's own multi-pass features\n * are built on the same primitive.\n */\nexport const createBlitter = (gl: GLContext): Blitter => {\n const program = createProgram(\n gl,\n isWebGL2Context(gl) ? defaultVertexShader300 : defaultVertexShader,\n isWebGL2Context(gl) ? blitFragmentShader300 : blitFragmentShader\n );\n const buffer = createFullscreenBuffer(gl, program);\n const textureUniform = gl.getUniformLocation(program, \"u_texture\");\n\n return {\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void {\n gl.bindFramebuffer(gl.FRAMEBUFFER, target);\n gl.viewport(0, 0, width, height);\n gl.useProgram(program);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n const location = gl.getAttribLocation(program, \"a_position\");\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (textureUniform) {\n gl.uniform1i(textureUniform, 0);\n }\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose(): void {\n gl.deleteProgram(program);\n gl.deleteBuffer(buffer);\n }\n };\n};\n","import type {\n GLContext,\n PingPong,\n RenderTarget,\n RenderTargetFormat,\n RenderTargetOptions\n} from \"../types\";\nimport { ShaderCompileError, UnsupportedError } from \"./errors\";\nimport { isWebGL2Context } from \"./webgl\";\n\nconst DEFAULT_CLEAR_COLOR = [0, 0, 0, 0] as const;\n\n/**\n * Whether `format` can be allocated as a color attachment on `gl`. `rgba8` is\n * always available; `rgba16f` and `rgba32f` need WebGL2 and\n * `EXT_color_buffer_float`.\n * Enables the extension as a side effect when present.\n */\nexport const supportsRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat\n): boolean => {\n if (format === \"rgba8\") return true;\n return isWebGL2Context(gl) && gl.getExtension(\"EXT_color_buffer_float\") !== null;\n};\n\n/**\n * Resolves the format a render target will actually use. When `format` is not\n * supported this warns and returns `rgba8`, or throws `UnsupportedError` when\n * `formatFallback` is `false`.\n */\nexport const resolveRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat = \"rgba8\",\n formatFallback = true\n): RenderTargetFormat => {\n if (supportsRenderTargetFormat(gl, format)) return format;\n\n const reason = `${format} render targets need WebGL2 with EXT_color_buffer_float.`;\n if (!formatFallback) throw new UnsupportedError(reason);\n console.warn(`[frapx] ${reason} Falling back to rgba8.`);\n return \"rgba8\";\n};\n\n/**\n * Creates a texture-backed framebuffer to render into and sample from. The\n * storage is cleared to `clearColor` on creation and on every resize.\n */\nexport const createRenderTarget = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): RenderTarget => {\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n return new Target(gl, width, height, format, options);\n};\n\n/**\n * Creates two render targets of the same size and format for feedback-style\n * rendering: draw into `write` while sampling `read`, then `swap()`.\n */\nexport const createPingPong = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): PingPong => {\n // Resolve once so a fallback warns a single time for both targets.\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n let read: RenderTarget = new Target(gl, width, height, format, options);\n let write: RenderTarget;\n try {\n write = new Target(gl, width, height, format, options);\n } catch (error) {\n read.dispose();\n throw error;\n }\n\n return {\n get read() {\n return read;\n },\n get write() {\n return write;\n },\n format,\n swap() {\n const previous = read;\n read = write;\n write = previous;\n },\n resize(nextWidth: number, nextHeight: number) {\n read.resize(nextWidth, nextHeight);\n write.resize(nextWidth, nextHeight);\n },\n clear() {\n read.clear();\n write.clear();\n },\n dispose() {\n read.dispose();\n write.dispose();\n }\n };\n};\n\nclass Target implements RenderTarget {\n texture!: WebGLTexture;\n framebuffer!: WebGLFramebuffer;\n width: number;\n height: number;\n\n constructor(\n private readonly gl: GLContext,\n width: number,\n height: number,\n readonly format: RenderTargetFormat,\n private readonly options: RenderTargetOptions\n ) {\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n resize(width: number, height: number): void {\n if (width === this.width && height === this.height) return;\n this.release();\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n clear(): void {\n const gl = this.gl;\n const [r, g, b, a] = this.options.clearColor ?? DEFAULT_CLEAR_COLOR;\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\n gl.viewport(0, 0, this.width, this.height);\n gl.clearColor(r, g, b, a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n dispose(): void {\n this.release();\n }\n\n private allocate(): void {\n const gl = this.gl;\n const texture = gl.createTexture();\n if (!texture) {\n throw new ShaderCompileError(\"Failed to create render target texture.\");\n }\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) {\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\"Failed to create render target framebuffer.\");\n }\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (this.format !== \"rgba8\" && isWebGL2Context(gl)) {\n const half = this.format === \"rgba16f\";\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n half ? gl.RGBA16F : gl.RGBA32F,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n half ? gl.HALF_FLOAT : gl.FLOAT,\n null\n );\n } else {\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n null\n );\n }\n\n const wrap = getWrap(gl, this.options.wrap ?? \"clamp\");\n // Linear filtering of 32-bit float textures is an optional extension.\n const linear =\n this.options.filter !== \"nearest\" &&\n (this.format !== \"rgba32f\" || gl.getExtension(\"OES_texture_float_linear\") !== null);\n const filter = linear ? gl.LINEAR : gl.NEAREST;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\n `Render target framebuffer (${this.format}) is incomplete: ${status}`\n );\n }\n\n this.texture = texture;\n this.framebuffer = framebuffer;\n this.clear();\n }\n\n private release(): void {\n this.gl.deleteFramebuffer(this.framebuffer);\n this.gl.deleteTexture(this.texture);\n }\n}\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<RenderTargetOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n"],"mappings":"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","names":["size","getWrap"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/errors.ts","../src/internal/shaderLog.ts","../src/internal/webgl.ts","../src/internal/capture.ts","../src/internal/dom.ts","../src/host.ts","../src/internal/names.ts","../src/internal/uniforms.ts","../src/internal/bindings.ts","../src/internal/textures.ts","../src/internal/textureSet.ts","../src/internal/fullscreenProgram.ts","../src/internal/blit.ts","../src/internal/renderTarget.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** One line of a shader compile error, located in the source that was compiled. */\nexport type ShaderErrorLine = {\n /** 1-based line in the compiled source (after `glsl` template interpolation). */\n line: number;\n message: string;\n /** That line of the source, or \"\" when the log points past the end. */\n source: string;\n /** Up to two lines either side, with their numbers, the error line included. */\n context: ReadonlyArray<{ line: number; source: string }>;\n};\n\n/** `\"link\"` for program link errors, which carry no line numbers. */\nexport type ShaderStage = \"vertex\" | \"fragment\" | \"link\";\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {\n /** The stage that failed, or `null` for errors not tied to compiling a shader. */\n readonly stage: ShaderStage | null;\n /** Errors located in the source, parsed from the driver's info log. Empty when it had none. */\n readonly lines: readonly ShaderErrorLine[];\n\n constructor(\n message: string,\n details: { stage?: ShaderStage; lines?: readonly ShaderErrorLine[] } = {}\n ) {\n super(message);\n this.stage = details.stage ?? null;\n this.lines = details.lines ?? [];\n }\n}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { ShaderErrorLine } from \"./errors\";\n\n// Browsers translate shaders through ANGLE: \"ERROR: 0:12: 'x' : undeclared identifier\".\nconst ANGLE_STYLE = /^\\s*ERROR:\\s*\\d+:(\\d+):\\s*(.*)$/;\n// Native NVIDIA-style drivers: \"0(12) : error C1008: undefined variable\".\nconst NVIDIA_STYLE = /^\\s*\\d+\\((\\d+)\\)\\s*:\\s*error\\s*\\w*\\s*:\\s*(.*)$/i;\n// Follow-up noise after the real error.\nconst NOISE = /compilation terminated|^\\s*''\\s*:\\s*$/i;\n\nconst CONTEXT_LINES = 2;\n\n/**\n * Finds the errors in a shader info log and attaches the source lines they\n * point at. Lines the log does not locate are left out; the log itself stays\n * the error message.\n */\nexport const parseShaderLog = (log: string, source: string): ShaderErrorLine[] => {\n const sourceLines = source.split(/\\r?\\n/);\n const lineAt = (line: number) => sourceLines[line - 1] ?? \"\";\n const results: ShaderErrorLine[] = [];\n const seen = new Set<string>();\n\n for (const entry of log.split(/\\r?\\n/)) {\n const match = ANGLE_STYLE.exec(entry) ?? NVIDIA_STYLE.exec(entry);\n if (!match) continue;\n const line = Number(match[1]);\n const message = match[2]!.trim();\n if (!message || NOISE.test(message)) continue;\n const key = `${line}:${message}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const context: Array<{ line: number; source: string }> = [];\n const first = Math.max(1, line - CONTEXT_LINES);\n const last = Math.min(sourceLines.length, line + CONTEXT_LINES);\n for (let current = first; current <= last; current++) {\n context.push({ line: current, source: lineAt(current) });\n }\n results.push({ line, message, source: lineAt(line), context });\n }\n return results;\n};\n","import type { GLContext } from \"../types\";\nimport { ShaderCompileError } from \"./errors\";\nimport { parseShaderLog } from \"./shaderLog\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const defaultVertexShader300 = `#version 300 es\nin vec2 a_position;\nout vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const isGLSL300 = (src: string): boolean =>\n /^\\s*#version\\s+300\\s+es\\b/.test(src);\n\n// Duck-typed instead of `instanceof WebGL2RenderingContext` so this also works\n// against test mocks and other environments where the global constructor may\n// be unavailable.\nexport const isWebGL2Context = (gl: GLContext): gl is WebGL2RenderingContext =>\n typeof (gl as WebGL2RenderingContext).createVertexArray === \"function\";\n\nexport const createProgram = (\n gl: GLContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n let fragment: WebGLShader;\n try {\n fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n } catch (error) {\n gl.deleteShader(vertex);\n throw error;\n }\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log, { stage: \"link\" });\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: GLContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: GLContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log, {\n stage: type === gl.VERTEX_SHADER ? \"vertex\" : \"fragment\",\n lines: parseShaderLog(log, source)\n });\n }\n\n return shader;\n};\n","import type { GLContext } from \"../types\";\nimport { isWebGL2Context } from \"./webgl\";\n\n/**\n * Resolves once the GPU has finished every command submitted so far, polling\n * a fence between tasks. Waiting between heavy draws keeps each submission\n * short, so a long render never trips the browser's GPU watchdog and loses\n * the context. Resolves immediately on WebGL1.\n */\nexport const waitForGpu = (gl: GLContext): Promise<void> => {\n if (!isWebGL2Context(gl)) return Promise.resolve();\n const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);\n if (!sync) return Promise.resolve();\n gl.flush();\n return new Promise((resolve) => {\n const poll = () => {\n const status = gl.clientWaitSync(sync, 0, 0);\n if (status === gl.TIMEOUT_EXPIRED) {\n setTimeout(poll, 4);\n return;\n }\n gl.deleteSync(sync);\n resolve();\n };\n poll();\n });\n};\n\n/**\n * Reads RGBA pixels from `framebuffer` (or the drawing buffer when `null`) and\n * returns them top row first. Must run in the same task as the draw when\n * reading the drawing buffer, since it is not preserved.\n */\nexport const readPixels = <T extends \"rgba8\" | \"rgba16f\">(\n gl: GLContext,\n framebuffer: WebGLFramebuffer | null,\n width: number,\n height: number,\n format: T\n): T extends \"rgba16f\" ? Float32Array : Uint8Array => {\n const length = width * height * 4;\n const data =\n format === \"rgba16f\" ? new Float32Array(length) : new Uint8Array(length);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n // RGBA/FLOAT is the read combination EXT_color_buffer_float guarantees.\n gl.readPixels(\n 0,\n 0,\n width,\n height,\n gl.RGBA,\n format === \"rgba16f\" ? gl.FLOAT : gl.UNSIGNED_BYTE,\n data\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n flipRows(data, width * 4, height);\n return data as T extends \"rgba16f\" ? Float32Array : Uint8Array;\n};\n\n/** Encodes the canvas as PNG. The snapshot is taken synchronously. */\nexport const canvasToPng = (canvas: HTMLCanvasElement): Promise<Blob> =>\n new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error(\"Failed to encode the canvas as PNG.\"));\n }, \"image/png\");\n });\n\n// WebGL reads bottom-up; captures are top row first like images.\nconst flipRows = (\n data: Uint8Array | Float32Array,\n rowLength: number,\n rows: number\n): void => {\n const temp = data.slice(0, rowLength);\n for (let top = 0, bottom = rows - 1; top < bottom; top++, bottom--) {\n const topStart = top * rowLength;\n const bottomStart = bottom * rowLength;\n temp.set(data.subarray(topStart, topStart + rowLength));\n data.copyWithin(topStart, bottomStart, bottomStart + rowLength);\n data.set(temp, bottomStart);\n }\n};\n","import type { DprOption, Resolution, SetupCanvasOptions } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n /** True when the canvas was created without being attached to the document. */\n detached?: boolean;\n};\n\nexport type CanvasSize = {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (options: SetupCanvasOptions): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) {\n if (!options.detached) return null;\n canvas.dataset.frapxCanvas = \"\";\n return {\n target: canvas,\n canvas,\n createdCanvas: true,\n restoredPosition: null,\n detached: true\n };\n }\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\n/**\n * `\"auto\"` follows `devicePixelRatio`, capped by `maxDpr` (default 2). A\n * number or function is used as given and capped only when `maxDpr` is set.\n * Values below 1 are allowed; `<= 0` or non-finite throws `RangeError`.\n */\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n if (dpr === undefined || dpr === \"auto\") {\n const device =\n typeof window === \"undefined\" ? 1 : window.devicePixelRatio || 1;\n return Math.min(device, assertPositive(\"maxDpr\", maxDpr ?? 2));\n }\n\n const raw = assertPositive(\"dpr\", typeof dpr === \"function\" ? dpr() : dpr);\n return maxDpr === undefined ? raw : Math.min(raw, assertPositive(\"maxDpr\", maxDpr));\n};\n\n/** Checks the static parts of the dpr options; a `dpr` function is checked when it is called. */\nexport const assertDprOptions = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): void => {\n if (typeof dpr === \"number\") assertPositive(\"dpr\", dpr);\n if (maxDpr !== undefined) assertPositive(\"maxDpr\", maxDpr);\n};\n\nconst assertPositive = (name: string, value: number): number => {\n if (!Number.isFinite(value) || value <= 0) {\n throw new RangeError(`\\`${name}\\` must be a finite number above 0, got ${value}`);\n }\n return value;\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): CanvasSize => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\n/**\n * Sizes the canvas to a fixed internal resolution. The viewport size still\n * comes from the target so `u_viewportSize` reflects the displayed size; a\n * detached canvas has no layout, so its viewport equals the resolution.\n */\nexport const resizeCanvasToResolution = (\n canvas: HTMLCanvasElement,\n target: Element | null,\n resolution: Resolution\n): CanvasSize => {\n const [width, height] = resolution;\n let viewportWidth = width;\n let viewportHeight = height;\n\n if (target) {\n const rect = target.getBoundingClientRect();\n viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n }\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: SetupCanvasOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","import type {\n CaptureFormat,\n CaptureOptions,\n CaptureResult,\n ClockMode,\n GLContext,\n HostFrameState,\n HostPointer,\n Resolution,\n RuntimeHostInstance,\n RuntimeHostOptions,\n ShaderStatus,\n TimeSource\n} from \"./types\";\nimport { DestroyedError, TargetNotFoundError, UnsupportedError } from \"./internal/errors\";\nimport { canvasToPng, readPixels } from \"./internal/capture\";\nimport {\n assertDprOptions,\n resolveDpr,\n resizeCanvasToResolution,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\n// Manual clocks report a neutral pointer so output never depends on input.\nconst IDLE_POINTER: HostPointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n\nconst clampDelta = (delta: number): number =>\n Math.min(Math.max(delta, 0), MAX_DELTA_SECONDS);\n\ntype Gate = \"offscreen\" | \"hidden\" | \"reducedMotion\";\n\nexport const createRuntimeHost = (\n options: RuntimeHostOptions\n): RuntimeHostInstance => {\n return new RuntimeHost(options);\n};\n\nclass RuntimeHost implements RuntimeHostInstance {\n readonly ready: Promise<void>;\n\n private readonly options: RuntimeHostOptions;\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private context: GLContext | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private captureDrawing = false;\n private resizePending = false;\n private destroyed = false;\n private gates = new Set<Gate>();\n private reducedMotionActive = false;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n private statusBeforeLoss: ShaderStatus = \"idle\";\n private clockMode: ClockMode;\n private manualDelta = 0;\n private lastManualTime: number | null = null;\n private source: TimeSource | null;\n // The source's value at the previous loop frame; null restarts u_delta at 0.\n private lastSourceTime: number | null = null;\n private fixedResolution: Resolution | null;\n private objectFitRestore: string | null = null;\n // Letterbox offset (CSS px) of the contained canvas content inside the target.\n private contentOffsetX = 0;\n private contentOffsetY = 0;\n\n constructor(options: RuntimeHostOptions) {\n this.options = options;\n this.clockMode = options.clock ?? \"realtime\";\n this.source = options.timeSource ?? null;\n this.warnIfSourceUnread();\n assertDprOptions(options.dpr, options.maxDpr);\n this.fixedResolution = options.resolution\n ? normalizeResolution(options.resolution)\n : null;\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): GLContext | null {\n return this.context;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n get clock(): ClockMode {\n return this.clockMode;\n }\n\n /**\n * The time of the last frame drawn, before any `accumulation.loop`\n * wrapping: the value `setTime()` would need to reproduce that frame.\n * While gated it is the time the loop stopped at, and with a time source\n * it is the last value read from the source.\n */\n get time(): number {\n return this.elapsed;\n }\n\n get timeSource(): TimeSource | null {\n return this.source;\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n this.reconcile();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.setStatus(\"paused\");\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.context ||\n this.currentStatus === \"unsupported\" ||\n this.inRender\n )\n return;\n\n if (this.isManual) {\n // The caller decides when to draw; visibility gates do not apply.\n this.renderInternal(this.elapsed, this.manualDelta);\n return;\n }\n\n // Redraws at the last frame's time: refinement and reduced motion must\n // not chase a running source.\n if (this.hasVisibilityBlock) return;\n this.renderInternal(this.elapsed, 0);\n }\n\n setTime(seconds: number): void {\n if (!Number.isFinite(seconds)) {\n throw new RangeError(`setTime() expects a finite number, got ${seconds}`);\n }\n if (this.destroyed) return;\n\n if (this.isManual) {\n this.manualDelta =\n this.lastManualTime === null ? 0 : seconds - this.lastManualTime;\n this.lastManualTime = seconds;\n }\n this.elapsed = seconds;\n }\n\n setClock(clock: ClockMode): void {\n if (this.destroyed || clock === this.clockMode) return;\n this.clockMode = clock;\n this.manualDelta = 0;\n this.lastManualTime = null;\n // Gates kept tracking while manual, so this resumes against current state.\n this.reconcile();\n }\n\n setTimeSource(source: TimeSource | null): void {\n if (this.destroyed) return;\n this.source = source;\n this.lastSourceTime = null;\n this.warnIfSourceUnread();\n }\n\n // Only the realtime loop reads the source, and demand mode runs no loop.\n private warnIfSourceUnread(): void {\n if (this.source && this.options.renderMode === \"demand\") {\n this.debugWarn(\"`timeSource` is not read with renderMode \\\"demand\\\", which runs no frame loop. Call setTime() instead.\");\n }\n }\n\n setResolution(resolution: Resolution | null): void {\n if (this.destroyed) return;\n\n if (resolution === null) {\n if (this.isDetached) {\n throw new TypeError(\n \"A canvas without a target needs a fixed resolution.\"\n );\n }\n this.fixedResolution = null;\n } else {\n const next = normalizeResolution(resolution);\n if (this.context) assertWithinLimits(this.context, next);\n this.fixedResolution = next;\n }\n\n this.applyObjectFit();\n this.resize();\n }\n\n async captureFrame<F extends CaptureFormat = \"png\">(\n options: CaptureOptions<F> = {}\n ): Promise<CaptureResult<F>> {\n const format: CaptureFormat = options.format ?? \"png\";\n if (format !== \"png\" && format !== \"rgba8\" && format !== \"rgba16f\") {\n throw new RangeError(`Unknown capture format: ${String(format)}`);\n }\n\n await this.ready;\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n if (!this.dom || !this.context) {\n throw new UnsupportedError(\"Cannot capture without a WebGL context.\");\n }\n if (this.inRender) {\n throw new Error(\"captureFrame() cannot be called while a frame is drawing.\");\n }\n\n // Check before drawing so a rejected capture has no side effects.\n const sourceFormat = this.options.captureSource?.()?.format;\n if (format === \"rgba16f\" && sourceFormat !== \"rgba16f\" && sourceFormat !== \"rgba32f\") {\n throw new UnsupportedError(\n \"rgba16f capture needs a float render target, such as feedback with format rgba16f.\"\n );\n }\n options.signal?.throwIfAborted();\n\n const delta = this.isManual ? this.manualDelta : 0;\n const drawContext = this.context;\n if (!this.options.onCaptureDraw) {\n this.renderInternal(this.elapsed, delta);\n return this.readCapture(format, drawContext);\n }\n\n try {\n await this.renderForCapture(this.options.onCaptureDraw, delta, options.signal);\n return this.readCapture(format, drawContext);\n } finally {\n // Resizes requested while drawing apply once the frame is read.\n if (this.resizePending) {\n this.resizePending = false;\n this.resize();\n }\n }\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n // Keep the size an asynchronous capture draw started with until it is read.\n if (this.captureDrawing) {\n this.resizePending = true;\n return;\n }\n\n this.syncSize();\n\n if (this.shouldRenderOnDemand && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n this.context = null;\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n } else if (this.dom && this.objectFitRestore !== null) {\n this.dom.canvas.style.objectFit = this.objectFitRestore;\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n (dom.target as HTMLElement).style.position = dom.restoredPosition!;\n }\n\n this.setStatus(\"destroyed\");\n this.markReadyHandled();\n this.readyReject?.(new DestroyedError(\"Runtime host was destroyed.\"));\n }\n\n private get isManual(): boolean {\n return this.clockMode === \"manual\";\n }\n\n private get followsSource(): boolean {\n return this.source !== null && !this.isManual;\n }\n\n // A non-finite reading holds the previous time instead of throwing in a frame.\n private readSource(): number | null {\n if (!this.followsSource) return null;\n const now = this.source!();\n return Number.isFinite(now) ? now : null;\n }\n\n // The static frame takes the source's current time without a delta.\n private syncSourceTime(): void {\n const now = this.readSource();\n if (now !== null) this.elapsed = now;\n }\n\n // A loop frame under a source: time is the source's value, never clamped;\n // delta is the step from the previous frame, 0 when it went back.\n private advanceFromSource(): number {\n const now = this.readSource();\n if (now === null) return 0;\n const previous = this.lastSourceTime;\n this.lastSourceTime = now;\n this.elapsed = now;\n return previous === null ? 0 : clampDelta(now - previous);\n }\n\n private get isDetached(): boolean {\n if (this.dom) return this.dom.detached === true;\n return this.options.target === undefined && this.options.canvas === undefined;\n }\n\n // Demand mode re-renders on input changes, except under a manual clock where\n // only explicit render() calls draw.\n private get shouldRenderOnDemand(): boolean {\n return this.options.renderMode === \"demand\" && !this.isManual;\n }\n\n private get hasVisibilityBlock(): boolean {\n return this.gates.has(\"offscreen\") || this.gates.has(\"hidden\");\n }\n\n private get hasMotionBlock(): boolean {\n return (\n this.gates.has(\"reducedMotion\") && this.options.renderMode !== \"demand\"\n );\n }\n\n private setGate(gate: Gate, closed: boolean): void {\n if (closed === this.gates.has(gate)) return;\n if (closed) this.gates.add(gate);\n else this.gates.delete(gate);\n this.reconcile();\n }\n\n // `restoring` lets a restored context leave \"context-lost\" straight to what\n // the gates allow, so the status never passes through a stale value.\n private reconcile(restoring = false): void {\n if (\n this.destroyed ||\n this.currentStatus === \"unsupported\" ||\n this.currentStatus === \"error\" ||\n (this.currentStatus === \"context-lost\" && !restoring)\n ) {\n return;\n }\n\n if (this.isManual) {\n this.cancelFrame();\n this.setStatus(\"paused\");\n return;\n }\n\n if (this.running) {\n if (this.hasVisibilityBlock) {\n this.cancelFrame();\n this.setStatus(\"paused\");\n return;\n }\n\n if (this.hasMotionBlock) {\n this.cancelFrame();\n this.setStatus(\"paused\");\n this.renderStaticFrame();\n return;\n }\n\n this.setStatus(\"running\");\n if (this.options.renderMode === \"demand\") this.render();\n else this.scheduleFrame();\n return;\n }\n\n if (this.options.renderMode === \"demand\") this.render();\n }\n\n private renderStaticFrame(): void {\n if (this.hasVisibilityBlock) return;\n this.syncSourceTime();\n this.renderInternal(this.elapsed, 0);\n }\n\n private renderInternal(time: number, delta: number): void {\n // An asynchronous capture draw holds the lock across tasks.\n if (!this.dom || !this.context || this.inRender) return;\n const gl = this.context;\n\n this.inRender = true;\n try {\n this.syncSize();\n this.options.onDraw(this.createFrameState(time, delta, gl));\n this.frame++;\n } finally {\n this.inRender = false;\n }\n }\n\n // Holds the render lock across an asynchronous capture draw so no other\n // frame interleaves with it.\n private async renderForCapture(\n draw: NonNullable<RuntimeHostOptions[\"onCaptureDraw\"]>,\n delta: number,\n signal: AbortSignal | undefined\n ): Promise<void> {\n if (!this.dom || !this.context) return;\n this.inRender = true;\n this.captureDrawing = true;\n try {\n this.syncSize();\n await draw(this.createFrameState(this.elapsed, delta, this.context), signal);\n this.frame++;\n } finally {\n this.inRender = false;\n this.captureDrawing = false;\n }\n }\n\n // Reads the frame just drawn, in the task that drew it: the drawing buffer\n // is not preserved. Fails if the context drawn into is gone, including when\n // it was lost and restored while an asynchronous draw was pending.\n private readCapture<F extends CaptureFormat>(\n format: CaptureFormat,\n drawContext: GLContext | null\n ): Promise<CaptureResult<F>> | CaptureResult<F> {\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n const gl = this.context;\n if (!gl || gl !== drawContext || !this.dom) {\n throw new UnsupportedError(\"The WebGL context was lost while capturing.\");\n }\n\n if (format === \"png\") {\n return canvasToPng(this.dom.canvas) as Promise<CaptureResult<F>>;\n }\n if (format === \"rgba8\") {\n return readPixels(gl, null, this.width, this.height, \"rgba8\") as CaptureResult<F>;\n }\n const source = this.options.captureSource!()!;\n return readPixels(\n gl,\n source.framebuffer,\n source.width,\n source.height,\n \"rgba16f\"\n ) as CaptureResult<F>;\n }\n\n private createFrameState(\n time: number,\n delta: number,\n gl: GLContext = this.context!\n ): HostFrameState {\n return {\n gl,\n canvas: this.dom!.canvas,\n time,\n delta,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio,\n reducedMotion: this.isManual ? false : this.reducedMotionActive,\n pointer: this.isManual ? { ...IDLE_POINTER } : { ...this.pointer }\n };\n }\n\n /**\n * Measures the size and calls onResize if it changed. Frames measure too:\n * browsers run animation frames before resize observations, so in a running\n * loop a frame is usually the first to see a new size.\n */\n private syncSize(): void {\n const prevWidth = this.width;\n const prevHeight = this.height;\n const prevViewportWidth = this.viewportWidth;\n const prevViewportHeight = this.viewportHeight;\n\n this.measureSize();\n\n const sizeChanged =\n this.width !== prevWidth ||\n this.height !== prevHeight ||\n this.viewportWidth !== prevViewportWidth ||\n this.viewportHeight !== prevViewportHeight;\n\n if (sizeChanged && this.context) {\n this.options.onResize?.(this.createFrameState(this.elapsed, 0));\n }\n }\n\n private measureSize(): void {\n if (!this.dom) return;\n\n if (this.fixedResolution) {\n const size = resizeCanvasToResolution(\n this.dom.canvas,\n this.dom.detached ? null : this.dom.target,\n this.fixedResolution\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n // Internal pixels per displayed CSS pixel under object-fit: contain.\n this.pixelRatio = Math.max(\n size.width / size.viewportWidth,\n size.height / size.viewportHeight\n );\n this.contentOffsetX =\n (size.viewportWidth - size.width / this.pixelRatio) / 2;\n this.contentOffsetY =\n (size.viewportHeight - size.height / this.pixelRatio) / 2;\n return;\n }\n\n this.contentOffsetX = 0;\n this.contentOffsetY = 0;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n }\n\n // Letterbox the fixed-resolution canvas instead of stretching it.\n private applyObjectFit(): void {\n if (!this.dom) return;\n const style = this.dom.canvas.style;\n if (this.fixedResolution && this.objectFitRestore === null) {\n this.objectFitRestore = style.objectFit ?? \"\";\n style.objectFit = \"contain\";\n } else if (!this.fixedResolution && this.objectFitRestore !== null) {\n style.objectFit = this.objectFitRestore;\n this.objectFitRestore = null;\n }\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\" || this.isManual)\n return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n let delta: number;\n if (this.followsSource) {\n delta = this.advanceFromSource();\n } else {\n delta = this.lastTimestamp ? clampDelta(seconds - this.lastTimestamp) : 0;\n this.elapsed += delta;\n }\n this.lastTimestamp = seconds;\n this.renderInternal(this.elapsed, delta);\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n this.lastSourceTime = null;\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas({\n ...(this.options.target !== undefined && { target: this.options.target }),\n ...(this.options.canvas !== undefined && { canvas: this.options.canvas }),\n ...(this.options.layer !== undefined && { layer: this.options.layer }),\n ...(this.options.canvasClass !== undefined && { canvasClass: this.options.canvasClass }),\n ...(this.options.canvasStyle !== undefined && { canvasStyle: this.options.canvasStyle }),\n // Only a missing target/canvas may fall back to a detached canvas; a\n // target that fails to resolve must still report TargetNotFoundError.\n detached:\n this.fixedResolution !== null &&\n this.options.target === undefined &&\n this.options.canvas === undefined\n });\n\n if (!this.dom) {\n this.failUnsupported(\n new TargetNotFoundError(\n \"Target or canvas not found. Pass `resolution` to render without a target.\"\n )\n );\n return;\n }\n\n let gl: GLContext | null;\n try {\n gl = this.options.createContext(this.dom.canvas);\n } catch (error) {\n this.failUnsupported(\n error instanceof UnsupportedError\n ? error\n : new UnsupportedError(String(error))\n );\n return;\n }\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n if (this.fixedResolution) {\n try {\n assertWithinLimits(gl, this.fixedResolution);\n } catch (error) {\n this.failUnsupported(\n error instanceof Error ? error : new UnsupportedError(String(error))\n );\n return;\n }\n if (this.options.dpr !== undefined || this.options.maxDpr !== undefined) {\n this.debugWarn(\"`dpr` and `maxDpr` are ignored while `resolution` is set.\");\n }\n }\n\n this.context = gl;\n this.setStatus(\"loading\");\n // onStatusChange may have destroyed the host.\n if (this.destroyed) return;\n\n try {\n this.applyObjectFit();\n this.setupDomObservers();\n this.setupContextEvents();\n this.measureSize();\n await this.options.onInit(gl, this.width, this.height);\n if (this.destroyed) return;\n this.setStatus(\"ready\");\n if (this.destroyed) return;\n this.readyResolve?.();\n this.options.onReady?.();\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n } catch (error) {\n if (error instanceof UnsupportedError) this.failUnsupported(error);\n else this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n const detached = this.dom.detached === true;\n\n // A detached canvas has no layout: it can never be measured, scrolled into\n // view or pointed at, so only document-level observers apply.\n if (!detached && (this.options.autoResize ?? true)) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (!detached && (this.options.pauseWhenOffscreen ?? true)) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.setGate(\"offscreen\", !entry?.isIntersecting);\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenHidden ?? true) {\n if (document.hidden) this.gates.add(\"hidden\");\n const onVisibility = () => {\n this.setGate(\"hidden\", document.hidden);\n };\n document.addEventListener(\"visibilitychange\", onVisibility);\n this.removeListeners.push(() => {\n document.removeEventListener(\"visibilitychange\", onVisibility);\n });\n }\n\n this.setupMotionObserver();\n\n if (detached) return;\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left - this.contentOffsetX;\n const y = pointerEvent.clientY - rect.top - this.contentOffsetY;\n // Displayed content size in CSS px (smaller than rect when letterboxed).\n const contentWidth = this.fixedResolution\n ? this.width / this.pixelRatio\n : rect.width;\n const contentHeight = this.fixedResolution\n ? this.height / this.pixelRatio\n : rect.height;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (contentHeight - y) * this.pixelRatio;\n this.pointer.uvX = contentWidth > 0 ? x / contentWidth : 0;\n this.pointer.uvY = contentHeight > 0 ? 1 - y / contentHeight : 0;\n this.pointer.active = 1;\n\n if (this.shouldRenderOnDemand) this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.shouldRenderOnDemand) this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupMotionObserver(): void {\n if (typeof window.matchMedia !== \"function\") return;\n\n const query = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n this.reducedMotionActive = query.matches;\n if (this.options.respectReducedMotion && query.matches) {\n this.gates.add(\"reducedMotion\");\n }\n\n const onChange = (event: MediaQueryListEvent) => {\n this.reducedMotionActive = event.matches;\n if (this.options.respectReducedMotion) {\n this.setGate(\"reducedMotion\", event.matches);\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n };\n\n query.addEventListener(\"change\", onChange);\n this.removeListeners.push(() => {\n query.removeEventListener(\"change\", onChange);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.statusBeforeLoss = this.currentStatus;\n this.cancelFrame();\n this.context = null;\n this.setStatus(\"context-lost\");\n if (this.destroyed) return;\n this.options.onContextLost?.();\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.options.createContext(this.dom.canvas);\n if (!gl) return;\n this.context = gl;\n\n const afterRestore = async () => {\n try {\n await this.options.onContextRestored?.(gl, this.width, this.height);\n if (this.destroyed) return;\n if (this.contextRestoredShouldRun) {\n // Gates may have closed during the loss; report only their result.\n this.running = true;\n this.reconcile(true);\n return;\n }\n // A stopped or manual-clock instance would otherwise stay\n // \"context-lost\", and render() would refuse to draw.\n if (this.currentStatus === \"context-lost\") this.setStatus(this.statusBeforeLoss);\n if (!this.isManual) this.render();\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n void afterRestore();\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private failUnsupported(error: Error): void {\n this.setStatus(\"unsupported\");\n this.debugWarn(error.message);\n this.options.onError?.(error);\n // An unsupported environment is expected; a missing target stays loud.\n if (error instanceof UnsupportedError) this.markReadyHandled();\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.setStatus(\"error\");\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n // The only writer of currentStatus, so onStatusChange sees every change once.\n private setStatus(status: ShaderStatus): void {\n if (status === this.currentStatus) return;\n this.currentStatus = status;\n this.options.onStatusChange?.(status);\n }\n\n // Keeps an unawaited `ready` from surfacing as an unhandled rejection, e.g.\n // after a StrictMode cleanup or during SSR. Callers still see the rejection.\n private markReadyHandled(): void {\n this.ready.catch(() => {});\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/core] ${message}`);\n }\n }\n}\n\nconst normalizeResolution = (resolution: Resolution): Resolution => {\n const [width, height] = resolution;\n if (\n !Number.isFinite(width) ||\n !Number.isFinite(height) ||\n width < 1 ||\n height < 1\n ) {\n throw new RangeError(`Invalid resolution: ${width}x${height}`);\n }\n return [Math.round(width), Math.round(height)];\n};\n\nconst assertWithinLimits = (gl: GLContext, resolution: Resolution): void => {\n const [width, height] = resolution;\n const viewportDims = gl.getParameter(gl.MAX_VIEWPORT_DIMS) as\n | ArrayLike<number>\n | null;\n const renderbufferSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) as\n | number\n | null;\n const limit = (axis: 0 | 1): number =>\n Math.min(\n viewportDims?.[axis] ?? Number.POSITIVE_INFINITY,\n typeof renderbufferSize === \"number\"\n ? renderbufferSize\n : Number.POSITIVE_INFINITY\n );\n\n if (width > limit(0) || height > limit(1)) {\n throw new UnsupportedError(\n `Resolution ${width}x${height} exceeds this GPU's limit of ${limit(0)}x${limit(1)}.`\n );\n }\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { ExplicitUniformInput, GLContext, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: GLContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const applyProgramUniform = (\n gl: GLContext,\n program: WebGLProgram,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n gl.useProgram(program);\n applyUniform(gl, location, uniform);\n};\n\n/**\n * Uploads every cached uniform to the bound program. Calls `onMissing` with\n * the name of each uniform the program lacks or optimized out.\n */\nexport const applyUniforms = (\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n cache: ReadonlyMap<string, NormalizedUniform>,\n onMissing?: (name: string) => void\n): void => {\n for (const [name, uniform] of cache) {\n const location = locations.get(name);\n if (!location) {\n onMissing?.(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n};\n\nexport const collectUniformLocations = (\n gl: GLContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import type { UniformInput } from \"../types\";\nimport { toUniformName } from \"./names\";\nimport { normalizeUniform, type NormalizedUniform } from \"./uniforms\";\n\n/**\n * Supplies uniform values for a time, such as a keyframe timeline. Runtimes\n * call `get()` with the same time as `u_time` before drawing.\n */\nexport type UniformSource = {\n get(time: number): Readonly<Record<string, UniformInput>>;\n};\n\n/** Ordered sources whose values override the runtime's own uniforms. */\nexport type UniformBindings = {\n /** Adds `source`; a later source wins for the same name. Returns its removal. */\n add(source: UniformSource): () => void;\n readonly size: number;\n /** Merged, normalized values at `time`, keyed by uniform name (`u_` prefixed). */\n evaluate(time: number): Map<string, NormalizedUniform>;\n /** A stable string of the values at `time`, to notice when they change. */\n signature(time: number): string;\n};\n\nexport const createUniformBindings = (): UniformBindings => {\n const sources: UniformSource[] = [];\n\n const evaluate = (time: number): Map<string, NormalizedUniform> => {\n const merged = new Map<string, NormalizedUniform>();\n for (const source of sources) {\n for (const [name, value] of Object.entries(source.get(time))) {\n merged.set(toUniformName(name), normalizeUniform(value));\n }\n }\n return merged;\n };\n\n return {\n add(source) {\n sources.push(source);\n let removed = false;\n return () => {\n if (removed) return;\n removed = true;\n const index = sources.indexOf(source);\n if (index >= 0) sources.splice(index, 1);\n };\n },\n get size() {\n return sources.length;\n },\n evaluate,\n signature(time) {\n if (sources.length === 0) return \"\";\n let text = \"\";\n for (const [name, uniform] of evaluate(time)) {\n text += `${name}:${uniform.type}:${Array.from(uniform.value).join(\",\")};`;\n }\n return text;\n }\n };\n};\n\n// --- Keyframes -------------------------------------------------------------------\n\nexport type KeyframeValue =\n | number\n | readonly [number, number]\n | readonly [number, number, number]\n | readonly [number, number, number, number];\n\n/** `[time in seconds, value]`. */\nexport type Keyframe = readonly [number, KeyframeValue];\n\n/**\n * How a segment eases from one key to the next: `\"linear\"`, `\"smooth\"`\n * (smoothstep), `\"step\"` (hold the earlier key), or a function of the\n * segment's 0–1 progress.\n */\nexport type Ease = \"linear\" | \"smooth\" | \"step\" | ((t: number) => number);\n\nexport type KeyframeTrack = readonly Keyframe[] | { keys: readonly Keyframe[]; ease?: Ease };\n\nexport type KeyframeOptions = {\n /** Default ease for tracks that do not set their own. Defaults to `\"linear\"`. */\n ease?: Ease;\n};\n\nconst EASES: Record<Exclude<Ease, (t: number) => number>, (t: number) => number> = {\n linear: (t) => t,\n smooth: (t) => t * t * (3 - 2 * t),\n step: () => 0\n};\n\nconst toEaseFunction = (ease: Ease): ((t: number) => number) => {\n if (typeof ease === \"function\") return ease;\n const fn = EASES[ease];\n if (!fn) throw new RangeError(`Unknown ease: ${String(ease)}`);\n return fn;\n};\n\nconst componentsOf = (value: KeyframeValue): readonly number[] =>\n typeof value === \"number\" ? [value] : value;\n\ntype CompiledTrack = {\n times: number[];\n values: Array<readonly number[]>;\n scalar: boolean;\n ease: (t: number) => number;\n};\n\nconst isKeyList = (track: KeyframeTrack): track is readonly Keyframe[] => Array.isArray(track);\n\nconst compileTrack = (name: string, track: KeyframeTrack, fallback: Ease): CompiledTrack => {\n // Not `\"keys\" in track`: arrays have a keys() method.\n const list = isKeyList(track);\n const keys = list ? track : track.keys;\n const ease = toEaseFunction((list ? undefined : track.ease) ?? fallback);\n if (keys.length === 0) throw new TypeError(`Keyframe track ${name} has no keys.`);\n\n const sorted = [...keys].sort((a, b) => a[0] - b[0]);\n const scalar = typeof sorted[0]![1] === \"number\";\n const size = componentsOf(sorted[0]![1]).length;\n for (const [time, value] of sorted) {\n if (!Number.isFinite(time)) throw new TypeError(`Keyframe track ${name} has a non-finite time.`);\n const components = componentsOf(value);\n if ((typeof value === \"number\") !== scalar || components.length !== size) {\n throw new TypeError(`Keyframe track ${name} mixes values of different sizes.`);\n }\n if (!components.every(Number.isFinite)) {\n throw new TypeError(`Keyframe track ${name} has a non-finite value.`);\n }\n }\n return {\n times: sorted.map(([time]) => time),\n values: sorted.map(([, value]) => componentsOf(value)),\n scalar,\n ease\n };\n};\n\nconst sampleTrack = (track: CompiledTrack, time: number): UniformInput => {\n const { times, values } = track;\n const last = times.length - 1;\n let components: readonly number[];\n if (time <= times[0]!) {\n components = values[0]!;\n } else if (time >= times[last]!) {\n components = values[last]!;\n } else {\n // The last key at or before `time`.\n let low = 0;\n let high = last;\n while (high - low > 1) {\n const middle = (low + high) >> 1;\n if (times[middle]! <= time) low = middle;\n else high = middle;\n }\n const span = times[high]! - times[low]!;\n const t = span > 0 ? track.ease((time - times[low]!) / span) : 0;\n const from = values[low]!;\n const to = values[high]!;\n components = from.map((value, index) => value + (to[index]! - value) * t);\n }\n return track.scalar ? components[0]! : (Array.from(components) as UniformInput);\n};\n\n/**\n * A `UniformSource` that interpolates keyframes per component: floats and\n * vec2–vec4 as tuples. Keys may come in any order; times before the first key\n * or after the last hold that key's value.\n *\n * ```ts\n * fx.bindUniforms(keyframes({\n * camPos: [[0, [0, 1, 6]], [4, [3, 1.5, 2]]],\n * glow: { keys: [[0, 0], [2, 1]], ease: \"smooth\" }\n * }));\n * ```\n */\nexport const keyframes = (\n tracks: Readonly<Record<string, KeyframeTrack>>,\n options: KeyframeOptions = {}\n): UniformSource => {\n const fallback = options.ease ?? \"linear\";\n toEaseFunction(fallback);\n const compiled = Object.entries(tracks).map(\n ([name, track]) => [name, compileTrack(name, track, fallback)] as const\n );\n return {\n get(time) {\n const values: Record<string, UniformInput> = {};\n for (const [name, track] of compiled) values[name] = sampleTrack(track, time);\n return values;\n }\n };\n};\n","import type {\n DataTextureFormat,\n DataTextureOptions,\n GLContext,\n TextureInput,\n TextureOptions,\n TextureSource\n} from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\nimport type { NormalizedUniform } from \"./uniforms\";\nimport { isWebGL2Context } from \"./webgl\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n /** `TEXTURE_2D` for images, `TEXTURE_3D` for data textures. */\n target: number;\n width: number;\n height: number;\n /** Depth of a 3D data texture; `null` for 2D textures. */\n depth: number | null;\n};\n\n/** Called with a message when a texture is loaded differently than asked. */\nexport type TextureWarn = (message: string) => void;\n\nexport const loadTexture = async (\n gl: GLContext,\n name: string,\n input: TextureInput,\n unit: number,\n warn?: TextureWarn\n): Promise<LoadedTexture> => {\n if (isDataTextureOptions(input)) {\n return loadDataTexture(gl, name, input, unit, warn);\n }\n\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n target: gl.TEXTURE_2D,\n width: getSourceWidth(source),\n height: getSourceHeight(source),\n depth: null\n };\n};\n\n/** The `u_<name>Size` uniform: vec2 for 2D textures, vec3 for 3D ones. */\nexport const getTextureSizeUniform = (texture: LoadedTexture): NormalizedUniform =>\n texture.depth === null\n ? { type: \"vec2\", value: [texture.width, texture.height] }\n : { type: \"vec3\", value: [texture.width, texture.height, texture.depth] };\n\nconst DATA_FORMATS: Record<\n DataTextureFormat,\n {\n array: string;\n matches: (data: DataTextureOptions[\"data\"]) => boolean;\n upload: (gl: WebGL2RenderingContext) => { internal: number; type: number };\n }\n> = {\n r8: {\n array: \"Uint8Array\",\n matches: (data) => data instanceof Uint8Array,\n upload: (gl) => ({ internal: gl.R8, type: gl.UNSIGNED_BYTE })\n },\n r16f: {\n array: \"Uint16Array\",\n matches: (data) => data instanceof Uint16Array,\n upload: (gl) => ({ internal: gl.R16F, type: gl.HALF_FLOAT })\n },\n r32f: {\n array: \"Float32Array\",\n matches: (data) => data instanceof Float32Array,\n upload: (gl) => ({ internal: gl.R32F, type: gl.FLOAT })\n }\n};\n\nconst loadDataTexture = (\n gl: GLContext,\n name: string,\n options: DataTextureOptions,\n unit: number,\n warn: TextureWarn | undefined\n): LoadedTexture => {\n if (!isWebGL2Context(gl)) {\n throw new TextureLoadError(`3D textures need WebGL2: ${name}`);\n }\n\n const format = DATA_FORMATS[options.format];\n if (!format) {\n throw new TextureLoadError(\n `Unknown data texture format \"${String(options.format)}\": ${name}`\n );\n }\n\n const [nx, ny, nz] = options.size;\n if (![nx, ny, nz].every((n) => Number.isInteger(n) && n > 0)) {\n throw new TextureLoadError(\n `Data texture size must be three positive integers, got [${options.size.join(\", \")}]: ${name}`\n );\n }\n if (!format.matches(options.data)) {\n throw new TextureLoadError(\n `Data texture format \"${options.format}\" needs a ${format.array}: ${name}`\n );\n }\n if (options.data.length !== nx * ny * nz) {\n throw new TextureLoadError(\n `Data texture has ${options.data.length} values, size [${nx}, ${ny}, ${nz}] needs ${nx * ny * nz}: ${name}`\n );\n }\n\n let filterName = options.filter ?? \"linear\";\n if (\n options.format === \"r32f\" &&\n filterName === \"linear\" &&\n gl.getExtension(\"OES_texture_float_linear\") === null\n ) {\n filterName = \"nearest\";\n warn?.(\n `r32f texture \"${name}\" is sampled with nearest filtering: OES_texture_float_linear is unavailable.`\n );\n }\n\n const texture = gl.createTexture();\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n const { internal, type } = format.upload(gl);\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_3D, texture);\n // texImage3D from an ArrayBufferView fails with UNPACK_FLIP_Y_WEBGL set,\n // which image uploads leave on by default.\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n gl.texImage3D(gl.TEXTURE_3D, 0, internal, nx, ny, nz, 0, gl.RED, type, options.data);\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, filterName);\n\n gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, wrap);\n gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n target: gl.TEXTURE_3D,\n width: nx,\n height: ny,\n depth: nz\n };\n};\n\nconst isDataTextureOptions = (input: TextureInput): input is DataTextureOptions =>\n typeof input === \"object\" && \"data\" in input;\n\nconst normalizeTextureInput = (\n input: TextureSource | TextureOptions\n): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: GLContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (\n input: unknown\n): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { GLContext, TextureInput, TextureMap } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { loadTexture, type LoadedTexture, type TextureWarn } from \"./textures\";\n\nexport type TextureSet = {\n /** The textures loaded so far, by name. */\n readonly textures: ReadonlyMap<string, LoadedTexture>;\n /** Whether `name` was given as an input, loaded or not. */\n hasInput(name: string): boolean;\n /**\n * Returns the texture unit for `name`, taking the lowest free unit on first\n * use. Runtimes reserve units for their own samplers (feedback, pass inputs)\n * here too, so they never collide with image textures.\n */\n reserveUnit(gl: GLContext, name: string): number;\n /**\n * Loads every input, then replaces the previously loaded textures. Used for\n * the initial load and after a context restore.\n */\n loadAll(gl: GLContext, isCancelled: () => boolean): Promise<void>;\n /**\n * Loads `input` as `name`. Resolves to the loaded texture, or `null` when a\n * later `set()` for the same name or `isCancelled()` superseded it (its\n * texture is deleted). On failure the unit is released if `name` is unused,\n * and the error is rethrown.\n */\n set(\n gl: GLContext,\n name: string,\n input: TextureInput,\n isCancelled: () => boolean\n ): Promise<LoadedTexture | null>;\n /**\n * Binds every loaded texture to its unit and points its sampler uniform at\n * it. Calls `onMissing` with the uniform name when the program lacks it.\n */\n bind(\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n onMissing?: (uniformName: string) => void\n ): void;\n /** Deletes every loaded texture. */\n dispose(gl: GLContext): void;\n};\n\nexport type TextureSetOptions = {\n /** Receives warnings about textures loaded differently than asked. */\n warn?: TextureWarn;\n};\n\n/**\n * Tracks named image and data textures and the texture units they occupy, for\n * a runtime that binds them to one or more programs.\n */\nexport const createTextureSet = (\n inputs: TextureMap = {},\n options: TextureSetOptions = {}\n): TextureSet => {\n const textureInputs = new Map<string, TextureInput>(Object.entries(inputs));\n let textures = new Map<string, LoadedTexture>();\n const units = new Map<string, number>();\n const versions = new Map<string, number>();\n\n const reserveUnit = (gl: GLContext, name: string): number => {\n const existing = units.get(name);\n if (existing !== undefined) return existing;\n\n const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number;\n const used = new Set(units.values());\n for (let unit = 0; unit < maxUnits; unit += 1) {\n if (!used.has(unit)) {\n units.set(name, unit);\n return unit;\n }\n }\n\n throw new TextureLoadError(\n `Texture unit limit exceeded while loading texture: ${name}`\n );\n };\n\n return {\n get textures() {\n return textures;\n },\n\n hasInput(name) {\n return textureInputs.has(name);\n },\n\n reserveUnit,\n\n async loadAll(gl, isCancelled) {\n const loaded = new Map<string, LoadedTexture>();\n for (const [name, input] of textureInputs) {\n if (isCancelled()) break;\n const unit = reserveUnit(gl, name);\n loaded.set(name, await loadTexture(gl, name, input, unit, options.warn));\n }\n\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n textures = loaded;\n },\n\n async set(gl, name, input, isCancelled) {\n const version = (versions.get(name) ?? 0) + 1;\n versions.set(name, version);\n\n try {\n const unit = reserveUnit(gl, name);\n const loaded = await loadTexture(gl, name, input, unit, options.warn);\n\n if (isCancelled() || versions.get(name) !== version) {\n gl.deleteTexture(loaded.texture);\n return null;\n }\n\n const previous = textures.get(name);\n textureInputs.set(name, input);\n textures.set(name, loaded);\n if (previous) gl.deleteTexture(previous.texture);\n return loaded;\n } catch (error) {\n if (!textures.has(name) && !textureInputs.has(name)) {\n units.delete(name);\n }\n throw error;\n }\n },\n\n bind(gl, locations, onMissing) {\n for (const texture of textures.values()) {\n const unit = units.get(texture.name);\n if (unit === undefined) continue;\n const location = locations.get(texture.uniformName);\n if (!location) {\n onMissing?.(texture.uniformName);\n continue;\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(texture.target, texture.texture);\n gl.uniform1i(location, unit);\n }\n },\n\n dispose(gl) {\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport { collectUniformLocations } from \"./uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isGLSL300\n} from \"./webgl\";\n\nexport type FullscreenProgram = {\n readonly program: WebGLProgram;\n /** Active uniform locations by name, array uniforms without `[0]`. */\n readonly locations: ReadonlyMap<string, WebGLUniformLocation>;\n /**\n * Binds the program, its quad buffer and `a_position`, so a draw is correct\n * whatever GL state user hooks left behind.\n */\n use(): void;\n /** Draws the fullscreen quad with the current GL state. */\n draw(): void;\n dispose(): void;\n};\n\n/**\n * Compiles `fragment` with a fullscreen-quad vertex shader (the GLSL ES 3.00\n * one when `fragment` starts with `#version 300 es`, unless `vertex` is\n * given) and leaves it bound.\n */\nexport const createFullscreenProgram = (\n gl: GLContext,\n fragment: string,\n vertex?: string\n): FullscreenProgram => {\n const defaultVertex = isGLSL300(fragment)\n ? defaultVertexShader300\n : defaultVertexShader;\n const program = createProgram(gl, vertex ?? defaultVertex, fragment);\n gl.useProgram(program);\n const buffer = createFullscreenBuffer(gl, program);\n const attribLocation = gl.getAttribLocation(program, \"a_position\");\n const locations = collectUniformLocations(gl, program);\n\n return {\n program,\n locations,\n use() {\n gl.useProgram(program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n if (attribLocation >= 0) {\n gl.enableVertexAttribArray(attribLocation);\n gl.vertexAttribPointer(attribLocation, 2, gl.FLOAT, false, 0, 0);\n }\n },\n draw() {\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose() {\n gl.deleteBuffer(buffer);\n gl.deleteProgram(program);\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isWebGL2Context\n} from \"./webgl\";\n\nconst blitFragmentShader = `\nprecision mediump float;\nvarying vec2 v_uv;\nuniform sampler2D u_texture;\n\nvoid main() {\n gl_FragColor = texture2D(u_texture, v_uv);\n}\n`;\n\nconst blitFragmentShader300 = `#version 300 es\nprecision mediump float;\nin vec2 v_uv;\nuniform sampler2D u_texture;\nout vec4 fragColor;\n\nvoid main() {\n fragColor = texture(u_texture, v_uv);\n}\n`;\n\nexport type Blitter = {\n /**\n * Draws `texture` as a fullscreen quad into `target` (or the default\n * framebuffer when `target` is `null`), setting the viewport to\n * `width`/`height` first. Does not save or restore any other GL state.\n */\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void;\n /** Releases the GL resources owned by this blitter. */\n dispose(): void;\n};\n\n/**\n * Creates a reusable fullscreen-quad \"blit\" utility: draws a texture into a\n * framebuffer (or the canvas) using a minimal passthrough shader. Intended\n * for hand-rolled multi-pass/FBO pipelines; frapx's own multi-pass features\n * are built on the same primitive.\n */\nexport const createBlitter = (gl: GLContext): Blitter => {\n const program = createProgram(\n gl,\n isWebGL2Context(gl) ? defaultVertexShader300 : defaultVertexShader,\n isWebGL2Context(gl) ? blitFragmentShader300 : blitFragmentShader\n );\n const buffer = createFullscreenBuffer(gl, program);\n const textureUniform = gl.getUniformLocation(program, \"u_texture\");\n\n return {\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void {\n gl.bindFramebuffer(gl.FRAMEBUFFER, target);\n gl.viewport(0, 0, width, height);\n gl.useProgram(program);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n const location = gl.getAttribLocation(program, \"a_position\");\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (textureUniform) {\n gl.uniform1i(textureUniform, 0);\n }\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose(): void {\n gl.deleteProgram(program);\n gl.deleteBuffer(buffer);\n }\n };\n};\n","import type {\n GLContext,\n PingPong,\n RenderTarget,\n RenderTargetFormat,\n RenderTargetOptions\n} from \"../types\";\nimport { ShaderCompileError, UnsupportedError } from \"./errors\";\nimport { isWebGL2Context } from \"./webgl\";\n\nconst DEFAULT_CLEAR_COLOR = [0, 0, 0, 0] as const;\n\n/**\n * Whether `format` can be allocated as a color attachment on `gl`. `rgba8` is\n * always available; `rgba16f` and `rgba32f` need WebGL2 and\n * `EXT_color_buffer_float`.\n * Enables the extension as a side effect when present.\n */\nexport const supportsRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat\n): boolean => {\n if (format === \"rgba8\") return true;\n return isWebGL2Context(gl) && gl.getExtension(\"EXT_color_buffer_float\") !== null;\n};\n\n/**\n * Resolves the format a render target will actually use. When `format` is not\n * supported this warns and returns `rgba8`, or throws `UnsupportedError` when\n * `formatFallback` is `false`.\n */\nexport const resolveRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat = \"rgba8\",\n formatFallback = true\n): RenderTargetFormat => {\n if (supportsRenderTargetFormat(gl, format)) return format;\n\n const reason = `${format} render targets need WebGL2 with EXT_color_buffer_float.`;\n if (!formatFallback) throw new UnsupportedError(reason);\n console.warn(`[frapx] ${reason} Falling back to rgba8.`);\n return \"rgba8\";\n};\n\n/**\n * Creates a texture-backed framebuffer to render into and sample from. The\n * storage is cleared to `clearColor` on creation and on every resize.\n */\nexport const createRenderTarget = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): RenderTarget => {\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n return new Target(gl, width, height, format, options);\n};\n\n/**\n * Creates two render targets of the same size and format for feedback-style\n * rendering: draw into `write` while sampling `read`, then `swap()`.\n */\nexport const createPingPong = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): PingPong => {\n // Resolve once so a fallback warns a single time for both targets.\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n let read: RenderTarget = new Target(gl, width, height, format, options);\n let write: RenderTarget;\n try {\n write = new Target(gl, width, height, format, options);\n } catch (error) {\n read.dispose();\n throw error;\n }\n\n return {\n get read() {\n return read;\n },\n get write() {\n return write;\n },\n format,\n swap() {\n const previous = read;\n read = write;\n write = previous;\n },\n resize(nextWidth: number, nextHeight: number) {\n read.resize(nextWidth, nextHeight);\n write.resize(nextWidth, nextHeight);\n },\n clear() {\n read.clear();\n write.clear();\n },\n dispose() {\n read.dispose();\n write.dispose();\n }\n };\n};\n\nclass Target implements RenderTarget {\n texture!: WebGLTexture;\n framebuffer!: WebGLFramebuffer;\n width: number;\n height: number;\n\n constructor(\n private readonly gl: GLContext,\n width: number,\n height: number,\n readonly format: RenderTargetFormat,\n private readonly options: RenderTargetOptions\n ) {\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n resize(width: number, height: number): void {\n if (width === this.width && height === this.height) return;\n this.release();\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n clear(): void {\n const gl = this.gl;\n const [r, g, b, a] = this.options.clearColor ?? DEFAULT_CLEAR_COLOR;\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\n gl.viewport(0, 0, this.width, this.height);\n gl.clearColor(r, g, b, a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n dispose(): void {\n this.release();\n }\n\n private allocate(): void {\n const gl = this.gl;\n const texture = gl.createTexture();\n if (!texture) {\n throw new ShaderCompileError(\"Failed to create render target texture.\");\n }\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) {\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\"Failed to create render target framebuffer.\");\n }\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (this.format !== \"rgba8\" && isWebGL2Context(gl)) {\n const half = this.format === \"rgba16f\";\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n half ? gl.RGBA16F : gl.RGBA32F,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n half ? gl.HALF_FLOAT : gl.FLOAT,\n null\n );\n } else {\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n null\n );\n }\n\n const wrap = getWrap(gl, this.options.wrap ?? \"clamp\");\n // Linear filtering of 32-bit float textures is an optional extension.\n const linear =\n this.options.filter !== \"nearest\" &&\n (this.format !== \"rgba32f\" || gl.getExtension(\"OES_texture_float_linear\") !== null);\n const filter = linear ? gl.LINEAR : gl.NEAREST;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\n `Render target framebuffer (${this.format}) is incomplete: ${status}`\n );\n }\n\n this.texture = texture;\n this.framebuffer = framebuffer;\n this.clear();\n }\n\n private release(): void {\n this.gl.deleteFramebuffer(this.framebuffer);\n this.gl.deleteTexture(this.texture);\n }\n}\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<RenderTargetOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n"],"mappings":"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","names":["size","getWrap"]}
|