@dopaminefx/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/color.d.ts +71 -0
- package/dist/engine/color.d.ts.map +1 -0
- package/dist/engine/color.js +107 -0
- package/dist/engine/color.js.map +1 -0
- package/dist/engine/context.d.ts +54 -0
- package/dist/engine/context.d.ts.map +1 -0
- package/dist/engine/context.js +0 -0
- package/dist/engine/context.js.map +1 -0
- package/dist/engine/gl.d.ts +9 -0
- package/dist/engine/gl.d.ts.map +1 -0
- package/dist/engine/gl.js +39 -0
- package/dist/engine/gl.js.map +1 -0
- package/dist/engine/look/glsl.d.ts +95 -0
- package/dist/engine/look/glsl.d.ts.map +1 -0
- package/dist/engine/look/glsl.js +171 -0
- package/dist/engine/look/glsl.js.map +1 -0
- package/dist/engine/look/particles.glsl.d.ts +21 -0
- package/dist/engine/look/particles.glsl.d.ts.map +1 -0
- package/dist/engine/look/particles.glsl.js +44 -0
- package/dist/engine/look/particles.glsl.js.map +1 -0
- package/dist/engine/sdf.d.ts +77 -0
- package/dist/engine/sdf.d.ts.map +1 -0
- package/dist/engine/sdf.js +255 -0
- package/dist/engine/sdf.js.map +1 -0
- package/dist/engine/seed.d.ts +10 -0
- package/dist/engine/seed.d.ts.map +1 -0
- package/dist/engine/seed.js +20 -0
- package/dist/engine/seed.js.map +1 -0
- package/dist/engine/shadow.d.ts +41 -0
- package/dist/engine/shadow.d.ts.map +1 -0
- package/dist/engine/shadow.js +39 -0
- package/dist/engine/shadow.js.map +1 -0
- package/dist/engine/tempo.d.ts +33 -0
- package/dist/engine/tempo.d.ts.map +1 -0
- package/dist/engine/tempo.js +51 -0
- package/dist/engine/tempo.js.map +1 -0
- package/dist/framework/conductor.d.ts +100 -0
- package/dist/framework/conductor.d.ts.map +1 -0
- package/dist/framework/conductor.js +493 -0
- package/dist/framework/conductor.js.map +1 -0
- package/dist/framework/content.d.ts +67 -0
- package/dist/framework/content.d.ts.map +1 -0
- package/dist/framework/content.js +72 -0
- package/dist/framework/content.js.map +1 -0
- package/dist/framework/dope-pass.d.ts +131 -0
- package/dist/framework/dope-pass.d.ts.map +1 -0
- package/dist/framework/dope-pass.js +346 -0
- package/dist/framework/dope-pass.js.map +1 -0
- package/dist/framework/dope-zip.d.ts +22 -0
- package/dist/framework/dope-zip.d.ts.map +1 -0
- package/dist/framework/dope-zip.js +116 -0
- package/dist/framework/dope-zip.js.map +1 -0
- package/dist/framework/effect.d.ts +128 -0
- package/dist/framework/effect.d.ts.map +1 -0
- package/dist/framework/effect.js +19 -0
- package/dist/framework/effect.js.map +1 -0
- package/dist/framework/frame-expr.d.ts +124 -0
- package/dist/framework/frame-expr.d.ts.map +1 -0
- package/dist/framework/frame-expr.js +135 -0
- package/dist/framework/frame-expr.js.map +1 -0
- package/dist/framework/load-effect.d.ts +77 -0
- package/dist/framework/load-effect.d.ts.map +1 -0
- package/dist/framework/load-effect.js +135 -0
- package/dist/framework/load-effect.js.map +1 -0
- package/dist/framework/loader.d.ts +309 -0
- package/dist/framework/loader.d.ts.map +1 -0
- package/dist/framework/loader.js +266 -0
- package/dist/framework/loader.js.map +1 -0
- package/dist/framework/mood-registry.d.ts +58 -0
- package/dist/framework/mood-registry.d.ts.map +1 -0
- package/dist/framework/mood-registry.js +58 -0
- package/dist/framework/mood-registry.js.map +1 -0
- package/dist/framework/panel-runner.d.ts +96 -0
- package/dist/framework/panel-runner.d.ts.map +1 -0
- package/dist/framework/panel-runner.js +137 -0
- package/dist/framework/panel-runner.js.map +1 -0
- package/dist/framework/pass-common.d.ts +97 -0
- package/dist/framework/pass-common.d.ts.map +1 -0
- package/dist/framework/pass-common.js +178 -0
- package/dist/framework/pass-common.js.map +1 -0
- package/dist/framework/pass-runner.d.ts +183 -0
- package/dist/framework/pass-runner.d.ts.map +1 -0
- package/dist/framework/pass-runner.js +212 -0
- package/dist/framework/pass-runner.js.map +1 -0
- package/dist/framework/programs.d.ts +54 -0
- package/dist/framework/programs.d.ts.map +1 -0
- package/dist/framework/programs.js +33 -0
- package/dist/framework/programs.js.map +1 -0
- package/dist/framework/registry.d.ts +29 -0
- package/dist/framework/registry.d.ts.map +1 -0
- package/dist/framework/registry.js +38 -0
- package/dist/framework/registry.js.map +1 -0
- package/dist/framework/runtime.d.ts +19 -0
- package/dist/framework/runtime.d.ts.map +1 -0
- package/dist/framework/runtime.js +37 -0
- package/dist/framework/runtime.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/dist/overlay.d.ts +46 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +79 -0
- package/dist/overlay.js.map +1 -0
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -0
- package/src/engine/color.ts +154 -0
- package/src/engine/context.ts +0 -0
- package/src/engine/gl.ts +46 -0
- package/src/engine/look/glsl.ts +183 -0
- package/src/engine/look/particles.glsl.ts +44 -0
- package/src/engine/sdf.ts +298 -0
- package/src/engine/seed.ts +23 -0
- package/src/engine/shadow.ts +66 -0
- package/src/engine/tempo.ts +54 -0
- package/src/framework/conductor.ts +604 -0
- package/src/framework/content.ts +113 -0
- package/src/framework/dope-pass.ts +432 -0
- package/src/framework/dope-zip.ts +125 -0
- package/src/framework/effect.ts +127 -0
- package/src/framework/frame-expr.ts +217 -0
- package/src/framework/load-effect.ts +204 -0
- package/src/framework/loader.ts +502 -0
- package/src/framework/mood-registry.ts +87 -0
- package/src/framework/panel-runner.ts +233 -0
- package/src/framework/pass-common.ts +222 -0
- package/src/framework/pass-runner.ts +391 -0
- package/src/framework/programs.ts +62 -0
- package/src/framework/registry.ts +44 -0
- package/src/framework/runtime.ts +38 -0
- package/src/index.ts +227 -0
- package/src/overlay.ts +109 -0
- package/src/types.ts +63 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `.dope` CONTENT + TYPOGRAPHY consumers (Phase 3).
|
|
3
|
+
*
|
|
4
|
+
* Phase 0–2 moved an effect's numeric/palette/tempo params + its icon geometry
|
|
5
|
+
* into the `.dope`. Phase 3 finishes the job for the last code-shaped data:
|
|
6
|
+
*
|
|
7
|
+
* - `content.words` / `content.checkToken` — Comic's affirmation pool + the
|
|
8
|
+
* checkmark sentinel, picked per-fire by seed.
|
|
9
|
+
* - `content.glyphBands` — Solarbloom's whimsy→check-glyph (face + char) bands.
|
|
10
|
+
* - `typography` — Comic's mood→face baselines + the whimsy/intensity CURVE
|
|
11
|
+
* table (skew/stretch/tracking/outlineLayers/extrude/jitter/roundness),
|
|
12
|
+
* evaluated with the mapping grammar (extended with mix/max/min).
|
|
13
|
+
*
|
|
14
|
+
* These resolvers reproduce the legacy `mood.ts` arithmetic EXACTLY (the legacy
|
|
15
|
+
* functions stay as the parity reference, just like the numeric path), so a
|
|
16
|
+
* built-in's output is byte-identical while reskinning (different words, font,
|
|
17
|
+
* curves) becomes pure `.dope` editing.
|
|
18
|
+
*/
|
|
19
|
+
import { type ExprNode } from "./loader.js";
|
|
20
|
+
/**
|
|
21
|
+
* Deterministically pick one of `list` from a seed. Matches Comic's `pickWord`:
|
|
22
|
+
* `mulberry32(seed>>>0)()` → index. Same seed → same pick; un-pinned scatters.
|
|
23
|
+
*/
|
|
24
|
+
export declare function pickFromList<T>(list: readonly T[], seed: number): T;
|
|
25
|
+
/**
|
|
26
|
+
* Pick a band by whimsy (0..1), splitting the slider into equal bands. Matches
|
|
27
|
+
* Solarbloom's `pickCheckGlyph`: `floor(w * n)` clamped to the last band.
|
|
28
|
+
*/
|
|
29
|
+
export declare function pickBand<T>(bands: readonly T[], whimsy: number): T;
|
|
30
|
+
/** Per-mood typographic baselines (the `ComicBaseline` typographic fields). */
|
|
31
|
+
export interface TypographyMoodBaseline {
|
|
32
|
+
face: string;
|
|
33
|
+
skew: number;
|
|
34
|
+
tilt: number;
|
|
35
|
+
stretchX: number;
|
|
36
|
+
tracking: number;
|
|
37
|
+
roundness: number;
|
|
38
|
+
}
|
|
39
|
+
/** The `typography` section of a `.dope`. */
|
|
40
|
+
export interface DopeTypography {
|
|
41
|
+
/** Robust CSS fallback chain appended after the mood's primary face. */
|
|
42
|
+
fallbackStack: string;
|
|
43
|
+
/** Per-mood baselines, keyed by mood name. */
|
|
44
|
+
perMood: Record<string, TypographyMoodBaseline>;
|
|
45
|
+
/**
|
|
46
|
+
* Derived numeric fields, each an expression over `control` (intensity/whimsy)
|
|
47
|
+
* + `baseline` (the per-mood typographic baseline). String fields (fontStack)
|
|
48
|
+
* are assembled separately. clamp01/round flags mirror the param specs.
|
|
49
|
+
*/
|
|
50
|
+
fields: Record<string, {
|
|
51
|
+
from: ExprNode;
|
|
52
|
+
clamp01?: boolean;
|
|
53
|
+
round?: boolean;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
/** Resolved typography (the numeric fields + the assembled font stack). */
|
|
57
|
+
export interface ResolvedTypography {
|
|
58
|
+
fontStack: string;
|
|
59
|
+
[field: string]: number | string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Evaluate a typography table for a mood + intensity + whimsy. Pure; the
|
|
63
|
+
* `baseline` context is the per-mood typographic baseline so a field expr can
|
|
64
|
+
* reference e.g. `{ "baseline": "stretchX" }` or `{ "baseline": "roundness" }`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveTypography(typo: DopeTypography, mood: string, intensity: number, whimsy: number): ResolvedTypography;
|
|
67
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/framework/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAA0B,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAKpE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAInE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAIlE;AAMD,+EAA+E;AAC/E,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAChD;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChF;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,kBAAkB,CAwBpB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `.dope` CONTENT + TYPOGRAPHY consumers (Phase 3).
|
|
3
|
+
*
|
|
4
|
+
* Phase 0–2 moved an effect's numeric/palette/tempo params + its icon geometry
|
|
5
|
+
* into the `.dope`. Phase 3 finishes the job for the last code-shaped data:
|
|
6
|
+
*
|
|
7
|
+
* - `content.words` / `content.checkToken` — Comic's affirmation pool + the
|
|
8
|
+
* checkmark sentinel, picked per-fire by seed.
|
|
9
|
+
* - `content.glyphBands` — Solarbloom's whimsy→check-glyph (face + char) bands.
|
|
10
|
+
* - `typography` — Comic's mood→face baselines + the whimsy/intensity CURVE
|
|
11
|
+
* table (skew/stretch/tracking/outlineLayers/extrude/jitter/roundness),
|
|
12
|
+
* evaluated with the mapping grammar (extended with mix/max/min).
|
|
13
|
+
*
|
|
14
|
+
* These resolvers reproduce the legacy `mood.ts` arithmetic EXACTLY (the legacy
|
|
15
|
+
* functions stay as the parity reference, just like the numeric path), so a
|
|
16
|
+
* built-in's output is byte-identical while reskinning (different words, font,
|
|
17
|
+
* curves) becomes pure `.dope` editing.
|
|
18
|
+
*/
|
|
19
|
+
import { evalExpr } from "./loader.js";
|
|
20
|
+
import { mulberry32 } from "../engine/seed.js";
|
|
21
|
+
const clamp01 = (x) => (x < 0 ? 0 : x > 1 ? 1 : x);
|
|
22
|
+
/**
|
|
23
|
+
* Deterministically pick one of `list` from a seed. Matches Comic's `pickWord`:
|
|
24
|
+
* `mulberry32(seed>>>0)()` → index. Same seed → same pick; un-pinned scatters.
|
|
25
|
+
*/
|
|
26
|
+
export function pickFromList(list, seed) {
|
|
27
|
+
const r = mulberry32(seed >>> 0)();
|
|
28
|
+
const idx = Math.min(list.length - 1, Math.floor(r * list.length));
|
|
29
|
+
return list[idx];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Pick a band by whimsy (0..1), splitting the slider into equal bands. Matches
|
|
33
|
+
* Solarbloom's `pickCheckGlyph`: `floor(w * n)` clamped to the last band.
|
|
34
|
+
*/
|
|
35
|
+
export function pickBand(bands, whimsy) {
|
|
36
|
+
const w = clamp01(whimsy);
|
|
37
|
+
const idx = Math.min(bands.length - 1, Math.floor(w * bands.length));
|
|
38
|
+
return bands[idx];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Evaluate a typography table for a mood + intensity + whimsy. Pure; the
|
|
42
|
+
* `baseline` context is the per-mood typographic baseline so a field expr can
|
|
43
|
+
* reference e.g. `{ "baseline": "stretchX" }` or `{ "baseline": "roundness" }`.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveTypography(typo, mood, intensity, whimsy) {
|
|
46
|
+
// Degrade an undeclared mood to the first declared typography mood (not a
|
|
47
|
+
// hardcoded "celebratory"), matching the loader's own-default fallback.
|
|
48
|
+
const base = typo.perMood[mood] ?? typo.perMood[Object.keys(typo.perMood)[0]];
|
|
49
|
+
const ctx = {
|
|
50
|
+
controls: { intensity: clamp01(intensity), whimsy: clamp01(whimsy) },
|
|
51
|
+
// Only the numeric baselines are visible to the grammar.
|
|
52
|
+
baseline: {
|
|
53
|
+
skew: base.skew,
|
|
54
|
+
tilt: base.tilt,
|
|
55
|
+
stretchX: base.stretchX,
|
|
56
|
+
tracking: base.tracking,
|
|
57
|
+
roundness: base.roundness,
|
|
58
|
+
},
|
|
59
|
+
consts: {},
|
|
60
|
+
};
|
|
61
|
+
const out = { fontStack: `${base.face}, ${typo.fallbackStack}` };
|
|
62
|
+
for (const [name, spec] of Object.entries(typo.fields)) {
|
|
63
|
+
let v = evalExpr(spec.from, ctx);
|
|
64
|
+
if (spec.round)
|
|
65
|
+
v = Math.round(v);
|
|
66
|
+
if (spec.clamp01)
|
|
67
|
+
v = clamp01(v);
|
|
68
|
+
out[name] = v;
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/framework/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAA+B,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEnE;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAI,IAAkB,EAAE,IAAY;IAC9D,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,GAAG,CAAE,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAI,KAAmB,EAAE,MAAc;IAC7D,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,OAAO,KAAK,CAAC,GAAG,CAAE,CAAC;AACrB,CAAC;AAoCD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAoB,EACpB,IAAY,EACZ,SAAiB,EACjB,MAAc;IAEd,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,CAAE,CAAC;IAChF,MAAM,GAAG,GAAY;QACnB,QAAQ,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;QACpE,yDAAyD;QACzD,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B;QACD,MAAM,EAAE,EAAE;KACX,CAAC;IACF,MAAM,GAAG,GAAuB,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;IACrF,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,KAAK;YAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,OAAO;YAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic DATA-DRIVEN pass factory — instantiates a pure-shader effect from
|
|
3
|
+
* `(dope, shader, hooks)` with no per-effect factory code.
|
|
4
|
+
*
|
|
5
|
+
* For a datafied effect the `.dope` carries everything the hand-written
|
|
6
|
+
* per-effect `PassConfig` used to: the per-frame logic (`tempo.frame`), the
|
|
7
|
+
* shadow height (`render.shadowHeightFrac`), the per-pass uniforms
|
|
8
|
+
* (`render.pass`), the SDF-sourced samplers (`binding.samplers[].outline`),
|
|
9
|
+
* the loop-cap consts (`render.consts`), the runner config
|
|
10
|
+
* (`render.config.usesOrigin`), the reduced-motion peak/hold
|
|
11
|
+
* (`tempo.reducedMotion`) and the uniform-binding contract (`binding`). This
|
|
12
|
+
* module derives the `PassConfig` from that data — uniform names by the same
|
|
13
|
+
* `name → u<Name>` convention `computeScalarBinds` applies, exceptions from
|
|
14
|
+
* the binding contract — so the only hand-written web source left for such an
|
|
15
|
+
* effect is its GLSL.
|
|
16
|
+
*
|
|
17
|
+
* The honest boundary stays honest: anything genuinely code-shaped (a sprite
|
|
18
|
+
* panel, frame arrays, a host-rasterized aux texture) is passed through
|
|
19
|
+
* `hooks`, the same seams `PassConfig` always had — and a hook overrides the
|
|
20
|
+
* derived `auxTextures`/`passUniforms` when both exist.
|
|
21
|
+
*/
|
|
22
|
+
import { type DopeDoc } from "./loader.js";
|
|
23
|
+
import { type PassConfig, type PassParams } from "./pass-runner.js";
|
|
24
|
+
import { type PanelConfig, type PanelDraw } from "./panel-runner.js";
|
|
25
|
+
import { type RenderProgram } from "./programs.js";
|
|
26
|
+
import type { EffectFactory } from "./effect.js";
|
|
27
|
+
/** The code-shaped escape hatches a datafied effect may still need. */
|
|
28
|
+
export type DopePassHooks = Partial<Pick<PassConfig, "auxTextures" | "passUniforms" | "panel" | "frameArrays">> & {
|
|
29
|
+
/** Additional uniform names (beyond the derived set) the shader reads. */
|
|
30
|
+
extraUniforms?: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* The Canvas2D draw for a PASS effect's dynamic sprite panel (`render.panel`
|
|
33
|
+
* with the doc still pass-shaped — e.g. solarbloom's motes). The `.dope`
|
|
34
|
+
* `render.panel` block supplies the unit + sampler; this hook supplies only
|
|
35
|
+
* the genuinely code-shaped draw. Ignored when `hooks.panel` is given whole.
|
|
36
|
+
*/
|
|
37
|
+
panelDraw?: NonNullable<PassConfig["panel"]>["draw"];
|
|
38
|
+
};
|
|
39
|
+
/** The vertex + fragment GLSL pair (the per-effect look — code by design). */
|
|
40
|
+
export interface DopeShader {
|
|
41
|
+
vertex: string;
|
|
42
|
+
fragment: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Derive a {@link PassConfig} from a datafied `.dope` + its shader (+ optional
|
|
46
|
+
* code hooks). The derived contract is pinned by the per-effect dope-config
|
|
47
|
+
* vitests:
|
|
48
|
+
*
|
|
49
|
+
* - `uniforms`: every `render.params` key not in `binding.excludeParams` and
|
|
50
|
+
* not the scatter key → `u<Name>`; the scatter key contributes
|
|
51
|
+
* `binding.scatterWeb` when present (else it is not a shader uniform); every
|
|
52
|
+
* `binding.extras[].web`; every `binding.samplers[].web`; every
|
|
53
|
+
* `binding.arrays[].web` (the `frameArrays` uniform arrays); plus
|
|
54
|
+
* `hooks.extraUniforms`.
|
|
55
|
+
* - `bindings`: the scatter key → `scatterWeb` (or `null`), plus `null` for
|
|
56
|
+
* each excluded param that would otherwise auto-bind. (`style` and
|
|
57
|
+
* `durationMs` need no entry: `durationMs` is skipped by
|
|
58
|
+
* `computeScalarBinds`, and `style`'s conventional `uStyle` auto-bind is the
|
|
59
|
+
* same value the runner already sets as a standard uniform.)
|
|
60
|
+
* - `frame`: `tempo.frame.amp` + `tempo.frame.extras` evaluated per frame
|
|
61
|
+
* (extras keyed by canonical name, emitted under their `binding` web name).
|
|
62
|
+
* - `shadowHeightFrac`: `render.shadowHeightFrac` (bare number passes
|
|
63
|
+
* through; an expression is params-only — `{input}` throws).
|
|
64
|
+
* - `passUniforms`: `render.pass` evaluated ONCE PER PASS (canonical names →
|
|
65
|
+
* `binding` web names) over the resolved params + the pass-geometry inputs
|
|
66
|
+
* (`targetMinDimPx`, plus `sdfRange`/`sdfViewBoxW` from the first sampler
|
|
67
|
+
* with an `outline` source).
|
|
68
|
+
* - `auxTextures`: every `binding.samplers` entry with an `outline` whose
|
|
69
|
+
* baked SDF decodes → a `kind:"sdf"` spec at its `texture` unit, flipping
|
|
70
|
+
* its `on` extra to 1; absent/undecodable → analytic fallback.
|
|
71
|
+
* - `usesOrigin`: `render.config.usesOrigin`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function dopePassConfig(doc: DopeDoc, shader: DopeShader, hooks?: DopePassHooks): PassConfig;
|
|
74
|
+
/**
|
|
75
|
+
* Derive a {@link PanelConfig} (the Canvas2D-panel runner's config) from a
|
|
76
|
+
* datafied PANEL `.dope` + its shader + the one genuinely code-shaped piece —
|
|
77
|
+
* the per-frame Canvas2D `draw`. The derivation rules are the SAME as
|
|
78
|
+
* {@link dopePassConfig} (uniforms / bindings / `tempo.frame` /
|
|
79
|
+
* `render.shadowHeightFrac` / `render.pass`), with the panel runner's shape:
|
|
80
|
+
*
|
|
81
|
+
* - `panelSampler`: `render.panel.sampler` (required; `render.panel.texture`
|
|
82
|
+
* must be 0 — the panel runner binds the panel at TEXTURE0, the
|
|
83
|
+
* cross-platform panel slot).
|
|
84
|
+
* - `frame`: evaluated with `animMs := elapsedMs` — the panel runner never
|
|
85
|
+
* snaps "on twos" (declared as `render.config.stepping: "none"`).
|
|
86
|
+
* - `passUniforms`: `render.pass` over the resolved params + the pass inputs
|
|
87
|
+
* (`targetMinDimPx` from the targeted element box, `dpr`, and the SDF
|
|
88
|
+
* metadata when a sampler declares an outline).
|
|
89
|
+
*/
|
|
90
|
+
export declare function dopePanelConfig(doc: DopeDoc, shader: DopeShader, draw: PanelDraw, hooks?: Pick<DopePassHooks, "extraUniforms">): PanelConfig;
|
|
91
|
+
/** Options for {@link registerDopeEffect}. */
|
|
92
|
+
export interface RegisterDopeEffectOptions {
|
|
93
|
+
/** Code-shaped escape hatches forwarded to {@link dopePassConfig}. */
|
|
94
|
+
hooks?: DopePassHooks;
|
|
95
|
+
/**
|
|
96
|
+
* The registered effect/program name. Defaults to the last segment of
|
|
97
|
+
* `doc.id` (e.g. `dopamine.success.aurora` → `aurora`); pass explicitly when
|
|
98
|
+
* the public name differs (e.g. `dopamine.success.verdict` → `inkstroke`).
|
|
99
|
+
*/
|
|
100
|
+
name?: string;
|
|
101
|
+
/** Also register as a bundled program for `loadEffect()`. Default true. */
|
|
102
|
+
program?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Compose non-numeric, code-shaped params on top of the loader bag — applied
|
|
105
|
+
* to the factory's `resolve` AND forwarded to the bundled program.
|
|
106
|
+
*/
|
|
107
|
+
composeParams?: RenderProgram["composeParams"];
|
|
108
|
+
/** Override `tempo.reducedMotion`. */
|
|
109
|
+
reducedMotion?: {
|
|
110
|
+
peakMs?: number;
|
|
111
|
+
holdMs?: number;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build + register a fully data-driven effect from `(dope, shader, hooks)`:
|
|
116
|
+
* `resolve` is the `.dope` loader (with `render.consts` and the binding's
|
|
117
|
+
* scatter key), `create` is the generic pass runner over the derived config,
|
|
118
|
+
* and `reducedMotion` comes from `tempo.reducedMotion`. Registers the
|
|
119
|
+
* `EffectFactory` (and, by default, a bundled program under the same name) and
|
|
120
|
+
* returns the factory — the whole per-effect web factory, datafied.
|
|
121
|
+
*/
|
|
122
|
+
export declare function registerDopeEffect(doc: DopeDoc, shader: DopeShader, opts?: RegisterDopeEffectOptions): EffectFactory<PassParams>;
|
|
123
|
+
/**
|
|
124
|
+
* Build + register a data-driven Canvas2D-PANEL effect from
|
|
125
|
+
* `(dope, shader, draw)`: the same registration as {@link registerDopeEffect}
|
|
126
|
+
* but `create` is the generic PANEL runner over the {@link dopePanelConfig}
|
|
127
|
+
* derivation. The only hand-written web sources left for such an effect are
|
|
128
|
+
* its GLSL and the Canvas2D `draw` — the per-platform panel-draw seam.
|
|
129
|
+
*/
|
|
130
|
+
export declare function registerDopePanelEffect(doc: DopeDoc, shader: DopeShader, draw: PanelDraw, opts?: RegisterDopeEffectOptions): EffectFactory<PassParams>;
|
|
131
|
+
//# sourceMappingURL=dope-pass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dope-pass.d.ts","sourceRoot":"","sources":["../../src/framework/dope-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,EAAiC,KAAK,OAAO,EAAoB,MAAM,aAAa,CAAC;AAE5F,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAuB,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE1F,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAiB,aAAa,EAAgC,MAAM,aAAa,CAAC;AAE9F,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,OAAO,CACjC,IAAI,CAAC,UAAU,EAAE,aAAa,GAAG,cAAc,GAAG,OAAO,GAAG,aAAa,CAAC,CAC3E,GAAG;IACF,0EAA0E;IAC1E,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CACtD,CAAC;AAEF,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AA6ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,GAAE,aAAkB,GAAG,UAAU,CAoFtG;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,SAAS,EACf,KAAK,GAAE,IAAI,CAAC,aAAa,EAAE,eAAe,CAAM,GAC/C,WAAW,CAwDb;AAED,8CAA8C;AAC9C,MAAM,WAAW,yBAAyB;IACxC,sEAAsE;IACtE,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,sCAAsC;IACtC,aAAa,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,IAAI,GAAE,yBAA8B,GACnC,aAAa,CAAC,UAAU,CAAC,CAK3B;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,SAAS,EACf,IAAI,GAAE,yBAA8B,GACnC,aAAa,CAAC,UAAU,CAAC,CAK3B"}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic DATA-DRIVEN pass factory — instantiates a pure-shader effect from
|
|
3
|
+
* `(dope, shader, hooks)` with no per-effect factory code.
|
|
4
|
+
*
|
|
5
|
+
* For a datafied effect the `.dope` carries everything the hand-written
|
|
6
|
+
* per-effect `PassConfig` used to: the per-frame logic (`tempo.frame`), the
|
|
7
|
+
* shadow height (`render.shadowHeightFrac`), the per-pass uniforms
|
|
8
|
+
* (`render.pass`), the SDF-sourced samplers (`binding.samplers[].outline`),
|
|
9
|
+
* the loop-cap consts (`render.consts`), the runner config
|
|
10
|
+
* (`render.config.usesOrigin`), the reduced-motion peak/hold
|
|
11
|
+
* (`tempo.reducedMotion`) and the uniform-binding contract (`binding`). This
|
|
12
|
+
* module derives the `PassConfig` from that data — uniform names by the same
|
|
13
|
+
* `name → u<Name>` convention `computeScalarBinds` applies, exceptions from
|
|
14
|
+
* the binding contract — so the only hand-written web source left for such an
|
|
15
|
+
* effect is its GLSL.
|
|
16
|
+
*
|
|
17
|
+
* The honest boundary stays honest: anything genuinely code-shaped (a sprite
|
|
18
|
+
* panel, frame arrays, a host-rasterized aux texture) is passed through
|
|
19
|
+
* `hooks`, the same seams `PassConfig` always had — and a hook overrides the
|
|
20
|
+
* derived `auxTextures`/`passUniforms` when both exist.
|
|
21
|
+
*/
|
|
22
|
+
import { decodeSdf } from "../engine/sdf.js";
|
|
23
|
+
import { evalFrameExpr, evalParamExpr, evalPassExpr } from "./frame-expr.js";
|
|
24
|
+
import { getOutline, resolveDopeParams } from "./loader.js";
|
|
25
|
+
import { cap } from "./pass-common.js";
|
|
26
|
+
import { createPassInstance, } from "./pass-runner.js";
|
|
27
|
+
import { createPanelInstance } from "./panel-runner.js";
|
|
28
|
+
import { registerEffect } from "./registry.js";
|
|
29
|
+
import { registerProgram } from "./programs.js";
|
|
30
|
+
/**
|
|
31
|
+
* The shared pass/panel derivation over a datafied `.dope`: the uniform list,
|
|
32
|
+
* the binding exceptions, the per-frame and per-pass expression tables and the
|
|
33
|
+
* declared SDF pass inputs — everything both `dopePassConfig` and
|
|
34
|
+
* `dopePanelConfig` read identically (the rules in the {@link dopePassConfig}
|
|
35
|
+
* doc comment).
|
|
36
|
+
*/
|
|
37
|
+
function deriveDope(doc, extraUniforms) {
|
|
38
|
+
const binding = doc.binding ?? {};
|
|
39
|
+
const exclude = binding.excludeParams ?? [];
|
|
40
|
+
const scatterKey = binding.scatterKey ?? undefined;
|
|
41
|
+
const extraDefs = binding.extras ?? [];
|
|
42
|
+
const frameSpec = doc.tempo.frame;
|
|
43
|
+
if (!frameSpec)
|
|
44
|
+
throw new Error(`dope: ${doc.id} has no tempo.frame (not a datafied effect)`);
|
|
45
|
+
const loopPeriodMs = doc.tempo.loop?.periodMs;
|
|
46
|
+
const shadowSpec = doc.render.shadowHeightFrac;
|
|
47
|
+
if (shadowSpec === undefined) {
|
|
48
|
+
throw new Error(`dope: ${doc.id} has no render.shadowHeightFrac (not a datafied effect)`);
|
|
49
|
+
}
|
|
50
|
+
// --- uniforms ------------------------------------------------------------
|
|
51
|
+
const uniforms = new Set();
|
|
52
|
+
for (const name of Object.keys(doc.render.params)) {
|
|
53
|
+
if (exclude.includes(name) || name === scatterKey)
|
|
54
|
+
continue;
|
|
55
|
+
uniforms.add(cap(name));
|
|
56
|
+
}
|
|
57
|
+
if (scatterKey && binding.scatterWeb)
|
|
58
|
+
uniforms.add(binding.scatterWeb);
|
|
59
|
+
for (const e of extraDefs)
|
|
60
|
+
if (e.web)
|
|
61
|
+
uniforms.add(e.web);
|
|
62
|
+
for (const s of binding.samplers ?? [])
|
|
63
|
+
uniforms.add(typeof s === "string" ? s : s.web);
|
|
64
|
+
for (const a of binding.arrays ?? [])
|
|
65
|
+
uniforms.add(a.web);
|
|
66
|
+
for (const u of extraUniforms ?? [])
|
|
67
|
+
uniforms.add(u);
|
|
68
|
+
// --- bindings (exceptions to the `name → u<Name>` auto-bind) --------------
|
|
69
|
+
const bindings = {};
|
|
70
|
+
if (scatterKey)
|
|
71
|
+
bindings[scatterKey] = binding.scatterWeb ?? null;
|
|
72
|
+
for (const name of exclude) {
|
|
73
|
+
if (name === "style" || name === "durationMs")
|
|
74
|
+
continue; // see doc comment
|
|
75
|
+
bindings[name] = null;
|
|
76
|
+
}
|
|
77
|
+
// --- per-frame extras: canonical name → web uniform name ------------------
|
|
78
|
+
const extraExprs = Object.entries(frameSpec.extras ?? {}).map(([name, expr]) => {
|
|
79
|
+
const def = extraDefs.find((e) => e.name === name);
|
|
80
|
+
if (!def?.web) {
|
|
81
|
+
throw new Error(`dope: ${doc.id} tempo.frame.extras."${name}" has no binding.extras web name`);
|
|
82
|
+
}
|
|
83
|
+
return [def.web, expr];
|
|
84
|
+
});
|
|
85
|
+
// --- per-PASS uniforms (`render.pass`): canonical name → web uniform name --
|
|
86
|
+
// (a "note" key is documentation, not an expression — same convention as
|
|
87
|
+
// `binding.note`.)
|
|
88
|
+
const passExprs = Object.entries(doc.render.pass ?? {})
|
|
89
|
+
.filter(([name]) => name !== "note")
|
|
90
|
+
.map(([name, expr]) => {
|
|
91
|
+
const def = extraDefs.find((e) => e.name === name);
|
|
92
|
+
if (!def?.web) {
|
|
93
|
+
throw new Error(`dope: ${doc.id} render.pass."${name}" has no binding.extras web name`);
|
|
94
|
+
}
|
|
95
|
+
return [def.web, expr];
|
|
96
|
+
});
|
|
97
|
+
// SDF-sourced samplers: the first `outline` sampler supplies the pass-expr
|
|
98
|
+
// SDF inputs (declared metadata — readable even where the bitmap isn't bound).
|
|
99
|
+
const samplerDefs = (binding.samplers ?? []).filter((s) => typeof s !== "string");
|
|
100
|
+
const sdfOutline = samplerDefs.find((s) => s.outline);
|
|
101
|
+
const sdfSrc = sdfOutline ? getOutline(doc, sdfOutline.outline)?.sdf : undefined;
|
|
102
|
+
const sdfInputs = { range: sdfSrc?.range ?? 0, viewBoxW: sdfSrc?.viewBox?.[2] ?? 0 };
|
|
103
|
+
return { binding, frameSpec, loopPeriodMs, shadowSpec, uniforms, bindings, extraExprs, passExprs, sdfInputs };
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Derive a {@link PassConfig} from a datafied `.dope` + its shader (+ optional
|
|
107
|
+
* code hooks). The derived contract is pinned by the per-effect dope-config
|
|
108
|
+
* vitests:
|
|
109
|
+
*
|
|
110
|
+
* - `uniforms`: every `render.params` key not in `binding.excludeParams` and
|
|
111
|
+
* not the scatter key → `u<Name>`; the scatter key contributes
|
|
112
|
+
* `binding.scatterWeb` when present (else it is not a shader uniform); every
|
|
113
|
+
* `binding.extras[].web`; every `binding.samplers[].web`; every
|
|
114
|
+
* `binding.arrays[].web` (the `frameArrays` uniform arrays); plus
|
|
115
|
+
* `hooks.extraUniforms`.
|
|
116
|
+
* - `bindings`: the scatter key → `scatterWeb` (or `null`), plus `null` for
|
|
117
|
+
* each excluded param that would otherwise auto-bind. (`style` and
|
|
118
|
+
* `durationMs` need no entry: `durationMs` is skipped by
|
|
119
|
+
* `computeScalarBinds`, and `style`'s conventional `uStyle` auto-bind is the
|
|
120
|
+
* same value the runner already sets as a standard uniform.)
|
|
121
|
+
* - `frame`: `tempo.frame.amp` + `tempo.frame.extras` evaluated per frame
|
|
122
|
+
* (extras keyed by canonical name, emitted under their `binding` web name).
|
|
123
|
+
* - `shadowHeightFrac`: `render.shadowHeightFrac` (bare number passes
|
|
124
|
+
* through; an expression is params-only — `{input}` throws).
|
|
125
|
+
* - `passUniforms`: `render.pass` evaluated ONCE PER PASS (canonical names →
|
|
126
|
+
* `binding` web names) over the resolved params + the pass-geometry inputs
|
|
127
|
+
* (`targetMinDimPx`, plus `sdfRange`/`sdfViewBoxW` from the first sampler
|
|
128
|
+
* with an `outline` source).
|
|
129
|
+
* - `auxTextures`: every `binding.samplers` entry with an `outline` whose
|
|
130
|
+
* baked SDF decodes → a `kind:"sdf"` spec at its `texture` unit, flipping
|
|
131
|
+
* its `on` extra to 1; absent/undecodable → analytic fallback.
|
|
132
|
+
* - `usesOrigin`: `render.config.usesOrigin`.
|
|
133
|
+
*/
|
|
134
|
+
export function dopePassConfig(doc, shader, hooks = {}) {
|
|
135
|
+
const { binding, frameSpec, loopPeriodMs, shadowSpec, uniforms, bindings, extraExprs, passExprs, sdfInputs } = deriveDope(doc, hooks.extraUniforms);
|
|
136
|
+
const derivedPassUniforms = passExprs.length
|
|
137
|
+
? (_canvas, params, targetPx, dpr) => {
|
|
138
|
+
const pass = {
|
|
139
|
+
targetMinDimPx: Math.min(targetPx.width, targetPx.height),
|
|
140
|
+
sdfRange: sdfInputs.range,
|
|
141
|
+
sdfViewBoxW: sdfInputs.viewBoxW,
|
|
142
|
+
dpr,
|
|
143
|
+
};
|
|
144
|
+
const out = {};
|
|
145
|
+
for (const [web, expr] of passExprs)
|
|
146
|
+
out[web] = evalPassExpr(expr, params, pass);
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
: undefined;
|
|
150
|
+
// The declarative dynamic-panel WIRING (`render.panel`): the unit + sampler
|
|
151
|
+
// are data; the Canvas2D draw is the code-shaped hook. (A whole `hooks.panel`
|
|
152
|
+
// still overrides, like the other hooks.)
|
|
153
|
+
const panelSpec = doc.render.panel;
|
|
154
|
+
const derivedPanel = panelSpec && hooks.panelDraw
|
|
155
|
+
? { unit: panelSpec.texture ?? 0, sampler: panelSpec.sampler, draw: hooks.panelDraw }
|
|
156
|
+
: undefined;
|
|
157
|
+
// Declarative aux textures: each sampler with an `outline` whose baked SDF
|
|
158
|
+
// decodes becomes a kind:"sdf" spec (its `on` extra flips to 1 when bound);
|
|
159
|
+
// an absent/undecodable SDF contributes nothing — the analytic fallback.
|
|
160
|
+
const extraDefs = binding.extras ?? [];
|
|
161
|
+
const samplerDefs = (binding.samplers ?? []).filter((s) => typeof s !== "string");
|
|
162
|
+
const sdfAux = [];
|
|
163
|
+
for (const s of samplerDefs) {
|
|
164
|
+
if (!s.outline)
|
|
165
|
+
continue;
|
|
166
|
+
const baked = getOutline(doc, s.outline)?.sdf;
|
|
167
|
+
if (!baked)
|
|
168
|
+
continue;
|
|
169
|
+
try {
|
|
170
|
+
const onDef = s.on ? extraDefs.find((e) => e.name === s.on) : undefined;
|
|
171
|
+
sdfAux.push({
|
|
172
|
+
kind: "sdf",
|
|
173
|
+
unit: s.texture ?? 0,
|
|
174
|
+
sdf: decodeSdf(baked),
|
|
175
|
+
sampler: s.web,
|
|
176
|
+
onUniform: onDef?.web,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
/* undecodable → analytic fallback */
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const derivedAux = sdfAux.length ? () => sdfAux : undefined;
|
|
184
|
+
return {
|
|
185
|
+
vertex: shader.vertex,
|
|
186
|
+
fragment: shader.fragment,
|
|
187
|
+
uniforms: [...uniforms],
|
|
188
|
+
usesOrigin: doc.render.config?.usesOrigin ?? false,
|
|
189
|
+
loopPeriodMs,
|
|
190
|
+
bindings,
|
|
191
|
+
shadowHeightFrac: typeof shadowSpec === "number" ? shadowSpec : (params) => evalParamExpr(shadowSpec, params),
|
|
192
|
+
frame(info, params) {
|
|
193
|
+
// Loop clocks (0 without tempo.loop) — the SAME formula the runner uses
|
|
194
|
+
// for uLoopS/uPhase, so a `{input:"phase"}` amp matches the shader.
|
|
195
|
+
const loopMs = loopPeriodMs ? info.animMs % loopPeriodMs : 0;
|
|
196
|
+
const ctx = {
|
|
197
|
+
animMs: info.animMs,
|
|
198
|
+
life: info.life,
|
|
199
|
+
elapsedMs: info.elapsedMs,
|
|
200
|
+
params,
|
|
201
|
+
loopS: loopMs / 1000,
|
|
202
|
+
phase: loopPeriodMs ? loopMs / loopPeriodMs : 0,
|
|
203
|
+
};
|
|
204
|
+
const out = {
|
|
205
|
+
amp: evalFrameExpr(frameSpec.amp, ctx),
|
|
206
|
+
};
|
|
207
|
+
for (const [web, expr] of extraExprs)
|
|
208
|
+
out[web] = evalFrameExpr(expr, ctx);
|
|
209
|
+
return out;
|
|
210
|
+
},
|
|
211
|
+
auxTextures: hooks.auxTextures ?? derivedAux,
|
|
212
|
+
passUniforms: hooks.passUniforms ?? derivedPassUniforms,
|
|
213
|
+
panel: hooks.panel ?? derivedPanel,
|
|
214
|
+
frameArrays: hooks.frameArrays,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Derive a {@link PanelConfig} (the Canvas2D-panel runner's config) from a
|
|
219
|
+
* datafied PANEL `.dope` + its shader + the one genuinely code-shaped piece —
|
|
220
|
+
* the per-frame Canvas2D `draw`. The derivation rules are the SAME as
|
|
221
|
+
* {@link dopePassConfig} (uniforms / bindings / `tempo.frame` /
|
|
222
|
+
* `render.shadowHeightFrac` / `render.pass`), with the panel runner's shape:
|
|
223
|
+
*
|
|
224
|
+
* - `panelSampler`: `render.panel.sampler` (required; `render.panel.texture`
|
|
225
|
+
* must be 0 — the panel runner binds the panel at TEXTURE0, the
|
|
226
|
+
* cross-platform panel slot).
|
|
227
|
+
* - `frame`: evaluated with `animMs := elapsedMs` — the panel runner never
|
|
228
|
+
* snaps "on twos" (declared as `render.config.stepping: "none"`).
|
|
229
|
+
* - `passUniforms`: `render.pass` over the resolved params + the pass inputs
|
|
230
|
+
* (`targetMinDimPx` from the targeted element box, `dpr`, and the SDF
|
|
231
|
+
* metadata when a sampler declares an outline).
|
|
232
|
+
*/
|
|
233
|
+
export function dopePanelConfig(doc, shader, draw, hooks = {}) {
|
|
234
|
+
const { frameSpec, shadowSpec, uniforms, bindings, extraExprs, passExprs, sdfInputs } = deriveDope(doc, hooks.extraUniforms);
|
|
235
|
+
const panelSpec = doc.render.panel;
|
|
236
|
+
if (!panelSpec)
|
|
237
|
+
throw new Error(`dope: ${doc.id} has no render.panel (not a panel effect)`);
|
|
238
|
+
if ((panelSpec.texture ?? 0) !== 0) {
|
|
239
|
+
throw new Error(`dope: ${doc.id} render.panel.texture must be 0 for a panel-kind effect (TEXTURE0 is the panel slot)`);
|
|
240
|
+
}
|
|
241
|
+
if (doc.tempo.loop)
|
|
242
|
+
throw new Error(`dope: ${doc.id} tempo.loop is not supported by the panel runner`);
|
|
243
|
+
const derivedPassUniforms = passExprs.length
|
|
244
|
+
? (_canvas, params, dpr, targetPx) => {
|
|
245
|
+
const pass = {
|
|
246
|
+
targetMinDimPx: Math.min(targetPx.width, targetPx.height),
|
|
247
|
+
sdfRange: sdfInputs.range,
|
|
248
|
+
sdfViewBoxW: sdfInputs.viewBoxW,
|
|
249
|
+
dpr,
|
|
250
|
+
};
|
|
251
|
+
const out = {};
|
|
252
|
+
for (const [web, expr] of passExprs)
|
|
253
|
+
out[web] = evalPassExpr(expr, params, pass);
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
256
|
+
: undefined;
|
|
257
|
+
return {
|
|
258
|
+
vertex: shader.vertex,
|
|
259
|
+
fragment: shader.fragment,
|
|
260
|
+
uniforms: [...uniforms],
|
|
261
|
+
panelSampler: panelSpec.sampler,
|
|
262
|
+
bindings,
|
|
263
|
+
shadowHeightFrac: typeof shadowSpec === "number" ? shadowSpec : (params) => evalParamExpr(shadowSpec, params),
|
|
264
|
+
draw,
|
|
265
|
+
frame(info, params) {
|
|
266
|
+
// Panels never snap on twos (`render.config.stepping: "none"`), so the
|
|
267
|
+
// snapped clock IS the wall clock — `animMs := elapsedMs`.
|
|
268
|
+
const ctx = {
|
|
269
|
+
animMs: info.elapsedMs,
|
|
270
|
+
life: info.life,
|
|
271
|
+
elapsedMs: info.elapsedMs,
|
|
272
|
+
params,
|
|
273
|
+
loopS: 0,
|
|
274
|
+
phase: 0,
|
|
275
|
+
};
|
|
276
|
+
const out = {
|
|
277
|
+
amp: evalFrameExpr(frameSpec.amp, ctx),
|
|
278
|
+
};
|
|
279
|
+
for (const [web, expr] of extraExprs)
|
|
280
|
+
out[web] = evalFrameExpr(expr, ctx);
|
|
281
|
+
return out;
|
|
282
|
+
},
|
|
283
|
+
passUniforms: derivedPassUniforms,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Build + register a fully data-driven effect from `(dope, shader, hooks)`:
|
|
288
|
+
* `resolve` is the `.dope` loader (with `render.consts` and the binding's
|
|
289
|
+
* scatter key), `create` is the generic pass runner over the derived config,
|
|
290
|
+
* and `reducedMotion` comes from `tempo.reducedMotion`. Registers the
|
|
291
|
+
* `EffectFactory` (and, by default, a bundled program under the same name) and
|
|
292
|
+
* returns the factory — the whole per-effect web factory, datafied.
|
|
293
|
+
*/
|
|
294
|
+
export function registerDopeEffect(doc, shader, opts = {}) {
|
|
295
|
+
const config = dopePassConfig(doc, shader, opts.hooks);
|
|
296
|
+
const create = (params, ctx) => createPassInstance(config, params, ctx);
|
|
297
|
+
return registerDerived(doc, create, opts);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Build + register a data-driven Canvas2D-PANEL effect from
|
|
301
|
+
* `(dope, shader, draw)`: the same registration as {@link registerDopeEffect}
|
|
302
|
+
* but `create` is the generic PANEL runner over the {@link dopePanelConfig}
|
|
303
|
+
* derivation. The only hand-written web sources left for such an effect are
|
|
304
|
+
* its GLSL and the Canvas2D `draw` — the per-platform panel-draw seam.
|
|
305
|
+
*/
|
|
306
|
+
export function registerDopePanelEffect(doc, shader, draw, opts = {}) {
|
|
307
|
+
const config = dopePanelConfig(doc, shader, draw, { extraUniforms: opts.hooks?.extraUniforms });
|
|
308
|
+
const create = (params, ctx) => createPanelInstance(config, params, ctx);
|
|
309
|
+
return registerDerived(doc, create, opts);
|
|
310
|
+
}
|
|
311
|
+
/** The shared registration tail: resolve/reducedMotion/loop + the bundled program. */
|
|
312
|
+
function registerDerived(doc, create, opts) {
|
|
313
|
+
const scatterKey = doc.binding?.scatterKey;
|
|
314
|
+
if (!scatterKey)
|
|
315
|
+
throw new Error(`dope: ${doc.id} has no binding.scatterKey`);
|
|
316
|
+
const consts = doc.render.consts ?? {};
|
|
317
|
+
const name = opts.name ?? doc.id.split(".").pop();
|
|
318
|
+
const reducedMotion = opts.reducedMotion ?? doc.tempo.reducedMotion;
|
|
319
|
+
const factory = {
|
|
320
|
+
name,
|
|
321
|
+
resolve: (feeling) => {
|
|
322
|
+
const numeric = resolveDopeParams(doc, feeling, consts, scatterKey);
|
|
323
|
+
return (opts.composeParams
|
|
324
|
+
? opts.composeParams(numeric, feeling)
|
|
325
|
+
: numeric);
|
|
326
|
+
},
|
|
327
|
+
create,
|
|
328
|
+
reducedMotion,
|
|
329
|
+
// The continuous-loop contract: the conductor re-arms at durationMs instead
|
|
330
|
+
// of tearing down (the host stops it via the returned handle).
|
|
331
|
+
loop: doc.tempo.loop ? { periodMs: doc.tempo.loop.periodMs } : undefined,
|
|
332
|
+
};
|
|
333
|
+
if (opts.program !== false) {
|
|
334
|
+
// Expose as a bundled program so loadEffect() can bind host-authored
|
|
335
|
+
// variants of this effect's .dope with no code.
|
|
336
|
+
registerProgram(name, {
|
|
337
|
+
create,
|
|
338
|
+
scatterKey,
|
|
339
|
+
consts,
|
|
340
|
+
reducedMotion,
|
|
341
|
+
...(opts.composeParams ? { composeParams: opts.composeParams } : {}),
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
return registerEffect(factory);
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=dope-pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dope-pass.js","sourceRoot":"","sources":["../../src/framework/dope-pass.ts"],"names":[],"mappings":"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"}
|