Adding WebGPU to TODO.md. Annotating the parts of the WebGPU code that involve uniform buffer layout issues.

This commit is contained in:
Rezmason
2021-10-27 22:34:47 -07:00
parent c27c20f2cf
commit c3254c3aa1
4 changed files with 27 additions and 9 deletions

View File

@@ -1,5 +1,8 @@
TODO: TODO:
WebGPU
std140 problem with uniform buffers
Write an explanation of the rain pass (and include images) Write an explanation of the rain pass (and include images)
Compute Compute
Volumetric quads Volumetric quads

View File

@@ -33,7 +33,6 @@ export default async (canvas, config) => {
console.log(config); console.log(config);
const NUM_VERTICES_PER_QUAD = 6; const NUM_VERTICES_PER_QUAD = 6;
const THIRTY_TWO_BITS = 4; // 4 bytes = 32 bits
const numColumns = config.numColumns; const numColumns = config.numColumns;
const numRows = config.numColumns; const numRows = config.numColumns;
@@ -70,7 +69,8 @@ export default async (canvas, config) => {
const msdfTexture = await loadTexture(device, config.glyphTexURL); 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({ const configBuffer = device.createBuffer({
size: configBufferSize, size: configBufferSize,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, // Which of these are necessary? 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]); new Int32Array(configBuffer.getMappedRange()).set([numColumns, numRows]);
configBuffer.unmap(); configBuffer.unmap();
const msdfBufferSize = THIRTY_TWO_BITS * (1 * 1); // prettier-ignore
const msdfBufferSize = Float32Array.BYTES_PER_ELEMENT * (1);
const msdfBuffer = device.createBuffer({ const msdfBuffer = device.createBuffer({
size: msdfBufferSize, size: msdfBufferSize,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.FRAGMENT | GPUBufferUsage.COPY_DST, // Which of these are necessary? 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]); new Int32Array(msdfBuffer.getMappedRange()).set([config.glyphTextureColumns]);
msdfBuffer.unmap(); 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({ 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? 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({ const cameraBuffer = device.createBuffer({
size: configBufferSize, size: cameraBufferSize,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.VERTEX | GPUBufferUsage.COMPUTE | GPUBufferUsage.COPY_DST, // Which of these are necessary? 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 updateCameraBuffer = () => {
const canvasSize = canvasConfig.size; const canvasSize = canvasConfig.size;
const aspectRatio = canvasSize[0] / canvasSize[1]; 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]; 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(); updateCameraBuffer();

View File

@@ -23,6 +23,8 @@ let TWO_PI:f32 = 6.28318530718; // No, I'm not using Tau.
[[block]] struct CameraUniforms { [[block]] struct CameraUniforms {
screenSize: vec2<f32>; screenSize: vec2<f32>;
camera: mat4x4<f32>;
transform: mat4x4<f32>;
}; };
[[group(0), binding(5)]] var<uniform> cameraUniforms:CameraUniforms; [[group(0), binding(5)]] var<uniform> cameraUniforms:CameraUniforms;

View File

@@ -41,4 +41,5 @@ Textures were never resizable, you simply forgot
Bind groups let you bind a bunch of resources at once Bind groups let you bind a bunch of resources at once
Render bundles let you reissue commands Render bundles let you reissue commands
You can only use up to FOUR bind groups on your laptop's device! 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!