#wgsl-play
Web component for rendering WESL/WGSL fragment shaders.
#Installation
npm install wgsl-play
#Usage
<script type="module">import "wgsl-play";</script>
<wgsl-play src="./shader.wesl"></wgsl-play>
The component auto-fetches dependencies and starts animating.
#Shader API
wgsl-play renders a fullscreen triangle using a built-in vertex shader and only
accepts fragment shaders. Write a single @fragment function.
WESL extensions are supported (imports, conditional compilation).
Standard uniforms are provided at binding 0:
import test::Uniforms;
@group(0) @binding(0) var<uniform> u: Uniforms;
@fragment fn main(@builtin(position) pos: vec4f) -> @location(0) vec4f {
let uv = pos.xy / u.resolution;
return vec4f(uv, sin(u.time) * 0.5 + 0.5, 1.0);
}
| Uniform | Type | Description |
|---|---|---|
resolution |
vec2f |
Canvas dimensions in pixels |
time |
f32 |
Elapsed time in seconds |
mouse |
vec2f |
Mouse position (normalized 0-1) |
#Inline Source
Include shader code inline with a <script type="text/wesl"> tag:
<wgsl-play>
<script type="text/wesl">
import test::Uniforms;
@group(0) @binding(0) var<uniform> u: Uniforms;
@fragment fn main(@builtin(position) pos: vec4f) -> @location(0) vec4f {
let uv = pos.xy / u.resolution;
return vec4f(uv, sin(u.time) * 0.5 + 0.5, 1.0);
}
</script>
</wgsl-play>
#Programmatic Control
const player = document.querySelector("wgsl-play");
player.source = shaderCode;
player.pause();
player.rewind();
player.play();
#Multi-file Shaders
For apps with multiple shader files, use shader-root:
public/
shaders/
utils.wesl # import package::utils
effects/
main.wesl # import super::common
common.wesl
<wgsl-play src="/shaders/effects/main.wesl" shader-root="/shaders"></wgsl-play>
Local shader modules referenced via package:: or super::
will be fetched from the web server.
#Using with wesl-plugin
For more control, use wesl-plugin to assemble shaders and libraries at build time.
import shaderConfig from "./shader.wesl?link";
player.project = {
...shaderConfig,
conditions: { MOBILE: isMobileGPU },
constants: { num_lights: 4 }
};
#API Reference
#Attributes
| Attribute | Values | Default | Description |
|---|---|---|---|
src |
URL | - | URL to .wesl/.wgsl file |
shader-root |
string | /shaders |
Root path for internal imports |
autoplay |
boolean | true |
Start animating on load |
#Properties
| Property | Type | Description |
|---|---|---|
source |
string |
Get/set shader source |
project |
WeslProject |
Set full project config (weslSrc, libs, conditions, constants) |
isPlaying |
boolean |
Playback state (readonly) |
time |
number |
Animation time in seconds (readonly) |
hasError |
boolean |
Compilation error state (readonly) |
errorMessage |
string | null |
Error message (readonly) |
#Methods
| Method | Description |
|---|---|
play() |
Start/resume animation |
pause() |
Pause animation |
rewind() |
Reset to t=0 |
showError(message) |
Display error (empty string clears) |
#Events
| Event | Detail | Description |
|---|---|---|
compile-error |
{ message: string } |
Shader compilation failed |
init-error |
{ message: string } |
WebGPU initialization failed |
playback-change |
{ isPlaying: boolean } |
Play/pause state changed |
#Styling
wgsl-play {
width: 512px;
height: 512px;
}
wgsl-play::part(canvas) {
image-rendering: pixelated;
}