Skip to content

Instantly share code, notes, and snippets.

@greggman
Last active March 24, 2026 22:31
Show Gist options
  • Select an option

  • Save greggman/c5b6d08c587073515332c463ab820fe1 to your computer and use it in GitHub Desktop.

Select an option

Save greggman/c5b6d08c587073515332c463ab820fe1 to your computer and use it in GitHub Desktop.
WebGPU: Immediates
html, body {
margin: 0;
height: 100%;
}
canvas {
width: 100%;
height: 100%;
display: block;
}
<canvas></canvas>
const code = `
struct VSOut {
@builtin(position) pos: vec4f,
@location(0) uv: vec2f,
};
@vertex fn vs(
@builtin(vertex_index) VertexIndex : u32
) -> VSOut {
let pos = array(
vec2f( 0, 0.5),
vec2f(-0.5, -0.5),
vec2f( 0.5, -0.5),
);
var vout: VSOut;
let xy = pos[VertexIndex];
return VSOut(
vec4(xy, 0.0, 1.0),
xy,
);
}
var<immediate> color: vec4f;
@fragment fn fs(vin: VSOut) -> @location(0) vec4f {
return color;
}
`;
(async() => {
const adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
if (!device) {
alert('need webgpu');
return;
}
device.addEventListener('uncapturederror', e => console.error(e.error.message));
const canvas = document.querySelector("canvas")
const context = canvas.getContext('webgpu');
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
context.configure({
device,
format: presentationFormat,
alphaMode: 'opaque',
});
const module = device.createShaderModule({code});
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: { module },
fragment: { module, targets: [{format: presentationFormat}] }
});
function resizeToDisplaySize(device, canvas) {
const width = Math.min(device.limits.maxTextureDimension2D, canvas.clientWidth);
const height = Math.min(device.limits.maxTextureDimension2D, canvas.clientHeight);
const needResize = width !== presentationSize[0] ||
height !== presentationSize[1];
if (needResize) {
canvas.width = width;
canvas.height = height;
}
return needResize;
}
function render() {
const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
colorAttachments: [{
view: context.getCurrentTexture().createView(),
clearColor: [0, 0, 0, 0],
loadOp: 'clear',
storeOp: 'store',
}]
});
pass.setPipeline(pipeline);
pass.setImmediates(0, new Float32Array([0, 1, 0, 1]));
pass.draw(3);
pass.end();
device.queue.submit([encoder.finish()]);
}
render();
})();
{"name":"WebGPU: Immediates","settings":{},"filenames":["index.html","index.css","index.js"]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment