mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-18 14:19:30 -07:00
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:
6
TODO.txt
6
TODO.txt
@@ -4,8 +4,11 @@ WebGPU
|
|||||||
First decent rainRender
|
First decent rainRender
|
||||||
Port compute pass 100%
|
Port compute pass 100%
|
||||||
Compute entry point can live in the same wgsl file, I think
|
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
|
Reorder the config fields
|
||||||
|
Reconsider how the bind groups are organized?
|
||||||
Render target
|
Render target
|
||||||
Resize accordingly
|
Resize accordingly
|
||||||
Put in its own module
|
Put in its own module
|
||||||
@@ -13,6 +16,7 @@ WebGPU
|
|||||||
The other passes should be a breeze
|
The other passes should be a breeze
|
||||||
Just add them to the render bundle
|
Just add them to the render bundle
|
||||||
|
|
||||||
|
|
||||||
Update links in issues
|
Update links in issues
|
||||||
|
|
||||||
std140
|
std140
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ export default async (canvas, config) => {
|
|||||||
const configData = [
|
const configData = [
|
||||||
// common
|
// common
|
||||||
{ name: "animationSpeed", type: "f32", value: config.animationSpeed },
|
{ 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: "glyphHeightToWidth", type: "f32", value: config.glyphHeightToWidth },
|
||||||
{ name: "resurrectingCodeRatio", type: "f32", value: config.resurrectingCodeRatio },
|
{ name: "resurrectingCodeRatio", type: "f32", value: config.resurrectingCodeRatio },
|
||||||
{ name: "gridSize", type: "vec2<f32>", value: gridSize },
|
{ name: "gridSize", type: "vec2<f32>", value: gridSize },
|
||||||
@@ -94,19 +96,6 @@ export default async (canvas, config) => {
|
|||||||
configData.map((field) => field.value)
|
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 timeLayout = std140(["f32", "i32"]);
|
||||||
const timeBuffer = makeUniformBuffer(device, timeLayout);
|
const timeBuffer = makeUniformBuffer(device, timeLayout);
|
||||||
|
|
||||||
@@ -135,6 +124,13 @@ export default async (canvas, config) => {
|
|||||||
|
|
||||||
const rainRenderShaderModule = device.createShaderModule({ code: rainRenderShader });
|
const rainRenderShaderModule = device.createShaderModule({ code: rainRenderShader });
|
||||||
|
|
||||||
|
const rainComputePipeline = device.createComputePipeline({
|
||||||
|
compute: {
|
||||||
|
module: rainRenderShaderModule,
|
||||||
|
entryPoint: "computeMain",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const additiveBlendComponent = {
|
const additiveBlendComponent = {
|
||||||
operation: "add",
|
operation: "add",
|
||||||
srcFactor: "one",
|
srcFactor: "one",
|
||||||
@@ -161,9 +157,19 @@ export default async (canvas, config) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const bindGroup = device.createBindGroup({
|
const renderBindGroup = device.createBindGroup({
|
||||||
layout: rainRenderPipeline.getBindGroupLayout(0),
|
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) => (resource instanceof GPUBuffer ? { buffer: resource } : resource))
|
||||||
.map((resource, binding) => ({
|
.map((resource, binding) => ({
|
||||||
binding,
|
binding,
|
||||||
@@ -176,7 +182,7 @@ export default async (canvas, config) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
bundleEncoder.setPipeline(rainRenderPipeline);
|
bundleEncoder.setPipeline(rainRenderPipeline);
|
||||||
bundleEncoder.setBindGroup(0, bindGroup);
|
bundleEncoder.setBindGroup(0, renderBindGroup);
|
||||||
bundleEncoder.draw(numVerticesPerQuad * numQuads, 1, 0, 0);
|
bundleEncoder.draw(numVerticesPerQuad * numQuads, 1, 0, 0);
|
||||||
const renderBundles = [bundleEncoder.finish()];
|
const renderBundles = [bundleEncoder.finish()];
|
||||||
|
|
||||||
@@ -209,6 +215,13 @@ export default async (canvas, config) => {
|
|||||||
renderPassConfig.colorAttachments[0].view = canvasContext.getCurrentTexture().createView();
|
renderPassConfig.colorAttachments[0].view = canvasContext.getCurrentTexture().createView();
|
||||||
|
|
||||||
const encoder = device.createCommandEncoder();
|
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);
|
const renderPass = encoder.beginRenderPass(renderPassConfig);
|
||||||
renderPass.executeBundles(renderBundles);
|
renderPass.executeBundles(renderBundles);
|
||||||
renderPass.endPass();
|
renderPass.endPass();
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ let SQRT_5 : f32 = 2.23606797749979;
|
|||||||
[[block]] struct Config {
|
[[block]] struct Config {
|
||||||
// common
|
// common
|
||||||
animationSpeed : f32;
|
animationSpeed : f32;
|
||||||
|
glyphSequenceLength : i32;
|
||||||
|
glyphTextureColumns : i32;
|
||||||
glyphHeightToWidth : f32;
|
glyphHeightToWidth : f32;
|
||||||
resurrectingCodeRatio : f32;
|
resurrectingCodeRatio : f32;
|
||||||
gridSize : vec2<f32>;
|
gridSize : vec2<f32>;
|
||||||
@@ -43,29 +45,30 @@ let SQRT_5 : f32 = 2.23606797749979;
|
|||||||
};
|
};
|
||||||
[[group(0), binding(0)]] var<uniform> config : Config;
|
[[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 {
|
[[block]] struct Time {
|
||||||
seconds : f32;
|
seconds : f32;
|
||||||
frames : i32;
|
frames : i32;
|
||||||
};
|
};
|
||||||
[[group(0), binding(4)]] var<uniform> time : Time;
|
[[group(0), binding(1)]] var<uniform> time : Time;
|
||||||
|
|
||||||
[[block]] struct Scene {
|
[[block]] struct Scene {
|
||||||
screenSize : vec2<f32>;
|
screenSize : vec2<f32>;
|
||||||
camera : mat4x4<f32>;
|
camera : mat4x4<f32>;
|
||||||
transform : 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
|
// Shader params
|
||||||
|
|
||||||
|
struct ComputeInput {
|
||||||
|
[[builtin(global_invocation_id)]] id : vec3<u32>;
|
||||||
|
};
|
||||||
|
|
||||||
struct VertInput {
|
struct VertInput {
|
||||||
[[builtin(vertex_index)]] index : u32;
|
[[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);
|
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
|
// Vertex shader
|
||||||
|
|
||||||
[[stage(vertex)]] fn vertMain(input : VertInput) -> VertOutput {
|
[[stage(vertex)]] fn vertMain(input : VertInput) -> VertOutput {
|
||||||
@@ -179,9 +189,9 @@ fn median3(i : vec3<f32>) -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn getSymbolUV(glyphCycle : f32) -> vec2<f32> {
|
fn getSymbolUV(glyphCycle : f32) -> vec2<f32> {
|
||||||
var symbol = i32(f32(msdf.glyphSequenceLength) * glyphCycle);
|
var symbol = i32(f32(config.glyphSequenceLength) * glyphCycle);
|
||||||
var symbolX = symbol % msdf.glyphTextureColumns;
|
var symbolX = symbol % config.glyphTextureColumns;
|
||||||
var symbolY = symbol / msdf.glyphTextureColumns;
|
var symbolY = symbol / config.glyphTextureColumns;
|
||||||
return vec2<f32>(f32(symbolX), f32(symbolY));
|
return vec2<f32>(f32(symbolX), f32(symbolY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +243,7 @@ fn getSymbolUV(glyphCycle : f32) -> vec2<f32> {
|
|||||||
glyphUV = glyphUV - 0.5;
|
glyphUV = glyphUV - 0.5;
|
||||||
glyphUV = glyphUV * clamp(1.0 - config.glyphEdgeCrop, 0.0, 1.0);
|
glyphUV = glyphUV * clamp(1.0 - config.glyphEdgeCrop, 0.0, 1.0);
|
||||||
glyphUV = glyphUV + 0.5;
|
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
|
// MSDF : calculate brightness of fragment based on distance to shape
|
||||||
var dist = textureSample(msdfTexture, msdfSampler, msdfUV).rgb;
|
var dist = textureSample(msdfTexture, msdfSampler, msdfUV).rgb;
|
||||||
|
|||||||
Reference in New Issue
Block a user