byegl
This project aims to reimplement the WebGL API on top of WebGPU, which will allow established WebGL-based projects to gradually migrate to the WebGPU over time.
Getting Started
All you need to migrate your WebGL code to WebGPU is the following:
import * as byegl from 'https://esm.sh/[email protected]';
// npm: import * as byegl from 'byegl';
// Enable and await...
await byegl.enable();
// Intercepted by byegl 🥯🐶
const gl = canvas.getContext('webgl');
Enabling byegl will intercept calls to .getContext('webgl' | 'webgl2' | 'experimental-webgl')
on all canvases and return
a virtualized WebGL context.
Importing WebGPU resources
Once your WebGL app is running on byegl, you can can hook into the underlying WebGPU API directly.
const wgpuVertexBuffer = device.createBuffer({
// ^? GPUBuffer
size: 1024,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
});
// Create a two-way binding between both resources, allowing
// you to populate the buffer using a WGSL compute shader, and
// use it in a WebGL pipeline 🪄
const vertexBuffer = byegl.importWebGPUBuffer(gl, wgpuVertexBuffer);
// ^? WebGLBuffer
The Hooks: Water Surface example demonstrates this functionality in practice.
Retrieving WebGPU resources
If you need to access the underlying WebGPU resources, you can use the byegl.getWebGPUBuffer()
function.
const wgpuVertexBuffer = byegl.getWebGPUBuffer(gl, vertexBuffer);
// ^? GPUBuffer
Note that byegl may need to reallocate the buffer (in case the size of the data changes), so make sure to
call .getWebGPUBuffer()
each time you need to access the buffer, don’t store it off into a variable.
Retriving generated WGSL code
If you need to access the generated WGSL code, you can use the byegl.getWGSLSource()
function, passing
the WebGL program. Note that since in WebGPU, both the vertex and fragment shaders are colocated.
const program = gl.createProgram();
// ...
const wgsl = byegl.getWGSLSource(gl, program);
// ^? string | undefined
Checking if byegl is enabled
You can check if byegl has intercepted a specific context by calling byegl.isIntercepted(gl)
.
const intercepted = byegl.isIntercepted(gl);
// ^? boolean
Disabling byegl
If you want more granular control over when byegl
intercepts contexts, byegl.enable()
returns a function to disable it.
const disable = await byegl.enable();
//
// Run your program
//
disable(); // Bye byegl 👋
Things to consider when mixing GLSL and WGSL
WebGL’s clip-space coordinates are in the range [-1, 1] for X, Y and Z, whereas WebGPU’s clip-space Z coordinates are in the range [0, 1]. This is mitigated in the generated WGSL, but when writing your own WGSL shaders, you need to be aware of this difference.
News & Updates
Stay updated with the latest news about byegl on X or Bluesky. Follow posts tagged with #byegl.