summaryrefslogtreecommitdiff
path: root/public/js/webgpu.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/js/webgpu.js')
-rw-r--r--public/js/webgpu.js253
1 files changed, 253 insertions, 0 deletions
diff --git a/public/js/webgpu.js b/public/js/webgpu.js
new file mode 100644
index 0000000..b66f9ab
--- /dev/null
+++ b/public/js/webgpu.js
@@ -0,0 +1,253 @@
+//import { mat4, vec3 } from './gl-matrix/dist/gl-matrix.js';
+
+//import { formToJSON } from "axios";
+
+
+var ctx = null;
+var cnv = null;
+var wgc = null;
+var W = 800;
+var H = 600;
+
+const vertexShaderWGSL = `
+struct Uniforms {
+ modelViewProjectionMatrix : mat4x4<f32>,
+}
+@binding(0) @group(0) var<uniform> uniforms : Uniforms;
+
+struct VertexOutput {
+ @builtin(position) Position : vec4<f32>,
+ @location(0) color : vec4<f32>,
+}
+
+@vertex
+fn main(
+ @location(0) position : vec4<f32>,
+ @location(1) color : vec4<f32>
+) -> VertexOutput {
+ var output : VertexOutput;
+ output.Position = uniforms.modelViewProjectionMatrix * position;
+ output.color = color;
+ return output;
+}
+`;
+
+const fragmentShaderWGSL = `
+@fragment
+fn main(@location(0) color : vec4<f32>) -> @location(0) vec4<f32> {
+ return color;
+}
+`;
+
+$(document).ready(function() {
+ cnv = $('#c')[0];
+ if (cnv != null) {
+ //initDOM();
+ //ctx = cnv.getContext("2d");
+ W = window.outerWidth;
+ H = window.outerHeight;
+ cnv.width = W;
+ cnv.height = H;
+ //ctx.fillRect(0,0,W,H);
+
+ window.addEventListener('resize', resizeCanvas);
+ doWebGPUStuff();
+ } else {
+ console.error('Canvas element not found');
+ }
+});
+
+function resizeCanvas() {
+ W = window.outerWidth;
+ H = window.outerHeight;
+ cnv.width = W;
+ cnv.height = H;
+}
+
+async function doWebGPUStuff(){
+ console.log(navigator);
+ if (!navigator.gpu) {
+ console.error("WebGPU not supported on this browser.");
+ return;
+ }
+ const adapter = await navigator.gpu.requestAdapter();
+ if (!adapter) {
+ console.error("No appropriate GPUAdapter found.");
+ return;
+ }
+ console.log(adapter);
+
+ const device = await adapter.requestDevice();
+ console.log(device);
+
+ wgc = cnv.getContext("webgpu");
+ console.log(wgc);
+ const cnvFormat = navigator.gpu.getPreferredCanvasFormat();
+ wgc.configure({
+ device: device,
+ format: cnvFormat
+ });
+
+ const vertices = new Float32Array([
+ // Front face
+ -0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 1.0,
+ 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 1.0,
+ 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0,
+ -0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0,
+ // Back face
+ -0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
+ 0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
+ 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
+ -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
+ ]);
+
+ const indices = new Uint16Array([
+ 0, 1, 2, 0, 2, 3,
+ 1, 5, 6, 1, 6, 2,
+ 5, 4, 7, 5, 7, 6,
+ 4, 0, 3, 4, 3, 7,
+ 3, 2, 6, 3, 6, 7,
+ 4, 5, 1, 4, 1, 0
+ ]);
+
+ const vertexBuffer = device.createBuffer({
+ size: vertices.byteLength,
+ usage: GPUBufferUsage.VERTEX,
+ mappedAtCreation: true,
+ });
+ new Float32Array(vertexBuffer.getMappedRange()).set(vertices);
+ vertexBuffer.unmap();
+
+ const indexBuffer = device.createBuffer({
+ size: indices.byteLength,
+ usage: GPUBufferUsage.INDEX,
+ mappedAtCreation: true,
+ });
+ new Uint16Array(indexBuffer.getMappedRange()).set(indices);
+ indexBuffer.unmap();
+
+ const uniformBuffer = device.createBuffer({
+ size: 16 * 4,
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
+ });
+
+ const pipeline = device.createRenderPipeline({
+ layout: 'auto',
+ vertex: {
+ module: device.createShaderModule({
+ code: vertexShaderWGSL,
+ }),
+ entryPoint: 'main',
+ buffers: [
+ {
+ arrayStride: 7 * 4,
+ attributes: [
+ { shaderLocation: 0, offset: 0, format: 'float32x3' },
+ { shaderLocation: 1, offset: 3 * 4, format: 'float32x4' },
+ ],
+ },
+ ],
+ },
+ fragment: {
+ module: device.createShaderModule({
+ code: fragmentShaderWGSL,
+ }),
+ entryPoint: 'main',
+ targets: [
+ {
+ format: cnvFormat,
+ },
+ ],
+ },
+ primitive: {
+ topology: 'triangle-list',
+ },
+ depthStencil: {
+ depthWriteEnabled: true,
+ depthCompare: 'less',
+ format: 'depth24plus',
+ },
+ });
+
+ const depthTexture = device.createTexture({
+ size: [cnv.width, cnv.height],
+ format: 'depth24plus',
+ usage: GPUTextureUsage.RENDER_ATTACHMENT,
+ });
+
+ const uniformBindGroup = device.createBindGroup({
+ layout: pipeline.getBindGroupLayout(0),
+ entries: [
+ {
+ binding: 0,
+ resource: {
+ buffer: uniformBuffer,
+ },
+ },
+ ],
+ });
+
+ render(device);
+}
+
+function render (device) {
+ const aspect = cnv.width / cnv.height;
+ const projectionMatrix = mat4.create();
+ mat4.perspective(projectionMatrix, (2 * Math.PI) / 5, aspect, 1, 100.0);
+
+ const viewMatrix = mat4.create();
+ const eye = vec3.fromValues(0, 0, 4);
+ const center = vec3.fromValues(0, 0, 0);
+ const up = vec3.fromValues(0, 1, 0);
+ mat4.lookAt(viewMatrix, eye, center, up);
+
+ const modelViewProjectionMatrix = mat4.create();
+ const modelMatrix = mat4.create();
+ mat4.translate(modelMatrix, modelMatrix, [
+ (200 /*cursorPosition.x*/ / cnv.width) * 2 - 1,
+ -(( 200 /*cursorPosition.y*/ / cnv.height) * 2 - 1),
+ 0
+ ]);
+ mat4.rotate(modelMatrix, modelMatrix, Date.now() * 0.001, vec3.fromValues(0, 1, 0));
+
+ mat4.multiply(modelViewProjectionMatrix, viewMatrix, modelMatrix);
+ mat4.multiply(modelViewProjectionMatrix, projectionMatrix, modelViewProjectionMatrix);
+
+ device.queue.writeBuffer(
+ uniformBuffer,
+ 0,
+ modelViewProjectionMatrix.buffer,
+ modelViewProjectionMatrix.byteOffset,
+ modelViewProjectionMatrix.byteLength
+ );
+
+ const commandEncoder = device.createCommandEncoder();
+ const textureView = wgc.getCurrentTexture().createView();
+
+ const renderPassDescriptor = {
+ colorAttachments: [
+ {
+ view: textureView,
+ clearValue: { r: 0.1, g: 0.2, b: 0.3, a: 1.0 },
+ loadOp: 'clear',
+ storeOp: 'store',
+ },
+ ],
+ depthStencilAttachment: {
+ view: depthTexture.createView(),
+ depthClearValue: 1.0,
+ depthLoadOp: 'clear',
+ depthStoreOp: 'store',
+ },
+ };
+ const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
+ passEncoder.setPipeline(pipeline);
+ passEncoder.setBindGroup(0, uniformBindGroup);
+ passEncoder.setVertexBuffer(0, vertexBuffer);
+ passEncoder.setIndexBuffer(indexBuffer, 'uint16');
+ passEncoder.drawIndexed(36);
+ passEncoder.end();
+
+ device.queue.submit([commandEncoder.finish()]);
+ requestAnimationFrame(render);
+}