typegpu-shader-canvas

February 23, 2026 ยท View on GitHub

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.

Features

  • ๐Ÿ–ฑ๏ธ 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.

Installation

npm install typegpu-shader-canvas typegpu
npm install --save-dev unplugin-typegpu

Build Plugin

Your build pipeline must include unplugin-typegpu. This is what allows your shader to be compiled to WGSL for the WebGPU pipeline.

Vite example

// vite.config.ts
import typegpuPlugin from 'unplugin-typegpu/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [typegpuPlugin({})],
})

Usage

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.

Examples

Live examples

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()

API

createShaderCanvas(canvas, fragmentShader)

Creates a WebGPU shader canvas that renders a fragment shader to the given <canvas> element.

Parameters:

  • canvas โ€” an HTMLCanvasElement (e.g. from document.getElementById)
  • fragmentShader โ€” a function that receives FragmentParameters and returns a vec4f color. 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 with requestAnimationFrame.
  • stopRendering() โ€” stop the continuous rendering loop.
  • dispose() โ€” stop rendering and clean up all resources and event listeners.

FragmentParameters

The struct passed to your fragment shader function, with these fields:

FieldTypeDescription
pixelPosvec2fPixel coordinates of the fragment
uvvec2fUV coordinates (0,0 = bottom-left, 1,1 = top-right)
uvCenteredvec2fUV centered at origin (โˆ’1,โˆ’1 = bottom-left, 1,1 = top-right)
uvAspectvec2fAspect-corrected UV (0,0 = bottom-left, X,1 = top-right)
uvCenteredAspectvec2fAspect-corrected centered UV (โˆ’X,โˆ’1 = bottom-left, X,1 = top-right)
resolutionvec2fCanvas resolution in pixels
aspectRatiof32Canvas aspect ratio (width / height)
timef32Elapsed time in seconds since page load
mouseMouseMouse state (see below)

Mouse

FieldTypeDescription
pixelPosvec2fPosition in pixels on the canvas
uvvec2fPosition as UV (0,0 = bottom-left, 1,1 = top-right)
uvCenteredvec2fPosition as centered UV (โˆ’1,โˆ’1 = bottom-left, 1,1 = top-right)
uvAspectvec2fAspect-corrected UV position
uvCenteredAspectvec2fAspect-corrected centered UV position
isOveri321 if the mouse is over the canvas, else 0
downi321 if the left mouse button is down, else 0

Notes

  • This module uses top-level await for 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.

TODO

  • 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.