mirror of
https://github.com/Floriansylvain/WhateverWebGPU.git
synced 2026-08-19 11:43:26 +02:00
feat: draw a red square
This commit is contained in:
+85
@@ -1 +1,86 @@
|
||||
import "./style.css"
|
||||
|
||||
async function init() {
|
||||
const canvas = document.querySelector<HTMLCanvasElement>("#canvas")
|
||||
if (!canvas) {
|
||||
throw new Error("Canvas element not found")
|
||||
}
|
||||
if (!navigator.gpu) {
|
||||
throw new Error("WebGPU not supported on this browser.")
|
||||
}
|
||||
|
||||
const adapter = await navigator.gpu.requestAdapter()
|
||||
if (!adapter) {
|
||||
throw new Error("No appropriate GPUAdapter found.")
|
||||
}
|
||||
|
||||
const context = canvas.getContext("webgpu")
|
||||
if (!context) {
|
||||
throw new Error("Failed to get WebGPU context.")
|
||||
}
|
||||
|
||||
const device = await adapter.requestDevice()
|
||||
const canvasFormat = navigator.gpu.getPreferredCanvasFormat()
|
||||
context.configure({ device, format: canvasFormat })
|
||||
|
||||
const encoder = device.createCommandEncoder()
|
||||
|
||||
const vertexBufferLayout = {
|
||||
arrayStride: 8,
|
||||
attributes: [
|
||||
{
|
||||
format: "float32x2" as GPUVertexFormat,
|
||||
offset: 0,
|
||||
shaderLocation: 0,
|
||||
},
|
||||
],
|
||||
}
|
||||
const cellShaderModule = device.createShaderModule({
|
||||
label: "Cell shader",
|
||||
code: (await import("./shaders/cell.wgsl?raw")).default,
|
||||
})
|
||||
const cellPipeline = device.createRenderPipeline({
|
||||
label: "Cell pipeline",
|
||||
layout: "auto",
|
||||
vertex: {
|
||||
module: cellShaderModule,
|
||||
entryPoint: "vertexMain",
|
||||
buffers: [vertexBufferLayout],
|
||||
},
|
||||
fragment: {
|
||||
module: cellShaderModule,
|
||||
entryPoint: "fragmentMain",
|
||||
targets: [{ format: canvasFormat }],
|
||||
},
|
||||
})
|
||||
|
||||
const vertices = new Float32Array([
|
||||
-0.8, -0.8, 0.8, -0.8, 0.8, 0.8, -0.8, -0.8, 0.8, 0.8, -0.8, 0.8,
|
||||
])
|
||||
const vertexBuffer = device.createBuffer({
|
||||
label: "Cell vertices",
|
||||
size: vertices.byteLength,
|
||||
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
||||
})
|
||||
device.queue.writeBuffer(vertexBuffer, 0, vertices)
|
||||
|
||||
const pass = encoder.beginRenderPass({
|
||||
colorAttachments: [
|
||||
{
|
||||
view: context.getCurrentTexture().createView(),
|
||||
loadOp: "clear",
|
||||
clearValue: [0.0, 0.0, 0.4, 1.0],
|
||||
storeOp: "store",
|
||||
},
|
||||
],
|
||||
})
|
||||
pass.setPipeline(cellPipeline)
|
||||
pass.setVertexBuffer(0, vertexBuffer)
|
||||
pass.draw(vertices.length / 2)
|
||||
pass.end()
|
||||
device.queue.submit([encoder.finish()])
|
||||
}
|
||||
|
||||
init().catch((error) => {
|
||||
console.error("Failed to initialize the application:", error)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@vertex
|
||||
fn vertexMain(@location(0) pos: vec2f) -> @builtin(position) vec4f {
|
||||
return vec4f(pos, 0, 1);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragmentMain() -> @location(0) vec4f {
|
||||
return vec4f(1, 0, 0, 1);
|
||||
}
|
||||
+9
-90
@@ -1,96 +1,15 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.vanilla:hover {
|
||||
filter: drop-shadow(0 0 2em #3178c6aa);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
canvas {
|
||||
width: 512px;
|
||||
height: 512px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user