NOTE: This API is experimental and may change drastically until the 1.0 release
This library makes it easy to render TypeScript-based fragment shaders directly to a web-based canvas element through a WebGPU pipeline. This is made possible by the amazing TypeGPU library.
- 🚫 No setting up a WebGPU device or pipeline
- 🚫 No need to render triangle geometry
- 🚫 No need to write vertex shaders
- ✨ Just provide a canvas, and your shader code, and look at the pretty pixels.
- 🖱️ Mouse event handling for position and left click state, including off-canvas tracking.
- 📐 Rich coordinate space variables: pixel coords, UV (0–1), centered UV (−1–1), and aspect-corrected variants.
- 🔄 Automatically start animating in a render loop.
Note: This library requires a browser with WebGPU support.
npm install typegpu-shader-canvas typegpu
npm install --save-dev unplugin-typegpuYour build pipeline must include unplugin-typegpu. This is what allows your shader to be compiled to WGSL for the WebGPU pipeline.
// vite.config.ts
import typegpuPlugin from 'unplugin-typegpu/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [typegpuPlugin({})],
})Call createShaderCanvas(canvas, fragmentShader) with a reference to a canvas element and a TypeGPU shader function that returns a vec4f. The returned vector has 4 components interpreted as r, g, b, alpha.
This gives you a shader canvas object. Call startRendering() to start continuous rendering, or call render() to render one frame.
import { vec3f, vec4f } from 'typegpu/data'
import { mix, sin } from 'typegpu/std'
import { createShaderCanvas } from 'typegpu-shader-canvas'
createShaderCanvas(
document.getElementById('canvas'),
({ uvCentered, time }) => {
'use gpu'
const color = mix(
vec3f(1, 0, 0),
vec3f(0, 0, 1),
sin(time + uvCentered.x) * 0.5 + 0.5
)
return vec4f(color, 1)
},
).startRendering()Creates a WebGPU shader canvas that renders a fragment shader to the given <canvas> element.
Parameters:
canvas— anHTMLCanvasElement(e.g. fromdocument.getElementById)fragmentShader— a function that receivesFragmentParametersand returns avec4fcolor. Must contain a'use gpu'directive.
Returns an object with:
render()— renders a single frame. Use this if you want to implement your own rendering trigger.startRendering()— start a continuous rendering loop withrequestAnimationFrame.stopRendering()— stop the continuous rendering loop.dispose()— stop rendering and clean up all resources and event listeners.
The struct passed to your fragment shader function, with these fields:
| Field | Type | Description |
|---|---|---|
pixelPos |
vec2f |
Pixel coordinates of the fragment |
uv |
vec2f |
UV coordinates (0,0 = bottom-left, 1,1 = top-right) |
uvCentered |
vec2f |
UV centered at origin (−1,−1 = bottom-left, 1,1 = top-right) |
uvAspect |
vec2f |
Aspect-corrected UV (0,0 = bottom-left, X,1 = top-right) |
uvCenteredAspect |
vec2f |
Aspect-corrected centered UV (−X,−1 = bottom-left, X,1 = top-right) |
resolution |
vec2f |
Canvas resolution in pixels |
aspectRatio |
f32 |
Canvas aspect ratio (width / height) |
time |
f32 |
Elapsed time in seconds since page load |
mouse |
Mouse |
Mouse state (see below) |
| Field | Type | Description |
|---|---|---|
pixelPos |
vec2f |
Position in pixels on the canvas |
uv |
vec2f |
Position as UV (0,0 = bottom-left, 1,1 = top-right) |
uvCentered |
vec2f |
Position as centered UV (−1,−1 = bottom-left, 1,1 = top-right) |
uvAspect |
vec2f |
Aspect-corrected UV position |
uvCenteredAspect |
vec2f |
Aspect-corrected centered UV position |
isOver |
i32 |
1 if the mouse is over the canvas, else 0 |
down |
i32 |
1 if the left mouse button is down, else 0 |
- This module uses top-level
awaitfor WebGPU initialization, so it must be imported as an ES module. - Call
dispose()when you're done with a shader canvas to stop rendering and remove event listeners.
- Mouse tracking
- Implement cleanup and teardown support
- Easier declaration of a custom data buffer
- Performance reporting
- More examples
- Hosted examples
- Better handling when WebGPU is not supported
- Provide aspect ratio correct UV coordinates.