shadertown 0.1.0 → 0.2.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/README.md +20 -0
- package/dist/export.d.ts.map +1 -1
- package/dist/export.js +55 -5
- package/dist/export.js.map +1 -1
- package/dist/generated/sources.d.ts +41 -0
- package/dist/generated/sources.d.ts.map +1 -1
- package/dist/generated/sources.js +41 -0
- package/dist/generated/sources.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +8 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +23 -1
- package/dist/react.js.map +1 -1
- package/dist/registry.d.ts +1050 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +642 -0
- package/dist/registry.js.map +1 -1
- package/dist/renderer.d.ts +15 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +127 -0
- package/dist/renderer.js.map +1 -1
- package/dist/source.d.ts +56 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +191 -0
- package/dist/source.js.map +1 -0
- package/dist/stage.d.ts +13 -1
- package/dist/stage.d.ts.map +1 -1
- package/dist/stage.js +5 -1
- package/dist/stage.js.map +1 -1
- package/dist/types.d.ts +21 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/source.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { effect, sampler, target } from "vgpu";
|
|
2
|
+
import { shaderSources } from "./generated/sources.js";
|
|
3
|
+
import { resolveUniforms } from "./params.js";
|
|
4
|
+
export function isSourceLayer(input) {
|
|
5
|
+
return typeof input === "object" && input !== null && "shader" in input;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A shadertown shader rendered into an offscreen target, one pass ahead of the
|
|
9
|
+
* shader that reads it.
|
|
10
|
+
*
|
|
11
|
+
* The target tracks the canvas pixel for pixel, so the two agree on aspect and
|
|
12
|
+
* the fit maths reduces to the identity — a stacked pair costs one extra pass
|
|
13
|
+
* and no resampling.
|
|
14
|
+
*/
|
|
15
|
+
class LayerBackdrop {
|
|
16
|
+
stage;
|
|
17
|
+
shader;
|
|
18
|
+
params;
|
|
19
|
+
fit = 0;
|
|
20
|
+
recreated = new Set();
|
|
21
|
+
board;
|
|
22
|
+
pass;
|
|
23
|
+
time = 0;
|
|
24
|
+
width;
|
|
25
|
+
height;
|
|
26
|
+
constructor(stage, shader, params, width, height, startTime) {
|
|
27
|
+
this.stage = stage;
|
|
28
|
+
this.shader = shader;
|
|
29
|
+
this.params = params;
|
|
30
|
+
this.width = Math.max(1, Math.round(width));
|
|
31
|
+
this.height = Math.max(1, Math.round(height));
|
|
32
|
+
this.time = startTime;
|
|
33
|
+
this.board = target(stage.gpu, {
|
|
34
|
+
size: [this.width, this.height],
|
|
35
|
+
format: BACKDROP_FORMAT,
|
|
36
|
+
label: `shadertown:source:${shader}`,
|
|
37
|
+
});
|
|
38
|
+
this.pass = effect(stage.gpu, shaderSources[shader], {
|
|
39
|
+
label: `shadertown:source:${shader}`,
|
|
40
|
+
set: { params: this.uniforms(0) },
|
|
41
|
+
});
|
|
42
|
+
this.pass.compileSync({ colors: [BACKDROP_FORMAT] });
|
|
43
|
+
}
|
|
44
|
+
get texture() {
|
|
45
|
+
return this.board.color;
|
|
46
|
+
}
|
|
47
|
+
get size() {
|
|
48
|
+
return [this.width, this.height];
|
|
49
|
+
}
|
|
50
|
+
onRecreate(cb) {
|
|
51
|
+
this.recreated.add(cb);
|
|
52
|
+
return () => this.recreated.delete(cb);
|
|
53
|
+
}
|
|
54
|
+
prepare(frame, deltaTime) {
|
|
55
|
+
this.time += deltaTime;
|
|
56
|
+
this.pass.set({ params: this.uniforms(this.time) });
|
|
57
|
+
frame.pass(this.board, this.pass);
|
|
58
|
+
}
|
|
59
|
+
resize(width, height) {
|
|
60
|
+
const w = Math.max(1, Math.round(width));
|
|
61
|
+
const h = Math.max(1, Math.round(height));
|
|
62
|
+
if (w === this.width && h === this.height)
|
|
63
|
+
return;
|
|
64
|
+
this.width = w;
|
|
65
|
+
this.height = h;
|
|
66
|
+
this.board.resize([w, h]);
|
|
67
|
+
// Resizing hands back new textures, so anything holding the old view has
|
|
68
|
+
// to rebind before it reads a destroyed one.
|
|
69
|
+
for (const cb of this.recreated)
|
|
70
|
+
cb();
|
|
71
|
+
}
|
|
72
|
+
destroy() {
|
|
73
|
+
this.recreated.clear();
|
|
74
|
+
// An offscreen target's textures belong to the device and go with it, so
|
|
75
|
+
// `destroy` is an early release rather than a requirement — and it is not
|
|
76
|
+
// on the public `Target` shape.
|
|
77
|
+
this.board.destroy?.();
|
|
78
|
+
}
|
|
79
|
+
uniforms(time) {
|
|
80
|
+
return resolveUniforms(this.shader, this.params, {
|
|
81
|
+
resolution: [this.width, this.height],
|
|
82
|
+
pointer: [0.5, 0.5],
|
|
83
|
+
time,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** A still image, uploaded once and then just read. */
|
|
88
|
+
class LayerImage {
|
|
89
|
+
texture;
|
|
90
|
+
size;
|
|
91
|
+
fit = 1;
|
|
92
|
+
constructor(texture, size) {
|
|
93
|
+
this.texture = texture;
|
|
94
|
+
this.size = size;
|
|
95
|
+
}
|
|
96
|
+
onRecreate() {
|
|
97
|
+
return () => { };
|
|
98
|
+
}
|
|
99
|
+
prepare() {
|
|
100
|
+
/* nothing to draw — the texture is already there */
|
|
101
|
+
}
|
|
102
|
+
resize() {
|
|
103
|
+
/* the image keeps its own size; `fit` handles the mismatch */
|
|
104
|
+
}
|
|
105
|
+
destroy() {
|
|
106
|
+
this.texture.destroy();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** A video, re-uploaded each frame while it plays. */
|
|
110
|
+
class LayerVideo {
|
|
111
|
+
stage;
|
|
112
|
+
video;
|
|
113
|
+
texture;
|
|
114
|
+
size;
|
|
115
|
+
fit = 1;
|
|
116
|
+
lastTime = -1;
|
|
117
|
+
constructor(stage, video, texture, size) {
|
|
118
|
+
this.stage = stage;
|
|
119
|
+
this.video = video;
|
|
120
|
+
this.texture = texture;
|
|
121
|
+
this.size = size;
|
|
122
|
+
}
|
|
123
|
+
onRecreate() {
|
|
124
|
+
return () => { };
|
|
125
|
+
}
|
|
126
|
+
prepare() {
|
|
127
|
+
// A paused video is the same frame every time; copying it again is waste.
|
|
128
|
+
if (this.video.readyState < 2 || this.video.currentTime === this.lastTime)
|
|
129
|
+
return;
|
|
130
|
+
this.lastTime = this.video.currentTime;
|
|
131
|
+
copyImageToTexture(this.stage, this.video, this.texture, this.size);
|
|
132
|
+
}
|
|
133
|
+
resize() {
|
|
134
|
+
/* the video keeps its own size */
|
|
135
|
+
}
|
|
136
|
+
destroy() {
|
|
137
|
+
this.texture.destroy();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const BACKDROP_FORMAT = "rgba8unorm";
|
|
141
|
+
/** Linear and clamped: a source shader reads between texels and off the edge. */
|
|
142
|
+
export function sourceSampler(stage) {
|
|
143
|
+
return sampler(stage.gpu, {
|
|
144
|
+
magFilter: "linear",
|
|
145
|
+
minFilter: "linear",
|
|
146
|
+
addressModeU: "clamp-to-edge",
|
|
147
|
+
addressModeV: "clamp-to-edge",
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function imageSize(image) {
|
|
151
|
+
if (image instanceof HTMLVideoElement) {
|
|
152
|
+
return [Math.max(1, image.videoWidth), Math.max(1, image.videoHeight)];
|
|
153
|
+
}
|
|
154
|
+
if (image instanceof HTMLImageElement) {
|
|
155
|
+
return [Math.max(1, image.naturalWidth), Math.max(1, image.naturalHeight)];
|
|
156
|
+
}
|
|
157
|
+
return [Math.max(1, image.width), Math.max(1, image.height)];
|
|
158
|
+
}
|
|
159
|
+
function copyImageToTexture(stage, image, texture, size) {
|
|
160
|
+
stage.gpu.gpu.queue.copyExternalImageToTexture({ source: image, flipY: false }, { texture: texture.gpu, premultipliedAlpha: false }, size);
|
|
161
|
+
}
|
|
162
|
+
async function decode(url) {
|
|
163
|
+
const response = await fetch(url, { mode: "cors" });
|
|
164
|
+
if (!response.ok)
|
|
165
|
+
throw new Error(`shadertown: could not load source image (${response.status})`);
|
|
166
|
+
return createImageBitmap(await response.blob());
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Builds the layer a source shader reads.
|
|
170
|
+
*
|
|
171
|
+
* `startTime` only matters for a shader backdrop: it keeps a stacked pair in
|
|
172
|
+
* step with the grid offset the card was given.
|
|
173
|
+
*/
|
|
174
|
+
export async function createSourceLayer(stage, input, canvas) {
|
|
175
|
+
if (isSourceLayer(input)) {
|
|
176
|
+
return new LayerBackdrop(stage, input.shader, input.params ?? {}, canvas.width, canvas.height, canvas.startTime);
|
|
177
|
+
}
|
|
178
|
+
const image = typeof input === "string" ? await decode(input) : input;
|
|
179
|
+
const size = imageSize(image);
|
|
180
|
+
const texture = stage.gpu.device.createTexture({
|
|
181
|
+
size,
|
|
182
|
+
format: BACKDROP_FORMAT,
|
|
183
|
+
usage: ["texture_binding", "copy_dst", "render_attachment"],
|
|
184
|
+
label: "shadertown:source:image",
|
|
185
|
+
});
|
|
186
|
+
copyImageToTexture(stage, image, texture, size);
|
|
187
|
+
if (image instanceof HTMLVideoElement)
|
|
188
|
+
return new LayerVideo(stage, image, texture, size);
|
|
189
|
+
return new LayerImage(texture, size);
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
|
package/dist/stage.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Effect, Gpu, Surface } from "vgpu";
|
|
1
|
+
import type { Effect, Frame, Gpu, Surface } from "vgpu";
|
|
2
2
|
import type { ShaderName } from "./registry.js";
|
|
3
3
|
import type { ResolvedUniforms } from "./types.js";
|
|
4
4
|
/**
|
|
@@ -15,8 +15,20 @@ export interface StageInstance {
|
|
|
15
15
|
active: boolean;
|
|
16
16
|
/** Set when the instance wants exactly one more frame while paused. */
|
|
17
17
|
dirty: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Held out of the loop entirely. A source shader whose layer is still being
|
|
20
|
+
* built has a binding pointing at nothing, and drawing it would fault.
|
|
21
|
+
*/
|
|
22
|
+
blocked?: boolean;
|
|
18
23
|
localTime: number;
|
|
19
24
|
update(deltaTime: number): ResolvedUniforms;
|
|
25
|
+
/**
|
|
26
|
+
* Encoded just before this instance's own pass, into the same frame.
|
|
27
|
+
*
|
|
28
|
+
* A source shader draws its backdrop here, so the texture it is about to read
|
|
29
|
+
* is written by an earlier pass of the same command buffer.
|
|
30
|
+
*/
|
|
31
|
+
prepare?(frame: Frame, deltaTime: number): void;
|
|
20
32
|
}
|
|
21
33
|
export declare class Stage {
|
|
22
34
|
readonly gpu: Gpu;
|
package/dist/stage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAmB,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAmB,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5C;;;;;OAKG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACjD;AAED,qBAAa,KAAK;IAChB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,QAAQ,CAAK;gBAET,GAAG,EAAE,GAAG;IAIpB,GAAG,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAKlC,MAAM,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAKrC,2EAA2E;IAC3E,IAAI,IAAI,IAAI;IA6BZ,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,KAAK;CAId;AAID,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,gDAAgD;AAChD,wBAAgB,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,CAKzC;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAET;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAK9F"}
|
package/dist/stage.js
CHANGED
|
@@ -29,11 +29,15 @@ export class Stage {
|
|
|
29
29
|
this.lastTime = now;
|
|
30
30
|
let drew = false;
|
|
31
31
|
for (const instance of this.instances) {
|
|
32
|
+
if (instance.blocked)
|
|
33
|
+
continue;
|
|
32
34
|
if (!instance.active && !instance.dirty)
|
|
33
35
|
continue;
|
|
34
36
|
if (instance.surface.disposed)
|
|
35
37
|
continue;
|
|
36
|
-
const
|
|
38
|
+
const step = instance.active ? delta : 0;
|
|
39
|
+
instance.prepare?.(frame, step);
|
|
40
|
+
const uniforms = instance.update(step);
|
|
37
41
|
instance.effect.set({ params: uniforms });
|
|
38
42
|
frame.pass(instance.surface, instance.effect);
|
|
39
43
|
instance.dirty = false;
|
package/dist/stage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage.js","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"stage.js","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -24,7 +24,19 @@ export interface ColorControl {
|
|
|
24
24
|
readonly default: string;
|
|
25
25
|
readonly hint?: string;
|
|
26
26
|
}
|
|
27
|
-
export type ShaderFamily = "gradient" | "organic" | "geometric" | "fractal" | "spatial" | "texture";
|
|
27
|
+
export type ShaderFamily = "gradient" | "organic" | "geometric" | "fractal" | "spatial" | "texture" | "optical" | "distortion" | "image" | "transition";
|
|
28
|
+
/**
|
|
29
|
+
* Whether a shader invents its picture or reads one.
|
|
30
|
+
*
|
|
31
|
+
* A `source` shader binds a texture and two more slots on top of the shared
|
|
32
|
+
* `Params` block, so it can refract, recolour or resample a layer that is
|
|
33
|
+
* already there. The extra bindings are additive: a `generative` shader
|
|
34
|
+
* declares none of them and keeps the layout it has always had.
|
|
35
|
+
*
|
|
36
|
+
* Kind is decided by where the WGSL file lives, so it can never drift from the
|
|
37
|
+
* bindings the shader actually declares. Read it with `shaderKind(name)`.
|
|
38
|
+
*/
|
|
39
|
+
export type ShaderKind = "generative" | "source";
|
|
28
40
|
/** Rough per-frame cost, used to pick sensible defaults for previews. */
|
|
29
41
|
export type ShaderCost = "light" | "medium" | "heavy";
|
|
30
42
|
export interface ShaderDefinition {
|
|
@@ -36,6 +48,14 @@ export interface ShaderDefinition {
|
|
|
36
48
|
readonly cost: ShaderCost;
|
|
37
49
|
readonly controls: Readonly<Record<string, NumericControl>>;
|
|
38
50
|
readonly colors: Readonly<Record<ColorSlot, ColorControl>>;
|
|
51
|
+
/**
|
|
52
|
+
* For a `source` shader: which shader to render behind it when the caller
|
|
53
|
+
* supplies no source of their own, so a preview is never a blank canvas.
|
|
54
|
+
*
|
|
55
|
+
* Typed as a plain string rather than `ShaderName`, because `ShaderName` is
|
|
56
|
+
* derived from the registry that this interface describes.
|
|
57
|
+
*/
|
|
58
|
+
readonly defaultSource?: string;
|
|
39
59
|
}
|
|
40
60
|
/** Values written to the uniform block, in the order the WGSL struct declares. */
|
|
41
61
|
export interface ResolvedUniforms {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,OAAO,GACP,WAAW,GACX,UAAU,GACV,OAAO,GACP,UAAU,GACV,MAAM,GACN,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,CAAC;AAER,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,SAAS,GACT,WAAW,GACX,SAAS,GACT,SAAS,GACT,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shadertown",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Production WebGPU shader backgrounds for the web, drawn by vgpu.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Production WebGPU shader backgrounds and image effects for the web, drawn by vgpu. 28 shaders, a typed config, and a CLI that vendors the WGSL into your repo.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webgpu",
|
|
7
7
|
"shader",
|