The MSDF stuff shouldn't be in its own uniform buffer. This is basically config stuff.

Added a compute pass that currently does nothing while I learn how to make use of it.
This commit is contained in:
Rezmason
2021-10-31 20:00:11 -07:00
parent 53e1c5502c
commit 6f58882851
3 changed files with 58 additions and 31 deletions

View File

@@ -4,8 +4,11 @@ WebGPU
First decent rainRender
Port compute pass 100%
Compute entry point can live in the same wgsl file, I think
use textureLoad for texel access in render pipeline
ping-pong buffers
Bind both ping-pong buffers in render pass
The frame integer can be used by the render code to reference the correct one
Reorder the config fields
Reconsider how the bind groups are organized?
Render target
Resize accordingly
Put in its own module
@@ -13,6 +16,7 @@ WebGPU
The other passes should be a breeze
Just add them to the render bundle
Update links in issues
std140

View File

@@ -53,6 +53,8 @@ export default async (canvas, config) => {
const configData = [
// common
{ name: "animationSpeed", type: "f32", value: config.animationSpeed },
{ name: "glyphSequenceLength", type: "i32", value: config.glyphSequenceLength },
{ name: "glyphTextureColumns", type: "i32", value: config.glyphTextureColumns },
{ name: "glyphHeightToWidth", type: "f32", value: config.glyphHeightToWidth },
{ name: "resurrectingCodeRatio", type: "f32", value: config.resurrectingCodeRatio },
{ name: "gridSize", type: "vec2<f32>", value: gridSize },
@@ -94,19 +96,6 @@ export default async (canvas, config) => {
configData.map((field) => field.value)
);
const msdfData = [
{ name: "glyphSequenceLength", type: "i32", value: config.glyphSequenceLength },
{ name: "glyphTextureColumns", type: "i32", value: config.glyphTextureColumns },
];
console.table(msdfData);
const msdfLayout = std140(msdfData.map((field) => field.type));
const msdfBuffer = makeUniformBuffer(
device,
msdfLayout,
msdfData.map((field) => field.value)
);
const timeLayout = std140(["f32", "i32"]);
const timeBuffer = makeUniformBuffer(device, timeLayout);
@@ -135,6 +124,13 @@ export default async (canvas, config) => {
const rainRenderShaderModule = device.createShaderModule({ code: rainRenderShader });
const rainComputePipeline = device.createComputePipeline({
compute: {
module: rainRenderShaderModule,
entryPoint: "computeMain",
},
});
const additiveBlendComponent = {
operation: "add",
srcFactor: "one",
@@ -161,9 +157,19 @@ export default async (canvas, config) => {
},
});
const bindGroup = device.createBindGroup({
const renderBindGroup = device.createBindGroup({
layout: rainRenderPipeline.getBindGroupLayout(0),
entries: [configBuffer, msdfBuffer, msdfSampler, msdfTexture.createView(), timeBuffer, sceneBuffer]
entries: [configBuffer, timeBuffer, sceneBuffer, msdfSampler, msdfTexture.createView()]
.map((resource) => (resource instanceof GPUBuffer ? { buffer: resource } : resource))
.map((resource, binding) => ({
binding,
resource,
})),
});
const computeBindGroup = device.createBindGroup({
layout: rainComputePipeline.getBindGroupLayout(0),
entries: [configBuffer, timeBuffer]
.map((resource) => (resource instanceof GPUBuffer ? { buffer: resource } : resource))
.map((resource, binding) => ({
binding,
@@ -176,7 +182,7 @@ export default async (canvas, config) => {
});
bundleEncoder.setPipeline(rainRenderPipeline);
bundleEncoder.setBindGroup(0, bindGroup);
bundleEncoder.setBindGroup(0, renderBindGroup);
bundleEncoder.draw(numVerticesPerQuad * numQuads, 1, 0, 0);
const renderBundles = [bundleEncoder.finish()];
@@ -209,6 +215,13 @@ export default async (canvas, config) => {
renderPassConfig.colorAttachments[0].view = canvasContext.getCurrentTexture().createView();
const encoder = device.createCommandEncoder();
const computePass = encoder.beginComputePass();
computePass.setPipeline(rainComputePipeline);
computePass.setBindGroup(0, computeBindGroup);
computePass.dispatch(...gridSize, 1);
computePass.endPass();
const renderPass = encoder.beginRenderPass(renderPassConfig);
renderPass.executeBundles(renderBundles);
renderPass.endPass();

View File

@@ -9,6 +9,8 @@ let SQRT_5 : f32 = 2.23606797749979;
[[block]] struct Config {
// common
animationSpeed : f32;
glyphSequenceLength : i32;
glyphTextureColumns : i32;
glyphHeightToWidth : f32;
resurrectingCodeRatio : f32;
gridSize : vec2<f32>;
@@ -43,29 +45,30 @@ let SQRT_5 : f32 = 2.23606797749979;
};
[[group(0), binding(0)]] var<uniform> config : Config;
[[block]] struct MSDF {
glyphSequenceLength : i32;
glyphTextureColumns : i32;
};
[[group(0), binding(1)]] var<uniform> msdf : MSDF;
[[group(0), binding(2)]] var msdfSampler : sampler;
[[group(0), binding(3)]] var msdfTexture : texture_2d<f32>;
[[block]] struct Time {
seconds : f32;
frames : i32;
};
[[group(0), binding(4)]] var<uniform> time : Time;
[[group(0), binding(1)]] var<uniform> time : Time;
[[block]] struct Scene {
screenSize : vec2<f32>;
camera : mat4x4<f32>;
transform : mat4x4<f32>;
};
[[group(0), binding(5)]] var<uniform> scene : Scene;
[[group(0), binding(2)]] var<uniform> scene : Scene;
[[group(0), binding(3)]] var msdfSampler : sampler;
[[group(0), binding(4)]] var msdfTexture : texture_2d<f32>;
// Shader params
struct ComputeInput {
[[builtin(global_invocation_id)]] id : vec3<u32>;
};
struct VertInput {
[[builtin(vertex_index)]] index : u32;
};
@@ -100,6 +103,13 @@ fn wobble(x : f32) -> f32 {
return x + 0.3 * sin(SQRT_2 * x) + 0.2 * sin(SQRT_5 * x);
}
// Compute shader
[[stage(compute), workgroup_size(1, 1, 1)]] fn computeMain(input : ComputeInput) {
var hasSun = bool(config.hasSun); // TODO: remove
var seconds = time.seconds; // TODO: remove
}
// Vertex shader
[[stage(vertex)]] fn vertMain(input : VertInput) -> VertOutput {
@@ -179,9 +189,9 @@ fn median3(i : vec3<f32>) -> f32 {
}
fn getSymbolUV(glyphCycle : f32) -> vec2<f32> {
var symbol = i32(f32(msdf.glyphSequenceLength) * glyphCycle);
var symbolX = symbol % msdf.glyphTextureColumns;
var symbolY = symbol / msdf.glyphTextureColumns;
var symbol = i32(f32(config.glyphSequenceLength) * glyphCycle);
var symbolX = symbol % config.glyphTextureColumns;
var symbolY = symbol / config.glyphTextureColumns;
return vec2<f32>(f32(symbolX), f32(symbolY));
}
@@ -233,7 +243,7 @@ fn getSymbolUV(glyphCycle : f32) -> vec2<f32> {
glyphUV = glyphUV - 0.5;
glyphUV = glyphUV * clamp(1.0 - config.glyphEdgeCrop, 0.0, 1.0);
glyphUV = glyphUV + 0.5;
var msdfUV = (glyphUV + symbolUV) / f32(msdf.glyphTextureColumns);
var msdfUV = (glyphUV + symbolUV) / f32(config.glyphTextureColumns);
// MSDF : calculate brightness of fragment based on distance to shape
var dist = textureSample(msdfTexture, msdfSampler, msdfUV).rgb;