wgsl-play 0.0.39 → 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/README.md +59 -2
- package/dist/{WgslPlay-CSjRo-5Z.d.ts → WgslPlay-ouKx64GN.d.ts} +52 -3
- package/dist/WgslPlay-zK9mE5rV.js +1544 -0
- package/dist/WgslPlay.d.ts +2 -2
- package/dist/WgslPlay.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/jsx-preact.d.ts +12 -0
- package/dist/jsx-preact.js +0 -0
- package/dist/wgsl-play.js +1834 -754
- package/package.json +12 -8
- package/src/CanvasSize.ts +27 -0
- package/src/ComputeBuild.ts +151 -0
- package/src/FragmentRender.ts +147 -0
- package/src/PlaybackControls.ts +36 -13
- package/src/RenderResources.ts +132 -0
- package/src/Renderer.ts +112 -138
- package/src/ResultsPanel.ts +261 -0
- package/src/WgslPlay.css +80 -8
- package/src/WgslPlay.ts +346 -103
- package/src/icons/refresh.svg +1 -0
- package/src/jsx-preact.ts +15 -0
- package/src/test/BundleHydrator.test.ts +8 -11
- package/src/test/CanvasSize.test.ts +48 -0
- package/src/test/E2eHelpers.ts +117 -0
- package/src/test/RenderFrame.e2e.ts +33 -0
- package/src/test/ResultsPanel.test.ts +164 -0
- package/src/test/WgslPlay.basics.e2e.ts +87 -0
- package/src/test/WgslPlay.compute.e2e.ts +147 -0
- package/src/test/WgslPlay.connect.e2e.ts +101 -0
- package/src/test/WgslPlay.loading.e2e.ts +68 -0
- package/src/test/WgslPlay.resize.e2e.ts +199 -0
- package/src/test/WgslPlay.resources.e2e.ts +67 -0
- package/src/test/WgslPlay.resources.e2e.ts-snapshots/buffer-zero-init-chromium-darwin.png +0 -0
- package/src/test/WgslPlay.resources.e2e.ts-snapshots/texture-grid-chromium-darwin.png +0 -0
- package/src/test/WgslPlay.resources.e2e.ts-snapshots/texture-img-green-chromium-darwin.png +0 -0
- package/src/test/WgslPlay.resources.e2e.ts-snapshots/texture-img-magenta-chromium-darwin.png +0 -0
- package/src/test/WgslPlay.resources.e2e.ts-snapshots/texture-multi-chromium-darwin.png +0 -0
- package/src/test/WgslPlay.uniforms.e2e.ts +57 -0
- package/dist/WgslPlay-LsU6XE09.js +0 -933
- package/src/test/WgslPlay.e2e.ts +0 -327
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.basics.e2e.ts-snapshots}/basic-shader-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.basics.e2e.ts-snapshots}/conditions-after-red-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.basics.e2e.ts-snapshots}/conditions-initial-green-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.connect.e2e.ts-snapshots}/connect-conditions-green-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.connect.e2e.ts-snapshots}/connect-conditions-red-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.connect.e2e.ts-snapshots}/connect-dynamic-npm-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.connect.e2e.ts-snapshots}/connect-source-external-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.connect.e2e.ts-snapshots}/connect-source-multifile-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.loading.e2e.ts-snapshots}/link-import-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.loading.e2e.ts-snapshots}/npm-cdn-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.loading.e2e.ts-snapshots}/shader-root-internal-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.loading.e2e.ts-snapshots}/shader-root-src-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.loading.e2e.ts-snapshots}/static-import-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.uniforms.e2e.ts-snapshots}/uniforms-initial-chromium-darwin.png +0 -0
- /package/src/test/{WgslPlay.e2e.ts-snapshots → WgslPlay.uniforms.e2e.ts-snapshots}/uniforms-slider-changed-chromium-darwin.png +0 -0
package/README.md
CHANGED
|
@@ -118,6 +118,62 @@ const player = document.querySelector("wgsl-play");
|
|
|
118
118
|
player.setUniform("brightness", 0.8);
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
### Resource Annotations
|
|
122
|
+
|
|
123
|
+
Bind GPU resources by annotating shader globals. The component owns
|
|
124
|
+
`@group(0)` — `@binding(0)` is the uniform buffer, and annotated resources
|
|
125
|
+
take `@binding(1)` and onward in declaration order.
|
|
126
|
+
|
|
127
|
+
#### `@texture(name)` — host-provided image
|
|
128
|
+
|
|
129
|
+
Resolves to a child `<img>` or `<canvas>` of the `<wgsl-play>` element.
|
|
130
|
+
Lookup matches `[data-texture="name"]` first, then falls back to `#name`.
|
|
131
|
+
The image is decoded and uploaded as `rgba8unorm`.
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<wgsl-play>
|
|
135
|
+
<script type="text/wesl">
|
|
136
|
+
import env::u;
|
|
137
|
+
@texture(nebula) var photo: texture_2d<f32>;
|
|
138
|
+
@sampler(linear) var samp: sampler;
|
|
139
|
+
|
|
140
|
+
@fragment fn fs_main(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
141
|
+
return textureSample(photo, samp, pos.xy / u.resolution);
|
|
142
|
+
}
|
|
143
|
+
</script>
|
|
144
|
+
<img data-texture="nebula" src="/images/nebula.jpg" hidden>
|
|
145
|
+
</wgsl-play>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Only `texture_2d<f32>` is supported. `texture_cube`, `texture_2d_array`,
|
|
149
|
+
and storage textures are rejected with a clear error. `<img>` decoding
|
|
150
|
+
uses `imageOrientation: "from-image"`, `premultiplyAlpha: "none"`, and
|
|
151
|
+
`colorSpaceConversion: "none"` for deterministic uploads.
|
|
152
|
+
|
|
153
|
+
Changing an `<img>` `src`, swapping `data-texture`, or adding/removing
|
|
154
|
+
texture children rebuilds the pipeline automatically.
|
|
155
|
+
|
|
156
|
+
#### `@sampler(filter)`
|
|
157
|
+
|
|
158
|
+
Creates a sampler with `clamp-to-edge` addressing. Filter is `linear` or
|
|
159
|
+
`nearest`.
|
|
160
|
+
|
|
161
|
+
```wgsl
|
|
162
|
+
@sampler(nearest) var samp: sampler;
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### `@buffer`
|
|
166
|
+
|
|
167
|
+
Zero-initialized storage buffer; size inferred from the WGSL type.
|
|
168
|
+
`read` and `read_write` are both allowed.
|
|
169
|
+
|
|
170
|
+
```wgsl
|
|
171
|
+
@buffer var<storage, read> palette: array<vec4f, 8>;
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`@test_texture` (the wgsl-test fixture annotation) is rejected at
|
|
175
|
+
runtime — use `@texture(name)` with a host element instead.
|
|
176
|
+
|
|
121
177
|
### Inline source
|
|
122
178
|
|
|
123
179
|
You can include shader code inline if you'd prefer. Use a `<script type="text/wgsl">` (or `<script type="text/wesl">`) tag.
|
|
@@ -186,11 +242,12 @@ The `?raw` suffix imports the file as a string. This keeps shaders alongside you
|
|
|
186
242
|
- `play()` - Start/resume animation
|
|
187
243
|
- `pause()` - Pause animation
|
|
188
244
|
- `rewind()` - Reset to t=0
|
|
245
|
+
- `renderFrame()` - Wait for any in-flight build, render one frame, and resolve once it has been presented (for snapshotting the canvas)
|
|
189
246
|
- `setUniform(name, value)` - Set a uniform value programmatically
|
|
190
247
|
- `showError(message)` - Display error (empty string clears)
|
|
191
248
|
|
|
192
249
|
### Events
|
|
193
|
-
- `compile-error` - `{ message:
|
|
250
|
+
- `compile-error` - `{ message, source: "wesl"|"webgpu", kind: "shader"|"resource", resourceSource?, locations }`. `kind: "resource"` covers missing `@texture` host elements, unsupported texture dims, and `@test_texture` rejection; `resourceSource` names the offending var/source
|
|
194
251
|
- `init-error` - `{ message: string }` (WebGPU init failed)
|
|
195
252
|
- `playback-change` - `{ isPlaying: boolean }`
|
|
196
253
|
- `uniforms-layout` - `{ detail: AnnotatedLayout }` (fired after each compile)
|
|
@@ -255,7 +312,7 @@ import super::common::tint;
|
|
|
255
312
|
|
|
256
313
|
## Using with wesl-plugin
|
|
257
314
|
|
|
258
|
-
For more control, use the [wesl-plugin](https://github.com/
|
|
315
|
+
For more control, use the [wesl-plugin](https://github.com/webgpu-tools/wesl-js/tree/main/packages/wesl-plugin) to
|
|
259
316
|
assemble shaders and libraries at build time and provide
|
|
260
317
|
them wgsl-play in JavaScript or TypeScript.
|
|
261
318
|
- provides full support for Hot Module Reloading during development
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Conditions, WeslProject } from "wesl";
|
|
2
|
+
import { ResourceLoadError as ResourceLoadError$1 } from "wesl-gpu";
|
|
2
3
|
|
|
3
4
|
//#region src/Config.d.ts
|
|
4
5
|
/** Configuration for wgsl-play. */
|
|
@@ -20,6 +21,8 @@ interface CompileErrorLocation {
|
|
|
20
21
|
line: number;
|
|
21
22
|
column: number;
|
|
22
23
|
length?: number;
|
|
24
|
+
/** byte offset into the source file */
|
|
25
|
+
offset: number;
|
|
23
26
|
severity: "error" | "warning" | "info";
|
|
24
27
|
message: string;
|
|
25
28
|
}
|
|
@@ -27,17 +30,34 @@ interface CompileErrorLocation {
|
|
|
27
30
|
interface CompileErrorDetail {
|
|
28
31
|
message: string;
|
|
29
32
|
source: "wesl" | "webgpu";
|
|
33
|
+
/** What kind of failure: a shader compile/link problem or a host-side resource problem. */
|
|
34
|
+
kind: "shader" | "resource";
|
|
35
|
+
/** For resource errors, the `@texture(name)` or buffer var referenced. */
|
|
36
|
+
resourceSource?: string;
|
|
30
37
|
locations: CompileErrorLocation[];
|
|
31
38
|
}
|
|
32
|
-
/**
|
|
39
|
+
/** Attributes accepted by `<wgsl-play>` beyond standard HTML.
|
|
40
|
+
* Source of truth for framework-specific JSX augmentations (see `./jsx-preact.ts`). */
|
|
41
|
+
interface WgslPlayAttrs {
|
|
42
|
+
/** ID of a `<wgsl-edit>` (or compatible) element to source shader content from. */
|
|
43
|
+
from?: string;
|
|
44
|
+
/** Color theme; `"auto"` follows `prefers-color-scheme`. */
|
|
45
|
+
theme?: "light" | "dark" | "auto";
|
|
46
|
+
/** Allow drag-resize of the player via the corner handle. */
|
|
47
|
+
resizable?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** <wgsl-play> web component for rendering WESL/WGSL fragment shaders. */
|
|
33
50
|
declare class WgslPlay extends HTMLElement {
|
|
34
51
|
static observedAttributes: string[];
|
|
35
52
|
private canvas;
|
|
53
|
+
private resultsPanel;
|
|
36
54
|
private errorOverlay;
|
|
37
55
|
private controls;
|
|
38
56
|
private settings;
|
|
39
57
|
private resizeObserver;
|
|
40
58
|
private stopRenderLoop?;
|
|
59
|
+
private _currentMode;
|
|
60
|
+
private _rerunPending;
|
|
41
61
|
private renderState?;
|
|
42
62
|
private pendingUniforms;
|
|
43
63
|
private playback;
|
|
@@ -56,11 +76,15 @@ declare class WgslPlay extends HTMLElement {
|
|
|
56
76
|
private _mediaQuery;
|
|
57
77
|
private _onFullscreenChange;
|
|
58
78
|
private _pointerCleanup?;
|
|
59
|
-
private
|
|
79
|
+
private _resizeCleanups;
|
|
80
|
+
private _childObserver?;
|
|
60
81
|
/** Get config overrides from element attributes. */
|
|
61
82
|
private getConfigOverrides;
|
|
62
83
|
constructor();
|
|
63
84
|
connectedCallback(): void;
|
|
85
|
+
/** Start watching element size. Deferred until after `initWebGPU` so the
|
|
86
|
+
* observer has a real `maxTextureDimension2D` to clamp against. */
|
|
87
|
+
private observeCanvasSize;
|
|
64
88
|
disconnectedCallback(): void;
|
|
65
89
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
66
90
|
/** Current shader source code (main module). */
|
|
@@ -99,12 +123,25 @@ declare class WgslPlay extends HTMLElement {
|
|
|
99
123
|
/** Pause playback. */
|
|
100
124
|
pause(): void;
|
|
101
125
|
private setPlaying;
|
|
126
|
+
/** Mirror a default-true setter onto its attribute: absent = on, "false" = off. */
|
|
127
|
+
private setBoolAttr;
|
|
128
|
+
/** Wait for any in-flight build and render one frame to the canvas, resolving
|
|
129
|
+
* once it has been presented. Read the canvas via
|
|
130
|
+
* `element.shadowRoot.querySelector('canvas')`. */
|
|
131
|
+
renderFrame(): Promise<void>;
|
|
132
|
+
/** Resolve once initialization and any pending build have settled. Yields via
|
|
133
|
+
* setTimeout so async build steps (network fetch, GPU validation) get a
|
|
134
|
+
* chance to advance between polls. */
|
|
135
|
+
private awaitIdleBuild;
|
|
102
136
|
/** Reset animation to time 0 and pause. */
|
|
103
137
|
rewind(): void;
|
|
138
|
+
/** Stop the RAF loop, mark paused, and re-present the current frame. */
|
|
139
|
+
private stopAndPresent;
|
|
104
140
|
/** Display error message in overlay. Pass empty string to clear. */
|
|
105
141
|
showError(message: string): void;
|
|
106
142
|
/** Set a uniform value by name. Works before or after compilation. */
|
|
107
143
|
setUniform(name: string, value: number | number[]): void;
|
|
144
|
+
/** Apply uniforms set before the pipeline existed. */
|
|
108
145
|
private flushPendingUniforms;
|
|
109
146
|
/** Current uniform control values (readable). */
|
|
110
147
|
get uniforms(): Record<string, number | number[]>;
|
|
@@ -116,9 +153,11 @@ declare class WgslPlay extends HTMLElement {
|
|
|
116
153
|
private setupResizeHandle;
|
|
117
154
|
/** Recompute canvas resolution from attributes or CSS size. */
|
|
118
155
|
private updateCanvasSize;
|
|
156
|
+
/** Toggle the `dark` class to match `theme` attr or system preference. */
|
|
119
157
|
private updateTheme;
|
|
120
158
|
/** Set up WebGPU and load initial shader. Returns true if successful. */
|
|
121
159
|
private initialize;
|
|
160
|
+
/** Init WebGPU, wire observers/listeners, and dispatch ready/init-error. */
|
|
122
161
|
private doInitialize;
|
|
123
162
|
/** Load from source element, src URL, script child, or inline textContent. */
|
|
124
163
|
private loadInitialContent;
|
|
@@ -132,11 +171,21 @@ declare class WgslPlay extends HTMLElement {
|
|
|
132
171
|
private runBuild;
|
|
133
172
|
/** Fetch deps if needed and create the render pipeline. */
|
|
134
173
|
private buildPipeline;
|
|
174
|
+
/** Resolve a @texture(name) to a decoded image from light-DOM children.
|
|
175
|
+
* Prefers [data-texture="name"], falls back to #id. */
|
|
176
|
+
private resolveHostTexture;
|
|
177
|
+
/** Watch light-DOM for <img> add/remove/src changes and trigger a rebuild. */
|
|
178
|
+
private observeLightDomChildren;
|
|
135
179
|
/** Apply a successful build: flush uniforms, update controls, render. */
|
|
136
180
|
private applyBuild;
|
|
181
|
+
/** Show canvas vs results panel and (re-)render based on build mode. */
|
|
182
|
+
private applyMode;
|
|
183
|
+
/** Coalesce rapid uniform/refresh events into a single re-dispatch. */
|
|
184
|
+
private scheduleComputeRerun;
|
|
185
|
+
/** Show the error overlay and dispatch a `compile-error` event. */
|
|
137
186
|
private handleCompileError;
|
|
138
187
|
/** Extract source locations from a WESL parse error or GPU compilation error. */
|
|
139
188
|
private extractLocations;
|
|
140
189
|
}
|
|
141
190
|
//#endregion
|
|
142
|
-
export {
|
|
191
|
+
export { WgslPlayAttrs as a, getConfig as c, WgslPlay as i, resetConfig as l, CompileErrorLocation as n, WgslPlayConfig as o, ResourceLoadError$1 as r, defaults as s, CompileErrorDetail as t };
|