mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-22 15:49:30 -07:00
The delimiter between WGSL struct fields is now a comma, which is also the delimiter between parameters in angle brackets, so gpu-buffer needs to be a little cleverer with the lines it separates.
This commit is contained in:
@@ -50,7 +50,7 @@ export default async (canvas, config) => {
|
|||||||
GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST,
|
GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST,
|
||||||
};
|
};
|
||||||
|
|
||||||
const timeUniforms = structs.from(`struct Time { seconds : f32; frames : i32; };`).Time;
|
const timeUniforms = structs.from(`struct Time { seconds : f32, frames : i32, };`).Time;
|
||||||
const timeBuffer = makeUniformBuffer(device, timeUniforms);
|
const timeBuffer = makeUniformBuffer(device, timeUniforms);
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ const getTypeData = (type, attributes, otherStructLayouts) => {
|
|||||||
const parseAttributes = (str) => {
|
const parseAttributes = (str) => {
|
||||||
const attributes = {};
|
const attributes = {};
|
||||||
for (const attr of str.split(",").filter((attr) => attr.length > 0)) {
|
for (const attr of str.split(",").filter((attr) => attr.length > 0)) {
|
||||||
const match = attr.match(/@(\w+)(\((.*)\))?/); // @foo(bar)
|
const match = attr.match(/(\w+)(\((.*)\))?/); // foo(bar)
|
||||||
const [_, identifier, __, value] = match;
|
const [_, identifier, __, value] = match;
|
||||||
attributes[identifier] = value;
|
attributes[identifier] = value;
|
||||||
}
|
}
|
||||||
@@ -128,16 +128,33 @@ const parseStructLayout = (identifier, body, structLayouts) => {
|
|||||||
let byteOffset = 0;
|
let byteOffset = 0;
|
||||||
const lines = body
|
const lines = body
|
||||||
.trim()
|
.trim()
|
||||||
.split(";")
|
.split(",") // WGSL struct fields are currently delimited by commas...
|
||||||
.filter((s) => s.length > 0);
|
.filter((s) => s.length > 0)
|
||||||
|
// ...but some commas separate elements between angle brackets, rather than between lines:
|
||||||
|
.reduce((existingLines, line, index) => {
|
||||||
|
|
||||||
|
if (index === 0) {
|
||||||
|
return [line];
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastLine = existingLines[index - 1];
|
||||||
|
const angleBracketBalance = lastLine.split("<").length - lastLine.split(">").length;
|
||||||
|
if (angleBracketBalance !== 0) {
|
||||||
|
existingLines[index - 1] = `${lastLine},${line}`;
|
||||||
|
} else {
|
||||||
|
existingLines.push(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingLines;
|
||||||
|
}, []);
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
console.log(line);
|
const fieldMatch = line.match(/(@(.*?))? ?(\w+) ?: ?(@(.*?))? ?(.*)/); // @a(...) @b(...) foo : @c(...) @d(...) bar;
|
||||||
const fieldMatch = line.match(/(\[\[(.*?)\]\])? ?(\w+) ?: ?(\[\[(.*?)\]\])? ?(.*)/); // @a(...) @b(...) foo : @c(...) @d(...) bar;
|
|
||||||
const [_, __, leftAttributes, identifier, ___, rightAttributes, type] = fieldMatch;
|
const [_, __, leftAttributes, identifier, ___, rightAttributes, type] = fieldMatch;
|
||||||
|
|
||||||
const typeData = getTypeData(type, parseAttributes(rightAttributes ?? ""), structLayouts);
|
const typeData = getTypeData(type, parseAttributes(rightAttributes ?? ""), structLayouts);
|
||||||
if (typeData == null) {
|
if (typeData == null) {
|
||||||
console.warn(`gSkipping struct ${identifier}.`);
|
console.warn(`Skipping struct ${identifier}.`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,6 +183,7 @@ const parseStructLayoutsFromShader = (wgsl) => {
|
|||||||
|
|
||||||
const structLayouts = {};
|
const structLayouts = {};
|
||||||
const structMatches = Array.from(wgsl.matchAll(/struct (\w+) ?\{(.*?)\};/g)); // struct Foo {...}
|
const structMatches = Array.from(wgsl.matchAll(/struct (\w+) ?\{(.*?)\};/g)); // struct Foo {...}
|
||||||
|
|
||||||
for (const structMatch of structMatches) {
|
for (const structMatch of structMatches) {
|
||||||
const [_, identifier, body] = structMatch;
|
const [_, identifier, body] = structMatch;
|
||||||
const layout = parseStructLayout(identifier, body, structLayouts);
|
const layout = parseStructLayout(identifier, body, structLayouts);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
let ONE_OVER_SQRT_2PI = 0.39894;
|
let ONE_OVER_SQRT_2PI = 0.39894;
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
bloomRadius : f32;
|
bloomRadius : f32,
|
||||||
direction : vec2<f32>;
|
direction : vec2<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> config : Config;
|
@group(0) @binding(0) var<uniform> config : Config;
|
||||||
@@ -11,7 +11,7 @@ struct Config {
|
|||||||
@group(0) @binding(3) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
@group(0) @binding(3) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
struct ComputeInput {
|
struct ComputeInput {
|
||||||
@builtin(global_invocation_id) id : vec3<u32>;
|
@builtin(global_invocation_id) id : vec3<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn gaussianPDF(x : f32) -> f32 {
|
fn gaussianPDF(x : f32) -> f32 {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
struct Config {
|
struct Config {
|
||||||
pyramidHeight : f32;
|
pyramidHeight : f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> config : Config;
|
@group(0) @binding(0) var<uniform> config : Config;
|
||||||
@@ -16,7 +16,7 @@ struct Config {
|
|||||||
@group(0) @binding(6) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
@group(0) @binding(6) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
struct ComputeInput {
|
struct ComputeInput {
|
||||||
@builtin(global_invocation_id) id : vec3<u32>;
|
@builtin(global_invocation_id) id : vec3<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) {
|
@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
@group(0) @binding(1) var tex : texture_2d<f32>;
|
@group(0) @binding(1) var tex : texture_2d<f32>;
|
||||||
|
|
||||||
struct VertOutput {
|
struct VertOutput {
|
||||||
@builtin(position) Position : vec4<f32>;
|
@builtin(position) Position : vec4<f32>,
|
||||||
@location(0) uv : vec2<f32>;
|
@location(0) uv : vec2<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
@stage(vertex) fn vertMain(@builtin(vertex_index) index : u32) -> VertOutput {
|
@stage(vertex) fn vertMain(@builtin(vertex_index) index : u32) -> VertOutput {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
struct Config {
|
struct Config {
|
||||||
bloomStrength : f32;
|
bloomStrength : f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> config : Config;
|
@group(0) @binding(0) var<uniform> config : Config;
|
||||||
@@ -10,7 +10,7 @@ struct Config {
|
|||||||
@group(0) @binding(5) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
@group(0) @binding(5) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
struct ComputeInput {
|
struct ComputeInput {
|
||||||
@builtin(global_invocation_id) id : vec3<u32>;
|
@builtin(global_invocation_id) id : vec3<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn getBrightness(uv : vec2<f32>) -> vec4<f32> {
|
fn getBrightness(uv : vec2<f32>) -> vec4<f32> {
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
struct Config {
|
struct Config {
|
||||||
bloomStrength : f32;
|
bloomStrength : f32,
|
||||||
ditherMagnitude : f32;
|
ditherMagnitude : f32,
|
||||||
backgroundColor : vec3<f32>;
|
backgroundColor : vec3<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Palette {
|
struct Palette {
|
||||||
colors : array<vec3<f32>, 512>;
|
colors : array<vec3<f32>, 512>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Time {
|
struct Time {
|
||||||
seconds : f32;
|
seconds : f32,
|
||||||
frames : i32;
|
frames : i32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> config : Config;
|
@group(0) @binding(0) var<uniform> config : Config;
|
||||||
@@ -22,7 +22,7 @@ struct Time {
|
|||||||
@group(0) @binding(6) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
@group(0) @binding(6) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
struct ComputeInput {
|
struct ComputeInput {
|
||||||
@builtin(global_invocation_id) id : vec3<u32>;
|
@builtin(global_invocation_id) id : vec3<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
let PI : f32 = 3.14159265359;
|
let PI : f32 = 3.14159265359;
|
||||||
|
|||||||
@@ -3,60 +3,60 @@
|
|||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
// common properties used for compute and rendering
|
// common properties used for compute and rendering
|
||||||
animationSpeed : f32;
|
animationSpeed : f32,
|
||||||
glyphSequenceLength : i32;
|
glyphSequenceLength : i32,
|
||||||
glyphTextureGridSize : vec2<i32>;
|
glyphTextureGridSize : vec2<i32>,
|
||||||
glyphHeightToWidth : f32;
|
glyphHeightToWidth : f32,
|
||||||
resurrectingCodeRatio : f32;
|
resurrectingCodeRatio : f32,
|
||||||
gridSize : vec2<f32>;
|
gridSize : vec2<f32>,
|
||||||
showComputationTexture : i32;
|
showComputationTexture : i32,
|
||||||
|
|
||||||
// compute-specific properties
|
// compute-specific properties
|
||||||
brightnessThreshold : f32;
|
brightnessThreshold : f32,
|
||||||
brightnessOverride : f32;
|
brightnessOverride : f32,
|
||||||
brightnessDecay : f32;
|
brightnessDecay : f32,
|
||||||
cursorEffectThreshold : f32;
|
cursorEffectThreshold : f32,
|
||||||
cycleSpeed : f32;
|
cycleSpeed : f32,
|
||||||
cycleFrameSkip : i32;
|
cycleFrameSkip : i32,
|
||||||
fallSpeed : f32;
|
fallSpeed : f32,
|
||||||
hasSun : i32;
|
hasSun : i32,
|
||||||
hasThunder : i32;
|
hasThunder : i32,
|
||||||
raindropLength : f32;
|
raindropLength : f32,
|
||||||
rippleScale : f32;
|
rippleScale : f32,
|
||||||
rippleSpeed : f32;
|
rippleSpeed : f32,
|
||||||
rippleThickness : f32;
|
rippleThickness : f32,
|
||||||
cycleStyle : i32;
|
cycleStyle : i32,
|
||||||
rippleType : i32;
|
rippleType : i32,
|
||||||
|
|
||||||
// render-specific properties
|
// render-specific properties
|
||||||
forwardSpeed : f32;
|
forwardSpeed : f32,
|
||||||
glyphVerticalSpacing : f32;
|
glyphVerticalSpacing : f32,
|
||||||
glyphEdgeCrop : f32;
|
glyphEdgeCrop : f32,
|
||||||
isPolar : i32;
|
isPolar : i32,
|
||||||
density : f32;
|
density : f32,
|
||||||
slantScale : f32;
|
slantScale : f32,
|
||||||
slantVec : vec2<f32>;
|
slantVec : vec2<f32>,
|
||||||
volumetric : i32;
|
volumetric : i32,
|
||||||
loops : i32;
|
loops : i32,
|
||||||
highPassThreshold : f32;
|
highPassThreshold : f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The properties that change over time get their own buffer.
|
// The properties that change over time get their own buffer.
|
||||||
struct Time {
|
struct Time {
|
||||||
seconds : f32;
|
seconds : f32,
|
||||||
frames : i32;
|
frames : i32,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The properties related to the size of the canvas get their own buffer.
|
// The properties related to the size of the canvas get their own buffer.
|
||||||
struct Scene {
|
struct Scene {
|
||||||
screenSize : vec2<f32>;
|
screenSize : vec2<f32>,
|
||||||
camera : mat4x4<f32>;
|
camera : mat4x4<f32>,
|
||||||
transform : mat4x4<f32>;
|
transform : mat4x4<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The array of cells that the compute shader updates, and the fragment shader draws.
|
// The array of cells that the compute shader updates, and the fragment shader draws.
|
||||||
struct CellData {
|
struct CellData {
|
||||||
cells: array<vec4<f32>>;
|
cells: array<vec4<f32>>,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Shared bindings
|
// Shared bindings
|
||||||
@@ -75,23 +75,23 @@ struct CellData {
|
|||||||
// Shader params
|
// Shader params
|
||||||
|
|
||||||
struct ComputeInput {
|
struct ComputeInput {
|
||||||
@builtin(global_invocation_id) id : vec3<u32>;
|
@builtin(global_invocation_id) id : vec3<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertInput {
|
struct VertInput {
|
||||||
@builtin(vertex_index) index : u32;
|
@builtin(vertex_index) index : u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertOutput {
|
struct VertOutput {
|
||||||
@builtin(position) Position : vec4<f32>;
|
@builtin(position) Position : vec4<f32>,
|
||||||
@location(0) uv : vec2<f32>;
|
@location(0) uv : vec2<f32>,
|
||||||
@location(1) channel : vec3<f32>;
|
@location(1) channel : vec3<f32>,
|
||||||
@location(2) glyph : vec4<f32>;
|
@location(2) glyph : vec4<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FragOutput {
|
struct FragOutput {
|
||||||
@location(0) color : vec4<f32>;
|
@location(0) color : vec4<f32>,
|
||||||
@location(1) highPassColor : vec4<f32>;
|
@location(1) highPassColor : vec4<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
struct Config {
|
struct Config {
|
||||||
bloomStrength : f32;
|
bloomStrength : f32,
|
||||||
ditherMagnitude : f32;
|
ditherMagnitude : f32,
|
||||||
backgroundColor : vec3<f32>;
|
backgroundColor : vec3<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Time {
|
struct Time {
|
||||||
seconds : f32;
|
seconds : f32,
|
||||||
frames : i32;
|
frames : i32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> config : Config;
|
@group(0) @binding(0) var<uniform> config : Config;
|
||||||
@@ -17,7 +17,7 @@ struct Time {
|
|||||||
@group(0) @binding(5) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
@group(0) @binding(5) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
struct ComputeInput {
|
struct ComputeInput {
|
||||||
@builtin(global_invocation_id) id : vec3<u32>;
|
@builtin(global_invocation_id) id : vec3<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
let PI : f32 = 3.14159265359;
|
let PI : f32 = 3.14159265359;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
struct Config {
|
struct Config {
|
||||||
bloomStrength : f32;
|
bloomStrength : f32,
|
||||||
ditherMagnitude : f32;
|
ditherMagnitude : f32,
|
||||||
backgroundColor : vec3<f32>;
|
backgroundColor : vec3<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Time {
|
struct Time {
|
||||||
seconds : f32;
|
seconds : f32,
|
||||||
frames : i32;
|
frames : i32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> config : Config;
|
@group(0) @binding(0) var<uniform> config : Config;
|
||||||
@@ -18,7 +18,7 @@ struct Time {
|
|||||||
@group(0) @binding(6) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
@group(0) @binding(6) var outputTex : texture_storage_2d<rgba8unorm, write>;
|
||||||
|
|
||||||
struct ComputeInput {
|
struct ComputeInput {
|
||||||
@builtin(global_invocation_id) id : vec3<u32>;
|
@builtin(global_invocation_id) id : vec3<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
let PI : f32 = 3.14159265359;
|
let PI : f32 = 3.14159265359;
|
||||||
|
|||||||
Reference in New Issue
Block a user