WESL Logo

#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;
}