JSFiddle - React, Tailwind, and code Playground
by emadurandal
HTML
<canvas id="world" width="400" height="400"></canvas>
TypeScript
(async()=>{
const vertWGSL = `
@vertex
fn main(
@builtin(vertex_index) VertexIndex : u32
) -> @builtin(position) vec4<f32> {
var pos = array<vec2<f32>, 3>(
vec2<f32>(0.0, 0.5),
vec2<f32>(-0.5, -0.5),
vec2<f32>(0.5, -0.5)
);
return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
}
`;
const fragWGSL = `
override is_red: bool;
override color_r: f32 = 1.0;
override color_g: f32 = 1.0;
override color_b: f32 = 1.0;
@fragment
fn main() -> @location(0) vec4<f32> {
if (is_red) {
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
} else {
return vec4<f32>(color_r, color_g, color_b, 1.0);
}
}
`;
const g_adapter = await navigator.gpu.requestAdapter();
const g_device = await g_adapter!.requestDevice();
async function init(canvas: HTMLCanvasElement): Promise<{context: GPUCanvasContext, pipeline: GPURenderPipeline}> {
const context = canvas.getContext('webgpu') as GPUCanvasContext;
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
context.configure({
device: g_device,
format: presentationFormat,
alphaMode: 'opaque',
});
// create a render pipeline
const pipeline = g_device.createRenderPipeline({
layout: 'auto',
vertex: {
module: g_device.createShaderModule({
code: vertWGSL,
}),
entryPoint: 'main',
},
fragment: {
module: g_device.createShaderModule({
code: fragWGSL,
}),
entryPoint: 'main',
constants: {
'is_red': false,
'color_r': 0.5,
'color_g': 0.25,
'color_b': 1.0,
}
targets: [
// 0
{ // @location(0) in fragment shader
format: presentationFormat,
},
],
},
primitive: {
topology: 'triangle-list',
},
});
return {context, pipeline};
}
function frame({context, pipeline}: {context: GPUCanvasContext, pipeline: GPURenderPipeline}): void {
const commandEncoder = g_device.createCommandEncoder();
const textureView =...