Skip to content

Instantly share code, notes, and snippets.

@haehn
Created December 1, 2023 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haehn/d3f09cee203e515a7582f0ade9c6a0c6 to your computer and use it in GitHub Desktop.
Save haehn/d3f09cee203e515a7582f0ade9c6a0c6 to your computer and use it in GitHub Desktop.
Hello Triangle WebGPU
<!-- for linux: google-chrome --enable-unsafe-webgpu --use-vulkan=true --test-type --enable-features=Vulkan -->
<html>
<head>
<title>WebGPU Hello Triangle</title>
<style>
html, body { width: 100%; height: 100%; padding: 0; margin: 0; }
#c { width: 100%; height: 100%; }
</style>
</head>
<body>
<canvas id="c" width="600" height="600"></canvas>
<script>
async function initWebGPU() {
// Ensure WebGPU is supported
if (!navigator.gpu) {
console.error("WebGPU is not supported. Please use a compatible browser.");
return;
}
// Initialization
const canvas = document.getElementById("c");
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const context = canvas.getContext("webgpu");
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({
device: device,
format: format
});
// Shaders
const shaderCode = `
@vertex
fn vs_main(
@builtin(vertex_index) VertexIndex : u32
) -> @builtin(position) vec4<f32> {
var pos = array<vec2<f32>, 3>(
vec2(0.0, 0.5),
vec2(-0.5, -0.5),
vec2(0.5, -0.5)
);
return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
}
@fragment
fn fs_main() -> @location(0) vec4<f32> {
return vec4(1.0, 0.0, 0.0, 1.0);
}
`;
const shaderModule = device.createShaderModule({ code: shaderCode });
// Pipeline Configuration
const pipeline = device.createRenderPipeline({
vertex: {
module: shaderModule,
entryPoint: "vs_main"
},
fragment: {
module: shaderModule,
entryPoint: "fs_main",
targets: [{
format: format
}]
},
primitive: {
topology: "triangle-list"
},
layout: "auto"
});
// Drawing
const commandEncoder = device.createCommandEncoder();
const textureView = context.getCurrentTexture().createView();
const renderPassDescriptor = {
colorAttachments: [{
view: textureView,
loadValue: { r: 0, g: 0, b: 0, a: 1 },
storeOp: 'store',
loadOp: 'clear'
}]
};
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(pipeline);
passEncoder.draw(3, 1, 0, 0);
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
}
window.onload = initWebGPU;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment