wgsl-play 0.0.37 → 0.0.39
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 +117 -9
- package/dist/{WgslPlay-B86UkrM7.d.ts → WgslPlay-CSjRo-5Z.d.ts} +32 -11
- package/dist/WgslPlay-LsU6XE09.js +933 -0
- package/dist/WgslPlay.d.ts +2 -2
- package/dist/WgslPlay.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/wgsl-play.js +942 -218
- package/package.json +5 -4
- package/src/Renderer.ts +105 -44
- package/src/UniformControls.ts +124 -0
- package/src/WgslPlay.css +140 -2
- package/src/WgslPlay.ts +274 -148
- package/src/test/WgslPlay.e2e.ts +52 -2
- package/src/test/WgslPlay.e2e.ts-snapshots/uniforms-initial-chromium-darwin.png +0 -0
- package/src/test/WgslPlay.e2e.ts-snapshots/uniforms-slider-changed-chromium-darwin.png +0 -0
- package/dist/WgslPlay-DZgeJ1h6.js +0 -636
package/README.md
CHANGED
|
@@ -29,11 +29,94 @@ import env::u;
|
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
When no `@uniforms` struct is declared, a default is provided with `resolution` and `time`.
|
|
33
|
+
|
|
34
|
+
### Custom Uniforms
|
|
35
|
+
|
|
36
|
+
Declare a struct with `@uniforms` to add your own fields with UI controls:
|
|
37
|
+
|
|
38
|
+
```wgsl
|
|
39
|
+
import env::u;
|
|
40
|
+
|
|
41
|
+
@uniforms struct Params {
|
|
42
|
+
@auto resolution: vec2f,
|
|
43
|
+
@auto time: f32,
|
|
44
|
+
@range(1.0, 20.0, 5.0, 6.0) frequency: f32,
|
|
45
|
+
@color(0.2, 0.5, 1.0) tint: vec3f,
|
|
46
|
+
@toggle(0) invert: u32,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@fragment fn main(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
50
|
+
let wave = sin(pos.x * u.frequency + u.time);
|
|
51
|
+
var color = wave * u.tint;
|
|
52
|
+
if u.invert == 1u { color = 1.0 - color; }
|
|
53
|
+
return vec4f(color, 1.0);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `@auto` -- Runtime Fields
|
|
58
|
+
|
|
59
|
+
The player fills these automatically each frame. The field name determines
|
|
60
|
+
which value is bound (or use `@auto(name)` when the field name differs):
|
|
61
|
+
|
|
62
|
+
| Name | Type | Description |
|
|
63
|
+
|------|------|-------------|
|
|
64
|
+
| `resolution` | `vec2f` | Canvas size in pixels |
|
|
35
65
|
| `time` | `f32` | Elapsed time in seconds |
|
|
36
|
-
| `
|
|
66
|
+
| `delta_time` | `f32` | Delta time since last frame |
|
|
67
|
+
| `frame` | `u32` | Frame count |
|
|
68
|
+
| `mouse_pos` | `vec2f` | Pointer position in pixels |
|
|
69
|
+
| `mouse_delta` | `vec2f` | Pointer movement since last frame |
|
|
70
|
+
| `mouse_button` | `i32` | Active button: 0=none, 1=left, 2=middle, 3=right |
|
|
71
|
+
|
|
72
|
+
### UI Annotations
|
|
73
|
+
|
|
74
|
+
These generate interactive controls in the player.
|
|
75
|
+
|
|
76
|
+
#### `@range(min, max [, step [, initial]])`
|
|
77
|
+
|
|
78
|
+
Slider for `f32` or `i32`. Step defaults to `0.01` for `f32`, `1` for `i32`.
|
|
79
|
+
Initial defaults to `min`.
|
|
80
|
+
|
|
81
|
+
```wgsl
|
|
82
|
+
@range(1.0, 20.0) frequency: f32,
|
|
83
|
+
@range(1.0, 20.0, 5.0) frequency: f32, // step=5
|
|
84
|
+
@range(1.0, 20.0, 0.5, 5.0) frequency: f32, // step=0.5, initial=5
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### `@color(r, g, b)`
|
|
88
|
+
|
|
89
|
+
Color picker for `vec3f`:
|
|
90
|
+
|
|
91
|
+
```wgsl
|
|
92
|
+
@color(0.2, 0.5, 1.0) tint: vec3f,
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### `@toggle([initial])`
|
|
96
|
+
|
|
97
|
+
Boolean toggle for `u32` (0 or 1). WGSL forbids `bool` in uniform buffers.
|
|
98
|
+
|
|
99
|
+
```wgsl
|
|
100
|
+
@toggle invert: u32, // default=0
|
|
101
|
+
@toggle(1) invert: u32, // default=1
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Plain Fields
|
|
105
|
+
|
|
106
|
+
Fields without annotations are zero-initialized and settable from JavaScript
|
|
107
|
+
via `setUniform()`. This works before or after compilation.
|
|
108
|
+
|
|
109
|
+
```wgsl
|
|
110
|
+
@uniforms struct Params {
|
|
111
|
+
@auto resolution: vec2f,
|
|
112
|
+
brightness: f32, // no annotation — set from JS
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
const player = document.querySelector("wgsl-play");
|
|
118
|
+
player.setUniform("brightness", 0.8);
|
|
119
|
+
```
|
|
37
120
|
|
|
38
121
|
### Inline source
|
|
39
122
|
|
|
@@ -56,7 +139,7 @@ You can include shader code inline if you'd prefer. Use a `<script type="text/wg
|
|
|
56
139
|
|
|
57
140
|
```typescript
|
|
58
141
|
const player = document.querySelector("wgsl-play");
|
|
59
|
-
player.
|
|
142
|
+
player.shader = shaderCode;
|
|
60
143
|
player.pause();
|
|
61
144
|
player.rewind();
|
|
62
145
|
player.play();
|
|
@@ -68,7 +151,7 @@ player.play();
|
|
|
68
151
|
import shader from './examples/noise.wesl?raw';
|
|
69
152
|
|
|
70
153
|
const player = document.querySelector("wgsl-play");
|
|
71
|
-
player.
|
|
154
|
+
player.shader = shader;
|
|
72
155
|
```
|
|
73
156
|
|
|
74
157
|
The `?raw` suffix imports the file as a string. This keeps shaders alongside your source files with HMR support.
|
|
@@ -80,12 +163,20 @@ The `?raw` suffix imports the file as a string. This keeps shaders alongside you
|
|
|
80
163
|
- `shader-root` - Root path for internal imports (default: `/shaders`)
|
|
81
164
|
- `autoplay` - Start animating on load (default: `true`). Set `autoplay="false"` to start paused
|
|
82
165
|
- `transparent` - Use premultiplied alpha for transparent backgrounds (default: opaque)
|
|
166
|
+
- `from` - Element ID of a source provider (e.g., wgsl-edit) to connect to
|
|
167
|
+
- `no-controls` - Hide playback controls (play/pause, rewind, fullscreen)
|
|
168
|
+
- `no-settings` - Hide the uniform controls panel
|
|
169
|
+
- `width` / `height` - Fixed canvas resolution in pixels, independent of display size. When set, the canvas is not resized by the CSS layout
|
|
170
|
+
- `pixel-ratio` - Scale factor from CSS pixels to canvas pixels (default: `devicePixelRatio`). Set `pixel-ratio="1"` for 1:1 CSS pixels (no HiDPI scaling)
|
|
171
|
+
- `resizable` - Show a drag handle to let users resize the element interactively
|
|
83
172
|
- `fetch-libs` - Auto-fetch missing libraries from npm (default: `true`). Set `fetch-libs="false"` to disable
|
|
173
|
+
- `fetch-sources` - Auto-fetch local .wesl source files via HTTP (default: `true`). Set `fetch-sources="false"` to disable
|
|
84
174
|
|
|
85
175
|
### Properties
|
|
86
|
-
- `
|
|
176
|
+
- `shader: string` - Get/set shader source (single-file convenience)
|
|
87
177
|
- `conditions: Record<string, boolean>` - Get/set conditions for conditional compilation (`@if`/`@elif`/`@else`)
|
|
88
|
-
- `project: WeslProject` -
|
|
178
|
+
- `project: WeslProject` - Get/set full project config (weslSrc, libs, conditions, constants)
|
|
179
|
+
- `pixelRatio: number` - Get/set canvas-to-CSS pixel ratio (default: `devicePixelRatio`)
|
|
89
180
|
- `isPlaying: boolean` - Playback state (readonly)
|
|
90
181
|
- `time: number` - Animation time in seconds (readonly)
|
|
91
182
|
- `hasError: boolean` - Compilation error state (readonly)
|
|
@@ -95,12 +186,29 @@ The `?raw` suffix imports the file as a string. This keeps shaders alongside you
|
|
|
95
186
|
- `play()` - Start/resume animation
|
|
96
187
|
- `pause()` - Pause animation
|
|
97
188
|
- `rewind()` - Reset to t=0
|
|
189
|
+
- `setUniform(name, value)` - Set a uniform value programmatically
|
|
98
190
|
- `showError(message)` - Display error (empty string clears)
|
|
99
191
|
|
|
100
192
|
### Events
|
|
101
193
|
- `compile-error` - `{ message: string }`
|
|
102
194
|
- `init-error` - `{ message: string }` (WebGPU init failed)
|
|
103
195
|
- `playback-change` - `{ isPlaying: boolean }`
|
|
196
|
+
- `uniforms-layout` - `{ detail: AnnotatedLayout }` (fired after each compile)
|
|
197
|
+
|
|
198
|
+
## Canvas Sizing
|
|
199
|
+
|
|
200
|
+
By default the canvas resolution tracks CSS size at `devicePixelRatio`.
|
|
201
|
+
Use `pixel-ratio` or `width`/`height` to decouple:
|
|
202
|
+
|
|
203
|
+
```html
|
|
204
|
+
<!-- 1:1 CSS pixels (blocky on HiDPI, great for pixel art) -->
|
|
205
|
+
<wgsl-play pixel-ratio="1" style="width:512px; height:512px"></wgsl-play>
|
|
206
|
+
|
|
207
|
+
<!-- Fixed 64x64 canvas, stretched to whatever CSS size -->
|
|
208
|
+
<wgsl-play width="64" height="64" style="width:512px; height:512px"></wgsl-play>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
For crisp upscaling of low-res canvases, add `image-rendering: pixelated`:
|
|
104
212
|
|
|
105
213
|
## Styling
|
|
106
214
|
|
|
@@ -147,7 +255,7 @@ import super::common::tint;
|
|
|
147
255
|
|
|
148
256
|
## Using with wesl-plugin
|
|
149
257
|
|
|
150
|
-
For more control, use the [wesl-plugin](https://github.com/wgsl-tooling-wg/wesl-js/tree/main/
|
|
258
|
+
For more control, use the [wesl-plugin](https://github.com/wgsl-tooling-wg/wesl-js/tree/main/packages/wesl-plugin) to
|
|
151
259
|
assemble shaders and libraries at build time and provide
|
|
152
260
|
them wgsl-play in JavaScript or TypeScript.
|
|
153
261
|
- provides full support for Hot Module Reloading during development
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Conditions,
|
|
1
|
+
import { Conditions, WeslProject } from "wesl";
|
|
2
2
|
|
|
3
3
|
//#region src/Config.d.ts
|
|
4
4
|
/** Configuration for wgsl-play. */
|
|
@@ -14,8 +14,6 @@ declare function getConfig(overrides?: Partial<WgslPlayConfig>): WgslPlayConfig;
|
|
|
14
14
|
declare function resetConfig(): void;
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/WgslPlay.d.ts
|
|
17
|
-
/** Project configuration for multi-file shaders (subset of wesl link() API). */
|
|
18
|
-
type WeslProject = Pick<LinkParams, "weslSrc" | "rootModuleName" | "conditions" | "constants" | "libs" | "packageName">;
|
|
19
17
|
/** One source location within a compile error. */
|
|
20
18
|
interface CompileErrorLocation {
|
|
21
19
|
file?: string;
|
|
@@ -37,15 +35,17 @@ declare class WgslPlay extends HTMLElement {
|
|
|
37
35
|
private canvas;
|
|
38
36
|
private errorOverlay;
|
|
39
37
|
private controls;
|
|
38
|
+
private settings;
|
|
40
39
|
private resizeObserver;
|
|
41
40
|
private stopRenderLoop?;
|
|
42
41
|
private renderState?;
|
|
42
|
+
private pendingUniforms;
|
|
43
43
|
private playback;
|
|
44
44
|
private _weslSrc;
|
|
45
45
|
private _rootModuleName;
|
|
46
46
|
private _libs?;
|
|
47
47
|
private _linkOptions;
|
|
48
|
-
private
|
|
48
|
+
private _fetchSources;
|
|
49
49
|
private _initPromise?;
|
|
50
50
|
private _sourceEl;
|
|
51
51
|
private _sourceListener;
|
|
@@ -55,6 +55,8 @@ declare class WgslPlay extends HTMLElement {
|
|
|
55
55
|
private _theme;
|
|
56
56
|
private _mediaQuery;
|
|
57
57
|
private _onFullscreenChange;
|
|
58
|
+
private _pointerCleanup?;
|
|
59
|
+
private _resizeCleanup?;
|
|
58
60
|
/** Get config overrides from element attributes. */
|
|
59
61
|
private getConfigOverrides;
|
|
60
62
|
constructor();
|
|
@@ -62,22 +64,26 @@ declare class WgslPlay extends HTMLElement {
|
|
|
62
64
|
disconnectedCallback(): void;
|
|
63
65
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
64
66
|
/** Current shader source code (main module). */
|
|
65
|
-
get
|
|
66
|
-
/** Set shader source directly. */
|
|
67
|
-
set
|
|
67
|
+
get shader(): string;
|
|
68
|
+
/** Set shader source directly (single-file convenience). */
|
|
69
|
+
set shader(value: string);
|
|
68
70
|
/** Conditions for conditional compilation (@if/@elif/@else). */
|
|
69
71
|
get conditions(): Conditions;
|
|
70
72
|
set conditions(value: Conditions);
|
|
71
73
|
/** Set project configuration (mirrors wesl link() API). */
|
|
72
74
|
set project(value: WeslProject);
|
|
73
|
-
/** Set sources from a full project with weslSrc. */
|
|
74
|
-
private setProjectSources;
|
|
75
75
|
/** Whether to auto-fetch missing library packages from npm (default: true). */
|
|
76
76
|
get fetchLibs(): boolean;
|
|
77
77
|
set fetchLibs(value: boolean);
|
|
78
|
+
/** Whether to fetch local .wesl source files via HTTP (default: true). */
|
|
79
|
+
get fetchSources(): boolean;
|
|
80
|
+
set fetchSources(value: boolean);
|
|
78
81
|
/** Whether autoplay is enabled (default: true). Set autoplay="false" to start paused. */
|
|
79
82
|
get autoplay(): boolean;
|
|
80
83
|
set autoplay(value: boolean | string);
|
|
84
|
+
/** Scale factor from CSS pixels to canvas pixels (default: devicePixelRatio). */
|
|
85
|
+
get pixelRatio(): number;
|
|
86
|
+
set pixelRatio(value: number);
|
|
81
87
|
/** Whether the shader is currently playing. */
|
|
82
88
|
get isPlaying(): boolean;
|
|
83
89
|
/** Current animation time in seconds. */
|
|
@@ -97,8 +103,19 @@ declare class WgslPlay extends HTMLElement {
|
|
|
97
103
|
rewind(): void;
|
|
98
104
|
/** Display error message in overlay. Pass empty string to clear. */
|
|
99
105
|
showError(message: string): void;
|
|
106
|
+
/** Set a uniform value by name. Works before or after compilation. */
|
|
107
|
+
setUniform(name: string, value: number | number[]): void;
|
|
108
|
+
private flushPendingUniforms;
|
|
109
|
+
/** Current uniform control values (readable). */
|
|
110
|
+
get uniforms(): Record<string, number | number[]>;
|
|
100
111
|
/** Toggle fullscreen on this element. */
|
|
101
112
|
toggleFullscreen(): void;
|
|
113
|
+
/** Track pointer events on canvas for mouse_pos @auto fields. */
|
|
114
|
+
private setupMouseTracking;
|
|
115
|
+
/** Drag-to-resize via a custom handle (works on touch + mouse). */
|
|
116
|
+
private setupResizeHandle;
|
|
117
|
+
/** Recompute canvas resolution from attributes or CSS size. */
|
|
118
|
+
private updateCanvasSize;
|
|
102
119
|
private updateTheme;
|
|
103
120
|
/** Set up WebGPU and load initial shader. Returns true if successful. */
|
|
104
121
|
private initialize;
|
|
@@ -106,16 +123,20 @@ declare class WgslPlay extends HTMLElement {
|
|
|
106
123
|
/** Load from source element, src URL, script child, or inline textContent. */
|
|
107
124
|
private loadInitialContent;
|
|
108
125
|
/** Connect to a source provider element (e.g., wgsl-edit). */
|
|
109
|
-
private
|
|
126
|
+
private connectFrom;
|
|
110
127
|
/** Fetch shader from URL, then trigger a build. */
|
|
111
128
|
private loadFromUrl;
|
|
112
129
|
/** Mark build as needed. Coalesces rapid requests into a single build. */
|
|
113
130
|
private requestBuild;
|
|
114
131
|
/** Run builds until no longer dirty. Only one instance runs at a time. */
|
|
115
132
|
private runBuild;
|
|
133
|
+
/** Fetch deps if needed and create the render pipeline. */
|
|
134
|
+
private buildPipeline;
|
|
135
|
+
/** Apply a successful build: flush uniforms, update controls, render. */
|
|
136
|
+
private applyBuild;
|
|
116
137
|
private handleCompileError;
|
|
117
138
|
/** Extract source locations from a WESL parse error or GPU compilation error. */
|
|
118
139
|
private extractLocations;
|
|
119
140
|
}
|
|
120
141
|
//#endregion
|
|
121
|
-
export {
|
|
142
|
+
export { defaults as a, WgslPlayConfig as i, CompileErrorLocation as n, getConfig as o, WgslPlay as r, resetConfig as s, CompileErrorDetail as t };
|