JSFiddle - React, Tailwind, and code Playground

by rectalogic

HTML

<canvas width="200" height="200"></canvas>

JavaScript

// WebGPU Simple Triangle
// from https://webgpufundamentals.org/webgpu/webgpu-simple-triangle.html

async function main() {
  const adapter = await navigator.gpu?.requestAdapter();
  const device = await adapter?.requestDevice();
  if (!device) {
    fail('need a browser that supports WebGPU');
    return;
  }

  // Get a WebGPU context from the canvas and configure it
  const canvas = document.querySelector('canvas');
  const context = canvas.getContext('webgpu');
  const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
  context.configure({
    device,
    format: presentationFormat,
  });

  const module = device.createShaderModule({
    label: 'our hardcoded red triangle shaders',
    code: `
struct VertexOutput {
  @builtin(position) position: vec4f,
  @location(0) uv: vec2f,
};

const triangle = array(
  vec2f( 0.0,  0.5),  // top center
  vec2f(-0.5, -0.5),  // bottom left
  vec2f( 0.5, -0.5)   // bottom right
);
const uv = array(
  vec2f(0.5, 0.0),    // top center
  vec2f(0.0, 1.0),    // bottom left
  vec2f(1.0, 1.0),    // bottom right
);

@vertex fn vs(
  @builtin(vertex_index) vertexIndex : u32
) -> VertexOutput {
  var out: VertexOutput;
  out.position = vec4f(triangle[vertexIndex], 0.0, 1.0);
  out.uv = uv[vertexIndex];
  return out;
}

@fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
  // const fudge = 0.025;
  const fudge = 0.0;
  // Height of equilateral triangle is 3*r, triangle height is 1, so radius is 1/3
  const radius = 1.0 / 3.0 - fudge;
  let dist = distance(vec2f(0.5, 2.0 / 3.0 + fudge), input.uv);

  if dist < radius {
    return vec4<f32>(0.0, 0.0, 1.0, 1.0);
  } else {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
  }
}
    `,
  });

  const pipeline = device.createRenderPipeline({
    label: 'our hardcoded red triangle pipeline',
    layout: 'auto',
    vertex: {
      module,
    },
    fragment: {
      module,
      targets: [{ format: presentationFormat }],
    },
  });

  const renderPassDescriptor = {
  ...