From 5cd99541c28e31759276fff1dd3fcc60f40d13b8 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Fri, 2 Jun 2023 18:46:57 -0600 Subject: [PATCH 01/16] Dispatch workgroups per RenderPass --- examples/random3/compute.js | 55 ++++++++++++++---------------------- examples/random3/index.js | 9 ++++-- src/absulit.points.module.js | 24 ++++++++++++++-- 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/examples/random3/compute.js b/examples/random3/compute.js index 496b814f..53675adb 100644 --- a/examples/random3/compute.js +++ b/examples/random3/compute.js @@ -9,7 +9,7 @@ ${rand} ${RGBAFromHSV} ${fnusin} -const workgroupSize = 8; +const workgroupSize = 1; @compute @workgroup_size(workgroupSize,workgroupSize,1) fn main( @@ -21,40 +21,27 @@ fn main( let numColumns:f32 = params.screenWidth; let numRows:f32 = params.screenHeight; - let numColumnsPiece:i32 = i32(numColumns / f32(workgroupSize)); - let numRowsPiece:i32 = i32(numRows / f32(workgroupSize)); - - for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { - let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); - let ux = u32(x); - let ix = i32(x); - let nx = x / numColumns; - for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { - - let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); - let uy = u32(y); - let iy = i32(y); - let ny = y / numRows; - - rand_seed.x += f32(WorkGroupID.x); - rand_seed.y += f32(WorkGroupID.y); - - seed += i32(WorkGroupID.x + WorkGroupID.y); - - let randNumber = rand(); - rand_seed.y += randNumber + fract(params.sliderA); - var v = 0.; - if(randNumber < .5){ - v = 1.; - } - - // textureStore(outputTex, vec2(ux,uy), vec4(randNumber)); - // textureStore(outputTex, vec2(ux,uy), RGBAFromHSV(randNumber, 1, 1)); - // textureStore(outputTex, vec2(ux,uy), RGBAFromHSV( fnusin(randNumber), 1, 1)); - // textureStore(outputTex, vec2(ux,uy), vec4( fnusin(randNumber))); - textureStore(outputTex, vec2(ux,uy), vec4( fract(randNumber + fnusin(1)))); - } + rand_seed.x += f32(WorkGroupID.x); + rand_seed.y += f32(WorkGroupID.y); + + seed += i32(WorkGroupID.x + WorkGroupID.y); + + let randNumber = rand(); + rand_seed.y += randNumber + fract(params.sliderA); + var v = 0.; + if(randNumber < .5){ + v = 1.; } + + // textureStore(outputTex, GlobalId.xy, vec4(randNumber)); + // textureStore(outputTex, GlobalId.xy, RGBAFromHSV(randNumber, 1, 1)); + // textureStore(outputTex, GlobalId.xy, RGBAFromHSV( fnusin(randNumber), 1, 1)); + // textureStore(outputTex, GlobalId.xy, vec4( fnusin(randNumber))); + + textureStore(outputTex, GlobalId.xy, vec4( fract(randNumber + fnusin(1)))); + // textureStore(outputTex, WorkGroupID.xy, vec4( fract(randNumber + fnusin(1)))); + // textureStore(outputTex, LocalInvocationID.xy, vec4( fract(randNumber + fnusin(1)))); + } `; diff --git a/examples/random3/index.js b/examples/random3/index.js index ed686906..9d7cb854 100644 --- a/examples/random3/index.js +++ b/examples/random3/index.js @@ -1,10 +1,13 @@ import vert from './vert.js'; import compute from './compute.js'; import frag from './frag.js'; +import { RenderPass } from '../../src/absulit.points.module.js'; + const random3 = { - vert, - compute, - frag, + + renderPasses: [ + new RenderPass(vert, frag, compute, 800, 800) + ], init: async points => { points.addSampler('feedbackSampler'); points.addTexture2d('feedbackTexture', true); diff --git a/src/absulit.points.module.js b/src/absulit.points.module.js index 2fe56996..f2588d7a 100644 --- a/src/absulit.points.module.js +++ b/src/absulit.points.module.js @@ -32,7 +32,7 @@ export class RenderPass { * @param {String} fragmentShader WGSL Fragment Shader in a String. * @param {String} computeShader WGSL Compute Shader in a String. */ - constructor(vertexShader, fragmentShader, computeShader) { + constructor(vertexShader, fragmentShader, computeShader, workgroupCountX, workgroupCountY, workgroupCountZ) { this._vertexShader = vertexShader; this._computeShader = computeShader; this._fragmentShader = fragmentShader; @@ -56,6 +56,10 @@ export class RenderPass { this._hasFragmentShader = !!this._fragmentShader; this._hasVertexAndFragmentShader = this._hasVertexShader && this._hasFragmentShader; + + this._workgroupCountX = workgroupCountX || 8; + this._workgroupCountY = workgroupCountY || 8; + this._workgroupCountZ = workgroupCountZ || 1; } get internal() { @@ -129,6 +133,18 @@ export class RenderPass { get hasVertexAndFragmentShader() { return this._hasVertexAndFragmentShader; } + + get workgroupCountX() { + return this._workgroupCountX; + } + + get workgroupCountY() { + return this._workgroupCountY; + } + + get workgroupCountZ() { + return this._workgroupCountZ; + } } export class VertexBufferInfo { @@ -1427,7 +1443,11 @@ export default class Points { if (this._uniforms.length) { passEncoder.setBindGroup(0, renderPass.computeBindGroup); } - passEncoder.dispatchWorkgroups(8, 8, 1); + passEncoder.dispatchWorkgroups( + renderPass.workgroupCountX, + renderPass.workgroupCountY, + renderPass.workgroupCountZ + ); passEncoder.end(); } }); From 1a0fa0d23f266adcf325f984e39d19dbc8f2a8d3 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Fri, 2 Jun 2023 19:09:36 -0600 Subject: [PATCH 02/16] random 2 with better workgroups --- examples/random2/compute.js | 34 ++++------------------------------ examples/random2/index.js | 7 ++++--- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/examples/random2/compute.js b/examples/random2/compute.js index 4a6e2b9a..d0dd69dd 100644 --- a/examples/random2/compute.js +++ b/examples/random2/compute.js @@ -8,41 +8,15 @@ fn main( @builtin(workgroup_id) WorkGroupID: vec3, @builtin(local_invocation_id) LocalInvocationID: vec3 ) { - - let dims = textureDimensions(feedbackTexture); - let numColumns:f32 = f32(dims.x); - let numRows:f32 = f32(dims.y); - - let numColumnsPiece:i32 = i32(numColumns / f32(workgroupSize)); - let numRowsPiece:i32 = i32(numRows / f32(workgroupSize)); - - //-------------------------------------------------- - for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { - let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); - let ux = u32(x); - // let ix = i32(x); - // let nx = x / numColumns; - for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { - - let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); - let uy = u32(y); - // let iy = i32(y); - // let ny = y / numRows; - // let uv = vec2(nx,ny); - - let pointIndex = i32(y + (x * numColumns)); - let c = rands[pointIndex]; - - let positionU = vec2(ux,uy); - textureStore(outputTex, positionU, vec4(c)); - storageBarrier(); - } - } + let pointIndex = i32(GlobalId.y + (GlobalId.x * dims.x)); + let c = rands[pointIndex]; + textureStore(outputTex, GlobalId.xy, vec4(c)); + storageBarrier(); } `; diff --git a/examples/random2/index.js b/examples/random2/index.js index 360aa97c..e9ffd1e5 100644 --- a/examples/random2/index.js +++ b/examples/random2/index.js @@ -1,10 +1,11 @@ import vert from './vert.js'; import compute from './compute.js'; import frag from './frag.js'; +import { RenderPass } from '../../src/absulit.points.module.js'; const random2 = { - vert, - compute, - frag, + renderPasses: [ + new RenderPass(vert, frag, compute, 800, 800) + ], init: async points => { points.addUniform('randNumber', 0); points.addUniform('randNumber2', 0); From 443d71c8e124e75fda4e576a8c4a4c5cadcebe04 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 3 Jun 2023 08:18:27 -0600 Subject: [PATCH 03/16] separated original and new dithering demo - just keeping the original as reference compared with the second one, if I fix the dithering order then I will remove the original --- .../{dithering3 => dithering3_1}/compute.js | 2 +- examples/{dithering3 => dithering3_1}/frag.js | 0 .../{dithering3 => dithering3_1}/index.js | 0 examples/{dithering3 => dithering3_1}/vert.js | 0 examples/dithering3_2/compute.js | 182 ++++++++++++++++++ examples/dithering3_2/frag.js | 63 ++++++ examples/dithering3_2/index.js | 26 +++ examples/dithering3_2/vert.js | 19 ++ examples/main.js | 3 +- 9 files changed, 293 insertions(+), 2 deletions(-) rename examples/{dithering3 => dithering3_1}/compute.js (95%) rename examples/{dithering3 => dithering3_1}/frag.js (100%) rename examples/{dithering3 => dithering3_1}/index.js (100%) rename examples/{dithering3 => dithering3_1}/vert.js (100%) create mode 100644 examples/dithering3_2/compute.js create mode 100644 examples/dithering3_2/frag.js create mode 100644 examples/dithering3_2/index.js create mode 100644 examples/dithering3_2/vert.js diff --git a/examples/dithering3/compute.js b/examples/dithering3_1/compute.js similarity index 95% rename from examples/dithering3/compute.js rename to examples/dithering3_1/compute.js index a9e6ba61..33172a8a 100644 --- a/examples/dithering3/compute.js +++ b/examples/dithering3_1/compute.js @@ -1,4 +1,4 @@ -import { brightness } from './../../src/core/color.js'; +import { brightness } from '../../src/core/color.js'; const compute = /*wgsl*/` diff --git a/examples/dithering3/frag.js b/examples/dithering3_1/frag.js similarity index 100% rename from examples/dithering3/frag.js rename to examples/dithering3_1/frag.js diff --git a/examples/dithering3/index.js b/examples/dithering3_1/index.js similarity index 100% rename from examples/dithering3/index.js rename to examples/dithering3_1/index.js diff --git a/examples/dithering3/vert.js b/examples/dithering3_1/vert.js similarity index 100% rename from examples/dithering3/vert.js rename to examples/dithering3_1/vert.js diff --git a/examples/dithering3_2/compute.js b/examples/dithering3_2/compute.js new file mode 100644 index 00000000..ed3f0087 --- /dev/null +++ b/examples/dithering3_2/compute.js @@ -0,0 +1,182 @@ +import { brightness } from '../../src/core/color.js'; + +const compute = /*wgsl*/` + +struct Variable{ + init: i32 +} + +${brightness} + +const workgroupSize = 1; + +@compute @workgroup_size(workgroupSize,workgroupSize,1) +fn main( + @builtin(global_invocation_id) GlobalId: vec3, + @builtin(workgroup_id) WorkGroupID: vec3, + @builtin(local_invocation_id) LocalInvocationID: vec3 +) { + //-------------------------------------------------- + let dims = textureDimensions(image); + + let numColumns:f32 = f32(dims.x); + let numRows:f32 = f32(dims.y); + //let constant = u32(numColumns) / 93u; + + // let numColumnsPiece:i32 = i32(numColumns / f32(workgroupSize)); + // let numRowsPiece:i32 = i32(numRows / f32(workgroupSize)); + + var layerIndex = 0; + if(variables.init == 0){ + + // for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { + // let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); + // let ux = u32(x); + // let ix = i32(x); + // let nx = x / numColumns; + // for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { + + // let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); + // let uy = u32(y); + // let iy = i32(y); + // let ny = y / numRows; + // let uv = vec2(nx,ny); + + // let pointIndex = i32(y + (x * numColumns)); + + // var point = textureLoad(image, vec2(ix,iy), 0); // image + // //var point = textureLoad(image, vec2(ix,iy)); // video + // layers[0][pointIndex] = point; + // layers[1][pointIndex] = point; + // } + // } + + let pointIndex = i32(GlobalId.y + (GlobalId.x * dims.x)); + + var point = textureLoad(image, GlobalId.yx, 0); // image + // var point = textureLoad(image, GlobalId.yx); // video + layers[0][pointIndex] = point; + layers[1][pointIndex] = point; + + + + + + // variables.init = 1; + }else{ + layerIndex = 1; + } + + //GlobalId.xy + + //-------------------------------------------------- + + // for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { + // let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); + // let ux = u32(x); + // let ix = i32(x); + // let nx = x / numColumns; + // for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { + + // let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); + // let uy = u32(y); + // let iy = i32(y); + // let ny = y / numRows; + // let uv = vec2(nx,ny); + + // let pointIndex = i32(y + (x * numColumns)); + + // var point = layers[layerIndex][pointIndex]; + // let b = brightness(point); + // var newBrightness = 0.; + // if(b > .5){ + // newBrightness = 1.; + // } + + // let quant_error = b - newBrightness; + // let distance = 1; + // let distanceU = u32(distance); + // let distanceF = f32(distance); + // point = vec4(newBrightness); + + // let pointP = &layers[layerIndex][pointIndex]; + // (*pointP) = point; + + + // let pointIndexC = i32(y + ((x+distanceF) * numColumns)); + // var rightPoint = layers[layerIndex][pointIndexC]; + // rightPoint = vec4(brightness(rightPoint) + (.5 * quant_error)); + + // let pointPC = &layers[layerIndex][pointIndexC]; + // (*pointPC) = rightPoint; + + + // let pointIndexR = i32((y+distanceF) + (x * numColumns)); + // var bottomPoint = layers[layerIndex][pointIndexR]; + // bottomPoint = vec4(brightness(bottomPoint) + (.5 * quant_error)); + + // let pointPR = &layers[layerIndex][pointIndexR]; + // (*pointPR) = bottomPoint; + + // point = layers[layerIndex][pointIndex]; + // let positionU = vec2(ux,uy); + // textureStore(outputTex, positionU, point); + // storageBarrier(); + // } + // } + + let pointIndex = i32(GlobalId.x + (GlobalId.y * dims.y)); + + var point = layers[layerIndex][pointIndex]; + let b = brightness(point); + var newBrightness = 0.; + if(b > .5){ + newBrightness = 1.; + } + + let quant_error = b - newBrightness; + let distance = 1; + let distanceU = u32(distance); + let distanceF = f32(distance); + point = vec4(newBrightness); + + let pointP = &layers[layerIndex][pointIndex]; + (*pointP) = point; + + + let pointIndexC = i32(GlobalId.x + ((GlobalId.y+distanceU) * dims.y)); + var rightPoint = layers[layerIndex][pointIndexC]; + rightPoint = vec4(brightness(rightPoint) + (.5 * quant_error * params.sliderB)); + + let pointPC = &layers[layerIndex][pointIndexC]; + (*pointPC) = rightPoint; + + + let pointIndexR = i32((GlobalId.y+distanceU) + (GlobalId.x * dims.x)); + var bottomPoint = layers[layerIndex][pointIndexR]; + bottomPoint = vec4(brightness(bottomPoint) + (.5 * quant_error)); + + let pointPR = &layers[layerIndex][pointIndexR]; + (*pointPR) = bottomPoint; + + point = layers[layerIndex][pointIndex]; + let positionU = GlobalId.xy; + textureStore(outputTex, positionU, point); + storageBarrier(); + // workgroupBarrier(); + + + + + + + + + + + + +} +`; + +export default compute; diff --git a/examples/dithering3_2/frag.js b/examples/dithering3_2/frag.js new file mode 100644 index 00000000..d6c48df1 --- /dev/null +++ b/examples/dithering3_2/frag.js @@ -0,0 +1,63 @@ +import { snoise } from '../../src/core/noise2d.js'; +import { getClosestColorInPalette, orderedDithering, orderedDithering_threshold_map } from '../../src/core/effects.js'; +import { texturePosition } from '../../src/core/image.js'; +import { fnusin } from '../../src/core/animation.js'; + +const frag = /*wgsl*/` +struct Variable{ + init: i32 +} + +${fnusin} +${snoise} +${getClosestColorInPalette} +${orderedDithering} +${texturePosition} + +${orderedDithering_threshold_map} + +const numPaletteItems = 21; +const getClosestColorInPalette_palette = array< vec4, numPaletteItems>( + vec4(255./255, 69./255, 0, 1.), + vec4(255./255, 168./255, 0, 1.), + vec4(255./255, 214./255, 53./255, 1.), + vec4(0, 204./255, 120./255, 1.), + vec4(126./255, 237./255, 86./255, 1.), + vec4(0./255, 117./255, 111./255, 1.), + vec4(0./255, 158./255, 170./255, 1.), + vec4(36./255, 80./255, 164./255, 1.), + vec4(54./255, 144./255, 234./255, 1.), + vec4(81./255, 233./255, 244./255, 1.), + vec4(73./255, 58./255, 193./255, 1.), + vec4(106./255, 92./255, 255./255, 1.), + vec4(129./255, 30./255, 159./255, 1.), + vec4(180./255, 74./255, 192./255, 1.), + vec4(255./255, 56./255, 129./255, 1.), + vec4(255./255, 153./255, 170./255, 1.), + vec4(109./255, 72./255, 48./255, 1.), + vec4(156./255, 105./255, 38./255, 1.), + vec4(0, 0, 0, 1.), + vec4(137./255, 141./255, 144./255, 1.), + vec4(212./255, 215./255, 217./255, 1.), +); + + +@fragment +fn main( + @location(0) color: vec4, + @location(1) uv: vec2, + @location(2) ratio: vec2, + @location(3) uvRatio: vec2, + @location(4) mouse: vec2, + @builtin(position) position: vec4 + ) -> @location(0) vec4 { + + //let imageUV = (uv / f + vec2(0, .549 ) ) * vec2(1,-1 * dimsRatio) * ratio.y / params.sliderA; + //var point = textureSample(computeTexture, imageSampler, imageUV); //* .998046; + var point = texturePosition(computeTexture, imageSampler, vec2(0.), uv / params.sliderA, false); //* .998046; + + return point; +} +`; + +export default frag; diff --git a/examples/dithering3_2/index.js b/examples/dithering3_2/index.js new file mode 100644 index 00000000..a756392e --- /dev/null +++ b/examples/dithering3_2/index.js @@ -0,0 +1,26 @@ +import vert from './vert.js'; +import compute from './compute.js'; +import frag from './frag.js'; +import { RenderPass, ShaderType } from '../../src/absulit.points.module.js'; +const dithering3 = { + renderPasses: [ + new RenderPass(vert, frag, compute, 800, 800) + ], + init: async points => { + points.addSampler('imageSampler', null); + // await points.addTextureImage('image', './../img/carmen_lyra_423x643.jpg'); + // await points.addTextureImage('image', './../img/old_king_800x00.jpg'); + // await points.addTextureWebcam('image'); + // await points.addTextureImage('image', './../img/angel_600x600.jpg'); + // await points.addTextureImage('image', './../img/gratia_800x800.jpg'); + await points.addTextureImage('image', './../img/absulit_800x800.jpg'); + points.addBindingTexture('outputTex', 'computeTexture'); + points.addLayers(2); + points.addStorage('variables', 1, 'Variable', 2, false, ShaderType.COMPUTE); + }, + update: points => { + + } +} + +export default dithering3; \ No newline at end of file diff --git a/examples/dithering3_2/vert.js b/examples/dithering3_2/vert.js new file mode 100644 index 00000000..d1fe1d1f --- /dev/null +++ b/examples/dithering3_2/vert.js @@ -0,0 +1,19 @@ +const vert = /*wgsl*/` + +struct Variable{ + init: i32 +} + +@vertex +fn main( + @location(0) position: vec4, + @location(1) color: vec4, + @location(2) uv: vec2, + @builtin(vertex_index) vertexIndex: u32 +) -> Fragment { + + return defaultVertexBody(position, color, uv); +} +`; + +export default vert; diff --git a/examples/main.js b/examples/main.js index 532ba0dc..6f098d49 100644 --- a/examples/main.js +++ b/examples/main.js @@ -62,7 +62,8 @@ const shaderProjects = [ { name: 'Demo 6', path: './demo_6/index.js' }, { name: 'Dithering 1', path: './dithering1/index.js' }, { name: 'Dithering 2', path: './dithering2/index.js' }, - { name: 'Dithering 3', path: './dithering3/index.js' }, + { name: 'Dithering 3 - 1', path: './dithering3_1/index.js' }, + { name: 'Dithering 3 - 2', path: './dithering3_2/index.js' }, { name: 'Dithering 4', path: './dithering4/index.js' }, { name: 'Image Scale 1', path: './imagescale1/index.js' }, { name: 'Image Texture 1', path: './imagetexture1/index.js' }, From eb94059f66dddc23a397f97e26ce5b0efafcda32 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 3 Jun 2023 08:23:43 -0600 Subject: [PATCH 04/16] removed unused code --- examples/dithering3_2/compute.js | 101 ------------------------------- 1 file changed, 101 deletions(-) diff --git a/examples/dithering3_2/compute.js b/examples/dithering3_2/compute.js index ed3f0087..6d3e0bca 100644 --- a/examples/dithering3_2/compute.js +++ b/examples/dithering3_2/compute.js @@ -19,38 +19,9 @@ fn main( //-------------------------------------------------- let dims = textureDimensions(image); - let numColumns:f32 = f32(dims.x); - let numRows:f32 = f32(dims.y); - //let constant = u32(numColumns) / 93u; - - // let numColumnsPiece:i32 = i32(numColumns / f32(workgroupSize)); - // let numRowsPiece:i32 = i32(numRows / f32(workgroupSize)); - var layerIndex = 0; if(variables.init == 0){ - // for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { - // let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); - // let ux = u32(x); - // let ix = i32(x); - // let nx = x / numColumns; - // for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { - - // let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); - // let uy = u32(y); - // let iy = i32(y); - // let ny = y / numRows; - // let uv = vec2(nx,ny); - - // let pointIndex = i32(y + (x * numColumns)); - - // var point = textureLoad(image, vec2(ix,iy), 0); // image - // //var point = textureLoad(image, vec2(ix,iy)); // video - // layers[0][pointIndex] = point; - // layers[1][pointIndex] = point; - // } - // } - let pointIndex = i32(GlobalId.y + (GlobalId.x * dims.x)); var point = textureLoad(image, GlobalId.yx, 0); // image @@ -58,73 +29,13 @@ fn main( layers[0][pointIndex] = point; layers[1][pointIndex] = point; - - - - // variables.init = 1; }else{ layerIndex = 1; } - //GlobalId.xy - //-------------------------------------------------- - // for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { - // let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); - // let ux = u32(x); - // let ix = i32(x); - // let nx = x / numColumns; - // for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { - - // let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); - // let uy = u32(y); - // let iy = i32(y); - // let ny = y / numRows; - // let uv = vec2(nx,ny); - - // let pointIndex = i32(y + (x * numColumns)); - - // var point = layers[layerIndex][pointIndex]; - // let b = brightness(point); - // var newBrightness = 0.; - // if(b > .5){ - // newBrightness = 1.; - // } - - // let quant_error = b - newBrightness; - // let distance = 1; - // let distanceU = u32(distance); - // let distanceF = f32(distance); - // point = vec4(newBrightness); - - // let pointP = &layers[layerIndex][pointIndex]; - // (*pointP) = point; - - - // let pointIndexC = i32(y + ((x+distanceF) * numColumns)); - // var rightPoint = layers[layerIndex][pointIndexC]; - // rightPoint = vec4(brightness(rightPoint) + (.5 * quant_error)); - - // let pointPC = &layers[layerIndex][pointIndexC]; - // (*pointPC) = rightPoint; - - - // let pointIndexR = i32((y+distanceF) + (x * numColumns)); - // var bottomPoint = layers[layerIndex][pointIndexR]; - // bottomPoint = vec4(brightness(bottomPoint) + (.5 * quant_error)); - - // let pointPR = &layers[layerIndex][pointIndexR]; - // (*pointPR) = bottomPoint; - - // point = layers[layerIndex][pointIndex]; - // let positionU = vec2(ux,uy); - // textureStore(outputTex, positionU, point); - // storageBarrier(); - // } - // } - let pointIndex = i32(GlobalId.x + (GlobalId.y * dims.y)); var point = layers[layerIndex][pointIndex]; @@ -164,18 +75,6 @@ fn main( textureStore(outputTex, positionU, point); storageBarrier(); // workgroupBarrier(); - - - - - - - - - - - - } `; From c6c724ff8801fa17f75f3c871e8ad87a228d5379 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 3 Jun 2023 15:13:21 -0600 Subject: [PATCH 05/16] shapes 1 with better workgroups --- examples/shapes1/compute.js | 14 ++++++-------- examples/shapes1/index.js | 7 ++++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/examples/shapes1/compute.js b/examples/shapes1/compute.js index f468fbe7..81e78fa0 100644 --- a/examples/shapes1/compute.js +++ b/examples/shapes1/compute.js @@ -1,8 +1,8 @@ const compute = /*wgsl*/` -const workgroupSize = 8; +const workgroupSize = 1; -@compute @workgroup_size(8,8,1) +@compute @workgroup_size(workgroupSize,workgroupSize,1) fn main( @builtin(global_invocation_id) GlobalId: vec3, @builtin(workgroup_id) WorkGroupID: vec3, @@ -12,12 +12,10 @@ fn main( let numPoints = u32(params.numPoints); // list of points for the sine wave - for(var k:u32; k < numPoints; k++){ - let fk = f32(k); - let point = &points[k]; - (*point).x = fk / params.numPoints; - (*point).y = sin( ((*point).x * 32) + time) * .1; - } + let fk = f32(GlobalId.x); + let point = &points[GlobalId.x]; + (*point).x = fk / params.numPoints; + (*point).y = sin( ((*point).x * 32) + time) * .1; } `; diff --git a/examples/shapes1/index.js b/examples/shapes1/index.js index a7fdc855..b25f8730 100644 --- a/examples/shapes1/index.js +++ b/examples/shapes1/index.js @@ -1,10 +1,11 @@ import vert from './vert.js'; import compute from './compute.js'; import frag from './frag.js'; +import { RenderPass } from '../../src/absulit.points.module.js'; const shapes1 = { - vert, - compute, - frag, + renderPasses: [ + new RenderPass(vert, frag, compute, 128, 1, 1) + ], init: async points => { const numPoints = 128; points.addUniform('numPoints', numPoints); From 78ccbd0baf6b330e2e1d316b94c3513557a66e32 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 3 Jun 2023 16:29:47 -0600 Subject: [PATCH 06/16] converted shapes 2 to better workgroups - and the demo changed completely to a more interesting one --- examples/shapes2/compute.js | 60 ++++++++++++++++--------------------- examples/shapes2/index.js | 7 +++-- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/examples/shapes2/compute.js b/examples/shapes2/compute.js index 58bd5db2..1b6a9741 100644 --- a/examples/shapes2/compute.js +++ b/examples/shapes2/compute.js @@ -1,3 +1,4 @@ +import { fnusin } from '../../src/core/animation.js'; import { clearAlpha, soften4, soften8 } from '../../src/core/effects.js'; import { sdfCircle, sdfLine2, sdfSegment } from '../../src/core/sdf.js'; @@ -9,6 +10,7 @@ ${clearAlpha} ${sdfSegment} ${sdfLine2} ${sdfCircle} +${fnusin} struct Colors{ items: array< vec4, 800*800 > @@ -49,9 +51,9 @@ fn getColorsAround4Layer(position: vec2, distance: u32) -> array< vec4, @builtin(workgroup_id) WorkGroupID: vec3, @@ -82,50 +84,38 @@ fn main( var rgba = vec4(0.); var colorsAround = array< vec4, 4 >(); - for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { - let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); - let ux = u32(x); - let ix = i32(x); - let nx = x / numColumns; - for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { - let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); - let uy = u32(y); - let iy = i32(y); - let ny = y / numRows; - let uv = vec2(nx,ny); + let nx = f32(GlobalId.x) / numColumns; + let ny = f32(GlobalId.y) / numRows; + let uv = vec2(nx,ny); + let positionU = GlobalId.xy; - let positionU = vec2(ux,uy); + let uIndex = getPointsIndex(positionU); + // let rgba = &points[uIndex]; + // let a = sin(uv.x * params.time); + // (*rgba) = vec4(a * uv.x, 1-uv.y, a, 1); - let uIndex = getPointsIndex(positionU); - // let rgba = &points[uIndex]; - // let a = sin(uv.x * params.time); - // (*rgba) = vec4(a * uv.x, 1-uv.y, a, 1); + rgba = points[uIndex]; + colorsAround = getColorsAround4Layer(positionU, 1); + let rgbaP = &points[uIndex]; - rgba = points[uIndex]; - colorsAround = getColorsAround4Layer(positionU, 1); - let rgbaP = &points[uIndex]; + (*rgbaP) = soften4(rgba, colorsAround, 1.); + rgba = points[uIndex]; + (*rgbaP) = clearAlpha(rgba, 1000.01); + if(rgba.a > 0){ + rgba -= .4; - (*rgbaP) = soften4(rgba, colorsAround, 1.); - rgba = points[uIndex]; - (*rgbaP) = clearAlpha(rgba, 1.01); - - let sdf = sdfCircle(vec2(.3,.3), .1, 0., uv); - (*rgbaP) += sdf; - - - rgba = points[uIndex]; - - - textureStore(outputTex, positionU, rgba); - } } + (*rgbaP) = rgba; + let sdf = sdfCircle(vec2(1.,1.) * fnusin(1), .01, .2, uv); + (*rgbaP) += sdf; + rgba = points[uIndex]; - + textureStore(outputTex, positionU, rgba); } `; diff --git a/examples/shapes2/index.js b/examples/shapes2/index.js index 89d3c1f9..ea29331b 100644 --- a/examples/shapes2/index.js +++ b/examples/shapes2/index.js @@ -1,10 +1,11 @@ import vert from './vert.js'; import compute from './compute.js'; import frag from './frag.js'; +import { RenderPass } from '../../src/absulit.points.module.js'; const shapes2 = { - vert, - compute, - frag, + renderPasses: [ + new RenderPass(vert, frag, compute, 800, 800, 1) + ], init: async points => { const numPoints = 800*800; points.addUniform('numPoints', numPoints); From 24bfaeb705af4680e2693c30b8cce4173e2ba670 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 3 Jun 2023 18:28:01 -0600 Subject: [PATCH 07/16] updating docs - Regarding the new render pass workgroup parameters --- README.md | 6 ++++++ examples/shapes2/compute.js | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c9858f9e..3a57f8e5 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,12 @@ await points.init(renderPasses); You can pass a Compute Shader only, or a Vertex and Fragment together only. This way you can have a Compute Shader without visual output, create calculations and return their response values, or a regular Render Pipeline without Compute Shader calculations. +There's also three extra parameters in the RenderPass, these are to dispatch the workgroups for each dimension (x, y, z): + +```js +new RenderPass(vert1, frag1, compute1, 800, 800, 1); +``` + # Create your custom Shader project 1. Copy the `/examples/base/` and place it where you want to store your project. 2. Rename folder. diff --git a/examples/shapes2/compute.js b/examples/shapes2/compute.js index 1b6a9741..21c4f8c6 100644 --- a/examples/shapes2/compute.js +++ b/examples/shapes2/compute.js @@ -59,12 +59,8 @@ fn main( @builtin(workgroup_id) WorkGroupID: vec3, @builtin(local_invocation_id) LocalInvocationID: vec3 ) { - let time = params.time; - let numColumns:f32 = params.screenWidth; let numRows:f32 = params.screenHeight; - let numColumnsPiece:i32 = i32(numColumns / f32(workgroupSize)); - let numRowsPiece:i32 = i32(numRows / f32(workgroupSize)); var x = 450.; var y = 450.; @@ -104,7 +100,6 @@ fn main( (*rgbaP) = clearAlpha(rgba, 1000.01); if(rgba.a > 0){ rgba -= .4; - } (*rgbaP) = rgba; From 2c4efff6841a3367310154b279c7e41b1c7696f0 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Thu, 8 Jun 2023 18:40:34 -0600 Subject: [PATCH 08/16] Update absulit.points.module.js - bindingIndex has to increase because if not `addBindingTexture` can only add one, so this allows for multiple calls to `addBindingTexture` --- src/absulit.points.module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/absulit.points.module.js b/src/absulit.points.module.js index f2588d7a..35df7786 100644 --- a/src/absulit.points.module.js +++ b/src/absulit.points.module.js @@ -1334,7 +1334,7 @@ export default class Points { entries.push( { label: 'binding texture 2', - binding: bindingIndex, // this does not increase, must match the previous block + binding: bindingIndex++, resource: bindingTexture.texture.createView(), type: { name: 'texture', From 4cd0182f219d09a91da8f0486c877d3d58b0360d Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Thu, 8 Jun 2023 19:22:49 -0600 Subject: [PATCH 09/16] Update main.js - button to download image as png --- examples/main.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/main.js b/examples/main.js index 6f098d49..05404347 100644 --- a/examples/main.js +++ b/examples/main.js @@ -41,7 +41,7 @@ gui.add(stats2, 'visible').name('Show Stats').onChange(value => setStatsVisibili let isFullscreenData = { 'isFullscreen': false }; let fullscreenCheck = gui.add(isFullscreenData, 'isFullscreen').name('Fullscreen').onChange(value => points.fullscreen = value); -document.addEventListener("fullscreenchange", e => { +document.addEventListener('fullscreenchange', e => { let isFullscreen = window.innerWidth == screen.width && window.innerHeight == screen.height; isFullscreenData.isFullscreen = isFullscreen; fullscreenCheck.updateDisplay(); @@ -148,6 +148,13 @@ const recordingOptions = [ started: false, controller: null }, + { + nameStopped: 'Download PNG Image', + fn: function (e) { + let image = document.getElementById('gl-canvas').toDataURL().replace('image/png', 'image/octet-stream'); + window.location.href = image; + }, + }, ]; recordingOptions.forEach(recordingOption => { From d07bf5a7f1cda1b88de7b2bec36a8053cf4ee471 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 10 Jun 2023 18:30:24 -0600 Subject: [PATCH 10/16] fix to fullscreen not working with js console open - If the console is open it detect different dimensions, but if we first assign the fit window method it works - We remember fitWindow value and re assign it after we exit fullscreen --- src/absulit.points.module.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/absulit.points.module.js b/src/absulit.points.module.js index 35df7786..1db32a55 100644 --- a/src/absulit.points.module.js +++ b/src/absulit.points.module.js @@ -259,16 +259,20 @@ export default class Points { window.addEventListener('resize', this._resizeCanvasToFitWindow, false); document.addEventListener("fullscreenchange", e => { - let isFullscreen = window.innerWidth == screen.width && window.innerHeight == screen.height; + let isFullscreen = !!document.fullscreenElement; this._fullscreen = isFullscreen; if (!isFullscreen && !this._fitWindow) { this._resizeCanvasToDefault(); } + if (!isFullscreen) { + this.fitWindow = this._lastFitWindow; + } }); } this._fullscreen = false; this._fitWindow = false; + this._lastFitWindow = false; // _readStorage should only be read once @@ -1603,6 +1607,8 @@ export default class Points { set fullscreen(value) { if (value) { + this._lastFitWindow = this._fitWindow; + this.fitWindow = value; this._canvas.requestFullscreen().catch(err => { throw `Error attempting to enable fullscreen mode: ${err.message} (${err.name})`; }); From 9fe269670f330d4c1640957a3db0f884b7b95881 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 10 Jun 2023 19:01:25 -0600 Subject: [PATCH 11/16] Simplified circleblur compute - with better workgroups --- examples/circleblur/compute.js | 47 ++++++++++++---------------------- examples/circleblur/index.js | 8 +++--- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/examples/circleblur/compute.js b/examples/circleblur/compute.js index dbfcdd45..e69a0711 100644 --- a/examples/circleblur/compute.js +++ b/examples/circleblur/compute.js @@ -4,7 +4,7 @@ const compute = /*wgsl*/` ${clearMix} -const workgroupSize = 8; +const workgroupSize = 1; //'function', 'private', 'push_constant', 'storage', 'uniform', 'workgroup' @@ -15,42 +15,27 @@ fn main( @builtin(local_invocation_id) LocalInvocationID: vec3 ) { - let filterDim = 128u; - let blockDim = 128u; - let flipValue = 0u; + // let filterDim = 128u; + // let blockDim = 128u; + // let flipValue = 0u; - let filterOffset : u32 = (filterDim - 1u) / 2u; - let dims : vec2 = textureDimensions(feedbackTexture, 0); + // let filterOffset : u32 = (filterDim - 1u) / 2u; - let baseIndex = vec2( - WorkGroupID.xy * vec2(blockDim, 4u) + - LocalInvocationID.xy * vec2(4u, 1u) - ) - vec2(i32(filterOffset), 0); + // let baseIndex = vec2( + // WorkGroupID.xy * vec2(blockDim, 4u) + + // LocalInvocationID.xy * vec2(4u, 1u) + // ) - vec2(i32(filterOffset), 0); // ---------------------------------------------- - let numColumns:f32 = f32(dims.x); - let numRows:f32 = f32(dims.y); - let numColumnsPiece:i32 = i32(numColumns / f32(workgroupSize)); - let numRowsPiece:i32 = i32(numRows / f32(workgroupSize)); - for (var indexColumns:i32 = 0; indexColumns < numColumnsPiece; indexColumns++) { - let x:f32 = f32(WorkGroupID.x) * f32(numColumnsPiece) + f32(indexColumns); - let ux = u32(x); - let nx = x / numColumns; - for (var indexRows:i32 = 0; indexRows < numRowsPiece; indexRows++) { - - let y:f32 = f32(WorkGroupID.y) * f32(numRowsPiece) + f32(indexRows); - let uy = u32(y); - let ny = y / numRows; - - var rgba = textureSampleLevel(feedbackTexture,feedbackSampler, vec2(x,y), 0.0); - - rgba = clearMix(rgba, 1.01) + vec4(1.,0.,0., .5); - - textureStore(outputTex, vec2(ux,uy), rgba); - } - } + var rgba = textureSampleLevel( + feedbackTexture,feedbackSampler, + vec2(f32(GlobalId.x), f32(GlobalId.y)), + 0.0 + ); + rgba = clearMix(rgba, 1.01) + vec4(1.,0.,0., .5); + textureStore(outputTex, GlobalId.xy, rgba); } `; diff --git a/examples/circleblur/index.js b/examples/circleblur/index.js index a6e8d4d4..d5088067 100644 --- a/examples/circleblur/index.js +++ b/examples/circleblur/index.js @@ -1,10 +1,12 @@ import vert from './vert.js'; import compute from './compute.js'; import frag from './frag.js'; +import { RenderPass } from '../../src/absulit.points.module.js'; const circleblur = { - vert, - compute, - frag, + renderPasses: [ + new RenderPass(null, null, compute, 800, 800, 1), + new RenderPass(vert, frag, null, 8, 1, 1) + ], init: async points => { points.addSampler('feedbackSampler'); points.addTexture2d('feedbackTexture', true); From c86047f020410fc23406acfac412a9581802e9e9 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Tue, 27 Jun 2023 18:55:47 -0600 Subject: [PATCH 12/16] Removed assumed 4 byte alignment - Depending on the data type, not all fields in a struct are 4 bytes, a vec2 has 16 bytes because all vectors occupy 16 no matter what, so because of this, now the user has to be conscious about explicitly say the size of the struct. --- src/absulit.points.module.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/absulit.points.module.js b/src/absulit.points.module.js index 1db32a55..a75c6bba 100644 --- a/src/absulit.points.module.js +++ b/src/absulit.points.module.js @@ -949,7 +949,7 @@ export default class Points { if (storageItem.read) { usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC; } - storageItem.buffer = this._createBuffer(storageItem.size * storageItem.structSize * 4, usage); + storageItem.buffer = this._createBuffer(storageItem.size * storageItem.structSize, usage); } }); //-------------------------------------------- @@ -964,7 +964,7 @@ export default class Points { //let layerValues = []; let layersSize = 0; this._layers.forEach(layerItem => { - layersSize += layerItem.size * layerItem.structSize * 4; + layersSize += layerItem.size * layerItem.structSize; }); this._layers.buffer = this._createBuffer(layersSize, GPUBufferUsage.STORAGE); } From ee73201f2cdcd53c3cb2b86ed0fafa89c26e1da8 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Tue, 27 Jun 2023 19:09:17 -0600 Subject: [PATCH 13/16] restored layer byte size - This is static, unless I later decide to make it with a dynamic struct, it must remain the same --- src/absulit.points.module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/absulit.points.module.js b/src/absulit.points.module.js index a75c6bba..d7eb0c62 100644 --- a/src/absulit.points.module.js +++ b/src/absulit.points.module.js @@ -964,7 +964,7 @@ export default class Points { //let layerValues = []; let layersSize = 0; this._layers.forEach(layerItem => { - layersSize += layerItem.size * layerItem.structSize; + layersSize += layerItem.size * layerItem.structSize * 4; }); this._layers.buffer = this._createBuffer(layersSize, GPUBufferUsage.STORAGE); } From e1d56d94566311c8f4c6814e8d157eaa330b4be1 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Wed, 28 Jun 2023 19:19:45 -0600 Subject: [PATCH 14/16] added correct bytes --- examples/dithering3_1/index.js | 2 +- examples/dithering3_2/index.js | 2 +- examples/mouseclickscroll1/index.js | 2 +- examples/noise1/index.js | 4 ++-- examples/shapes1/index.js | 2 +- examples/shapes2/index.js | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/dithering3_1/index.js b/examples/dithering3_1/index.js index de5677be..845f76b8 100644 --- a/examples/dithering3_1/index.js +++ b/examples/dithering3_1/index.js @@ -16,7 +16,7 @@ const dithering3 = { await points.addTextureImage('image', './../img/absulit_800x800.jpg'); points.addBindingTexture('outputTex', 'computeTexture'); points.addLayers(2); - points.addStorage('variables', 1, 'Variable', 2, false, ShaderType.COMPUTE); + points.addStorage('variables', 1, 'Variable', 4, false, ShaderType.COMPUTE); }, update: points => { diff --git a/examples/dithering3_2/index.js b/examples/dithering3_2/index.js index a756392e..01fce08a 100644 --- a/examples/dithering3_2/index.js +++ b/examples/dithering3_2/index.js @@ -16,7 +16,7 @@ const dithering3 = { await points.addTextureImage('image', './../img/absulit_800x800.jpg'); points.addBindingTexture('outputTex', 'computeTexture'); points.addLayers(2); - points.addStorage('variables', 1, 'Variable', 2, false, ShaderType.COMPUTE); + points.addStorage('variables', 1, 'Variable', 4, false, ShaderType.COMPUTE); }, update: points => { diff --git a/examples/mouseclickscroll1/index.js b/examples/mouseclickscroll1/index.js index 0b5fa06e..e93107f8 100644 --- a/examples/mouseclickscroll1/index.js +++ b/examples/mouseclickscroll1/index.js @@ -5,7 +5,7 @@ const mouseclickscroll1 = { vert, frag, init: async points => { - points.addStorage('variables', 1, 'Variable', 4); + points.addStorage('variables', 1, 'Variable', 24); }, update: points => { diff --git a/examples/noise1/index.js b/examples/noise1/index.js index 9655fcba..a6adcfda 100644 --- a/examples/noise1/index.js +++ b/examples/noise1/index.js @@ -6,8 +6,8 @@ const noise1 = { init: async points => { const numPoints = 800*800; points.addUniform('value_noise_data_length', numPoints); - points.addStorage('value_noise_data', numPoints, 'f32', 1); - points.addStorage('variables', 1, 'Variable', 1); + points.addStorage('value_noise_data', numPoints, 'f32', 4); + points.addStorage('variables', 1, 'Variable', 4); }, update: points => { diff --git a/examples/shapes1/index.js b/examples/shapes1/index.js index b25f8730..a3954770 100644 --- a/examples/shapes1/index.js +++ b/examples/shapes1/index.js @@ -9,7 +9,7 @@ const shapes1 = { init: async points => { const numPoints = 128; points.addUniform('numPoints', numPoints); - points.addStorage('points', numPoints, 'vec2', 2); + points.addStorage('points', numPoints, 'vec2', 8); }, update: points => { diff --git a/examples/shapes2/index.js b/examples/shapes2/index.js index ea29331b..c4bfd027 100644 --- a/examples/shapes2/index.js +++ b/examples/shapes2/index.js @@ -9,7 +9,7 @@ const shapes2 = { init: async points => { const numPoints = 800*800; points.addUniform('numPoints', numPoints); - points.addStorage('points', numPoints, 'vec4', 4); + points.addStorage('points', numPoints, 'vec4', 16); points.addSampler('feedbackSampler', null); points.addBindingTexture('outputTex', 'computeTexture'); }, From e646a2a4d8d4433a7a47a46c238d0a15db3184d4 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 1 Jul 2023 16:37:14 -0600 Subject: [PATCH 15/16] restored way we calculate storage size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - it was never wrong 😄 - the thing is the error is the parameters sent into addStorage, so I have to be careful there --- src/absulit.points.module.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/absulit.points.module.js b/src/absulit.points.module.js index d7eb0c62..744f04d3 100644 --- a/src/absulit.points.module.js +++ b/src/absulit.points.module.js @@ -274,7 +274,6 @@ export default class Points { this._fitWindow = false; this._lastFitWindow = false; - // _readStorage should only be read once this._readStorageCopied = false; } @@ -747,15 +746,11 @@ export default class Points { let dynamicStructParams = ''; this._uniforms.forEach(variable => { - dynamicStructParams += /*wgsl*/`${variable.name}:f32, \n\t\t\t\t\t`; + dynamicStructParams += /*wgsl*/`${variable.name}:f32, \n\t`; }); if (this._uniforms.length) { - dynamicStructParams = /*wgsl*/` - struct Params { - ${dynamicStructParams} - } - \n`; + dynamicStructParams = /*wgsl*/`struct Params {\n\t${dynamicStructParams}\n}\n`; } renderPass.hasVertexShader && (dynamicGroupBindingsVertex += dynamicStructParams); @@ -949,7 +944,7 @@ export default class Points { if (storageItem.read) { usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC; } - storageItem.buffer = this._createBuffer(storageItem.size * storageItem.structSize, usage); + storageItem.buffer = this._createBuffer(storageItem.size * storageItem.structSize * 4, usage); } }); //-------------------------------------------- @@ -1200,7 +1195,7 @@ export default class Points { } if (this._storage.length) { - this._storage.forEach((storageItem, index) => { + this._storage.forEach(storageItem => { let internalCheck = internal == storageItem.internal; if (!storageItem.shaderType && internalCheck || storageItem.shaderType == shaderType && internalCheck) { entries.push( From 6a082108243149697134c8fcbea2e350e72364f2 Mon Sep 17 00:00:00 2001 From: Sebastian Sanabria Date: Sat, 1 Jul 2023 19:11:33 -0600 Subject: [PATCH 16/16] restored examples storage size - The code is correct and you can count the basic elements of each struct, meaning f32, i32, u32, etc. --- examples/dithering3_1/index.js | 2 +- examples/dithering3_2/index.js | 2 +- examples/mouseclickscroll1/index.js | 2 +- examples/noise1/index.js | 4 ++-- examples/shapes1/index.js | 2 +- examples/shapes2/index.js | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/dithering3_1/index.js b/examples/dithering3_1/index.js index 845f76b8..9486b077 100644 --- a/examples/dithering3_1/index.js +++ b/examples/dithering3_1/index.js @@ -16,7 +16,7 @@ const dithering3 = { await points.addTextureImage('image', './../img/absulit_800x800.jpg'); points.addBindingTexture('outputTex', 'computeTexture'); points.addLayers(2); - points.addStorage('variables', 1, 'Variable', 4, false, ShaderType.COMPUTE); + points.addStorage('variables', 1, 'Variable', 1, false, ShaderType.COMPUTE); }, update: points => { diff --git a/examples/dithering3_2/index.js b/examples/dithering3_2/index.js index 01fce08a..f16e3349 100644 --- a/examples/dithering3_2/index.js +++ b/examples/dithering3_2/index.js @@ -16,7 +16,7 @@ const dithering3 = { await points.addTextureImage('image', './../img/absulit_800x800.jpg'); points.addBindingTexture('outputTex', 'computeTexture'); points.addLayers(2); - points.addStorage('variables', 1, 'Variable', 4, false, ShaderType.COMPUTE); + points.addStorage('variables', 1, 'Variable', 1, false, ShaderType.COMPUTE); }, update: points => { diff --git a/examples/mouseclickscroll1/index.js b/examples/mouseclickscroll1/index.js index e93107f8..0b5fa06e 100644 --- a/examples/mouseclickscroll1/index.js +++ b/examples/mouseclickscroll1/index.js @@ -5,7 +5,7 @@ const mouseclickscroll1 = { vert, frag, init: async points => { - points.addStorage('variables', 1, 'Variable', 24); + points.addStorage('variables', 1, 'Variable', 4); }, update: points => { diff --git a/examples/noise1/index.js b/examples/noise1/index.js index a6adcfda..9655fcba 100644 --- a/examples/noise1/index.js +++ b/examples/noise1/index.js @@ -6,8 +6,8 @@ const noise1 = { init: async points => { const numPoints = 800*800; points.addUniform('value_noise_data_length', numPoints); - points.addStorage('value_noise_data', numPoints, 'f32', 4); - points.addStorage('variables', 1, 'Variable', 4); + points.addStorage('value_noise_data', numPoints, 'f32', 1); + points.addStorage('variables', 1, 'Variable', 1); }, update: points => { diff --git a/examples/shapes1/index.js b/examples/shapes1/index.js index a3954770..b25f8730 100644 --- a/examples/shapes1/index.js +++ b/examples/shapes1/index.js @@ -9,7 +9,7 @@ const shapes1 = { init: async points => { const numPoints = 128; points.addUniform('numPoints', numPoints); - points.addStorage('points', numPoints, 'vec2', 8); + points.addStorage('points', numPoints, 'vec2', 2); }, update: points => { diff --git a/examples/shapes2/index.js b/examples/shapes2/index.js index c4bfd027..ea29331b 100644 --- a/examples/shapes2/index.js +++ b/examples/shapes2/index.js @@ -9,7 +9,7 @@ const shapes2 = { init: async points => { const numPoints = 800*800; points.addUniform('numPoints', numPoints); - points.addStorage('points', numPoints, 'vec4', 16); + points.addStorage('points', numPoints, 'vec4', 4); points.addSampler('feedbackSampler', null); points.addBindingTexture('outputTex', 'computeTexture'); },