Driving more uniforms.read calls from the actual shaders.

This commit is contained in:
Rezmason
2021-11-08 03:01:46 -08:00
parent 61a3a6d783
commit 415ffa77ee
8 changed files with 31 additions and 27 deletions

View File

@@ -3,17 +3,18 @@ TODO:
WebGPU WebGPU
blur pass blur pass
Cleanup
Maybe buffer layouts and buffers can be consolidated somehow
Update links in issues Update links in issues
Try to change post processing to compute shaders once they're easier to support Try to change post processing to compute shaders once they're easier to support
gpu-uniforms (was "std140") gpu-uniforms
Resolve the memory positions of the fields in the parse layouts Is this an adequate name for it? Can't it be useful for non-uniform-related things?
Resolve each layout into a Proxy around an ArrayBuffer and three mapped typedarrays Resolve the remaining to-dos
Document and share it Try and drive use it for the palette color buffer
Test it
Demo it to others
Make improvements
License it and put it somewhere else
Write an explanation of the rain pass (and include images) Write an explanation of the rain pass (and include images)

View File

@@ -8,7 +8,6 @@ const numVerticesPerQuad = 2 * 3;
export default (context, getInputs) => { export default (context, getInputs) => {
const { config, adapter, device, canvasContext } = context; const { config, adapter, device, canvasContext } = context;
const ditherMagnitude = 0.05;
const linearSampler = device.createSampler({ const linearSampler = device.createSampler({
magFilter: "linear", magFilter: "linear",

View File

@@ -17,7 +17,7 @@ const colorToRGB = ([hue, saturation, lightness]) => {
const numVerticesPerQuad = 2 * 3; const numVerticesPerQuad = 2 * 3;
const makePalette = (device, entries) => { const makePalette = (device, paletteUniforms, entries) => {
const PALETTE_SIZE = 512; const PALETTE_SIZE = 512;
const paletteColors = Array(PALETTE_SIZE); const paletteColors = Array(PALETTE_SIZE);
@@ -79,12 +79,6 @@ const makePalette = (device, entries) => {
export default (context, getInputs) => { export default (context, getInputs) => {
const { config, adapter, device, canvasContext, timeBuffer } = context; const { config, adapter, device, canvasContext, timeBuffer } = context;
const ditherMagnitude = 0.05;
const configUniforms = uniforms.read(`struct Config { ditherMagnitude : f32; backgroundColor: vec3<f32>; };`).Config;
const configBuffer = makeUniformBuffer(device, configUniforms, { ditherMagnitude, backgroundColor: config.backgroundColor });
const paletteBuffer = makePalette(device, config.paletteEntries);
const linearSampler = device.createSampler({ const linearSampler = device.createSampler({
magFilter: "linear", magFilter: "linear",
@@ -104,6 +98,8 @@ export default (context, getInputs) => {
const presentationFormat = canvasContext.getPreferredFormat(adapter); const presentationFormat = canvasContext.getPreferredFormat(adapter);
let renderPipeline; let renderPipeline;
let configBuffer;
let paletteBuffer;
let output; let output;
const assets = [loadShader(device, "shaders/wgsl/palettePass.wgsl")]; const assets = [loadShader(device, "shaders/wgsl/palettePass.wgsl")];
@@ -126,6 +122,13 @@ export default (context, getInputs) => {
], ],
}, },
}); });
const paletteShaderUniforms = uniforms.read(paletteShader.code);
const configUniforms = paletteShaderUniforms.Config;
configBuffer = makeUniformBuffer(device, configUniforms, { ditherMagnitude: 0.05, backgroundColor: config.backgroundColor });
const paletteUniforms = paletteShaderUniforms.Palette;
paletteBuffer = makePalette(device, paletteUniforms, config.paletteEntries);
})(); })();
const setSize = (width, height) => { const setSize = (width, height) => {

View File

@@ -46,10 +46,8 @@ export default (context, getInputs) => {
// rather than a single quad for our geometry // rather than a single quad for our geometry
const numQuads = config.volumetric ? numCells : 1; const numQuads = config.volumetric ? numCells : 1;
// TODO: uniforms should be updated to provide this too
const cellsBuffer = device.createBuffer({ const cellsBuffer = device.createBuffer({
size: numCells * 4 * Float32Array.BYTES_PER_ELEMENT, size: numCells * uniforms.byteSizeOf("vec4<f32>"),
usage: GPUBufferUsage.STORAGE, usage: GPUBufferUsage.STORAGE,
}); });

View File

@@ -13,10 +13,6 @@ const numVerticesPerQuad = 2 * 3;
export default (context, getInputs) => { export default (context, getInputs) => {
const { config, adapter, device, canvasContext, timeBuffer } = context; const { config, adapter, device, canvasContext, timeBuffer } = context;
const ditherMagnitude = 0.05;
const configUniforms = uniforms.read(`struct Config { ditherMagnitude : f32; backgroundColor: vec3<f32>; };`).Config;
const configBuffer = makeUniformBuffer(device, configUniforms, { ditherMagnitude, backgroundColor: config.backgroundColor });
const linearSampler = device.createSampler({ const linearSampler = device.createSampler({
magFilter: "linear", magFilter: "linear",
@@ -36,6 +32,7 @@ export default (context, getInputs) => {
const presentationFormat = canvasContext.getPreferredFormat(adapter); const presentationFormat = canvasContext.getPreferredFormat(adapter);
let renderPipeline; let renderPipeline;
let configBuffer;
let output; let output;
const assets = [loadShader(device, "shaders/wgsl/resurrectionPass.wgsl")]; const assets = [loadShader(device, "shaders/wgsl/resurrectionPass.wgsl")];
@@ -58,6 +55,9 @@ export default (context, getInputs) => {
], ],
}, },
}); });
const configUniforms = uniforms.read(resurrectionShader.code).Config;
configBuffer = makeUniformBuffer(device, configUniforms, { ditherMagnitude: 0.05, backgroundColor: config.backgroundColor });
})(); })();
const setSize = (width, height) => { const setSize = (width, height) => {

View File

@@ -39,10 +39,6 @@ const numVerticesPerQuad = 2 * 3;
export default (context, getInputs) => { export default (context, getInputs) => {
const { config, adapter, device, canvasContext, timeBuffer } = context; const { config, adapter, device, canvasContext, timeBuffer } = context;
const ditherMagnitude = 0.05;
const configUniforms = uniforms.read(`struct Config { ditherMagnitude : f32; backgroundColor: vec3<f32>; };`).Config;
const configBuffer = makeUniformBuffer(device, configUniforms, { ditherMagnitude, backgroundColor: config.backgroundColor });
// Expand and convert stripe colors into 1D texture data // Expand and convert stripe colors into 1D texture data
const stripeColors = const stripeColors =
@@ -71,6 +67,7 @@ export default (context, getInputs) => {
const presentationFormat = canvasContext.getPreferredFormat(adapter); const presentationFormat = canvasContext.getPreferredFormat(adapter);
let renderPipeline; let renderPipeline;
let configBuffer;
let output; let output;
const assets = [loadShader(device, "shaders/wgsl/stripePass.wgsl")]; const assets = [loadShader(device, "shaders/wgsl/stripePass.wgsl")];
@@ -93,6 +90,9 @@ export default (context, getInputs) => {
], ],
}, },
}); });
const configUniforms = uniforms.read(stripeShader.code).Config;
configBuffer = makeUniformBuffer(device, configUniforms, { ditherMagnitude: 0.05, backgroundColor: config.backgroundColor });
})(); })();
const setSize = (width, height) => { const setSize = (width, height) => {

View File

@@ -32,7 +32,6 @@ const makePassFBO = (device, width, height, format = "rgba8unorm") =>
size: [width, height, 1], size: [width, height, 1],
format, format,
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
// TODO: whittle these down
}); });
const loadShader = async (device, url) => { const loadShader = async (device, url) => {

View File

@@ -211,9 +211,13 @@ const makeGenerator = (layout, structLayouts) => {
const api = Object.freeze({ const api = Object.freeze({
read: (wgsl) => { read: (wgsl) => {
if (typeof wgsl !== "string") {
throw new Error("Input is not a string.");
}
const structLayouts = parseStructLayoutsFromShader(wgsl); const structLayouts = parseStructLayoutsFromShader(wgsl);
return Object.fromEntries(Object.entries(structLayouts).map(([name, layout]) => [name, makeGenerator(layout, structLayouts)])); return Object.fromEntries(Object.entries(structLayouts).map(([name, layout]) => [name, makeGenerator(layout, structLayouts)]));
}, },
byteSizeOf: (simpleType) => simpleTypes[simpleType][1] * BYTES_PER_ELEMENT,
}); });
export default api; export default api;