From c3254c3aa1e9dd5288af3c4509b708bab60c6ac3 Mon Sep 17 00:00:00 2001 From: Rezmason Date: Wed, 27 Oct 2021 22:34:47 -0700 Subject: [PATCH] Adding WebGPU to TODO.md. Annotating the parts of the WebGPU code that involve uniform buffer layout issues. --- TODO.txt | 3 +++ js/webgpu_main.js | 28 ++++++++++++++++++++-------- shaders/rainRenderPass.wgsl | 2 ++ webgpu_notes.txt | 3 ++- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/TODO.txt b/TODO.txt index 3332431..9b66b79 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,5 +1,8 @@ TODO: +WebGPU + std140 problem with uniform buffers + Write an explanation of the rain pass (and include images) Compute Volumetric quads diff --git a/js/webgpu_main.js b/js/webgpu_main.js index 7e8a063..8a6b548 100644 --- a/js/webgpu_main.js +++ b/js/webgpu_main.js @@ -33,7 +33,6 @@ export default async (canvas, config) => { console.log(config); const NUM_VERTICES_PER_QUAD = 6; - const THIRTY_TWO_BITS = 4; // 4 bytes = 32 bits const numColumns = config.numColumns; const numRows = config.numColumns; @@ -70,7 +69,8 @@ export default async (canvas, config) => { const msdfTexture = await loadTexture(device, config.glyphTexURL); - const configBufferSize = THIRTY_TWO_BITS * (1 * 1 + 1 * 1); + // prettier-ignore + const configBufferSize = Float32Array.BYTES_PER_ELEMENT * (1 + 1); const configBuffer = device.createBuffer({ size: configBufferSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, // Which of these are necessary? @@ -79,7 +79,8 @@ export default async (canvas, config) => { new Int32Array(configBuffer.getMappedRange()).set([numColumns, numRows]); configBuffer.unmap(); - const msdfBufferSize = THIRTY_TWO_BITS * (1 * 1); + // prettier-ignore + const msdfBufferSize = Float32Array.BYTES_PER_ELEMENT * (1); const msdfBuffer = device.createBuffer({ size: msdfBufferSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.FRAGMENT | GPUBufferUsage.COPY_DST, // Which of these are necessary? @@ -88,23 +89,34 @@ export default async (canvas, config) => { new Int32Array(msdfBuffer.getMappedRange()).set([config.glyphTextureColumns]); msdfBuffer.unmap(); - const timeBufferSize = THIRTY_TWO_BITS * (1 * 1 + 1 * 1); + // prettier-ignore + const timeBufferSize = Float32Array.BYTES_PER_ELEMENT * (1 + 1); const timeBuffer = device.createBuffer({ - size: configBufferSize, + size: timeBufferSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.VERTEX | GPUBufferUsage.FRAGMENT | GPUBufferUsage.COMPUTE | GPUBufferUsage.COPY_DST, // Which of these are necessary? }); - const cameraBufferSize = THIRTY_TWO_BITS * (1 * 2); + // prettier-ignore + const cameraBufferSize = Float32Array.BYTES_PER_ELEMENT * (2 /* ??? */ + 2 + 16 + 16); const cameraBuffer = device.createBuffer({ - size: configBufferSize, + size: cameraBufferSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.VERTEX | GPUBufferUsage.COMPUTE | GPUBufferUsage.COPY_DST, // Which of these are necessary? }); + const { mat4, vec3 } = glMatrix; + const camera = mat4.create(); + const translation = vec3.set(vec3.create(), 0, 0.5 / numRows, -1); + const scale = vec3.set(vec3.create(), 1, 1, 1); + const transform = mat4.create(); + mat4.translate(transform, transform, translation); + mat4.scale(transform, transform, scale); + const updateCameraBuffer = () => { const canvasSize = canvasConfig.size; const aspectRatio = canvasSize[0] / canvasSize[1]; + mat4.perspective(camera, (Math.PI / 180) * 90, aspectRatio, 0.0001, 1000); const screenSize = aspectRatio > 1 ? [1, aspectRatio] : [1 / aspectRatio, 1]; - queue.writeBuffer(cameraBuffer, 0, new Float32Array(screenSize)); + queue.writeBuffer(cameraBuffer, 0, new Float32Array([...screenSize, /* ??? */ -1, -1, ...camera, ...transform])); }; updateCameraBuffer(); diff --git a/shaders/rainRenderPass.wgsl b/shaders/rainRenderPass.wgsl index d10a636..d745aea 100644 --- a/shaders/rainRenderPass.wgsl +++ b/shaders/rainRenderPass.wgsl @@ -23,6 +23,8 @@ let TWO_PI:f32 = 6.28318530718; // No, I'm not using Tau. [[block]] struct CameraUniforms { screenSize: vec2; + camera: mat4x4; + transform: mat4x4; }; [[group(0), binding(5)]] var cameraUniforms:CameraUniforms; diff --git a/webgpu_notes.txt b/webgpu_notes.txt index f03b14e..70743f8 100644 --- a/webgpu_notes.txt +++ b/webgpu_notes.txt @@ -41,4 +41,5 @@ Textures were never resizable, you simply forgot Bind groups let you bind a bunch of resources at once Render bundles let you reissue commands -You can only use up to FOUR bind groups on your laptop's device! \ No newline at end of file +You can only use up to FOUR bind groups on your laptop's device! +Here's an annoying gotcha: uniform buffers are like classic UBOs, and have esoteric ("std140") layout requirements! \ No newline at end of file