feedback icon indicating copy to clipboard operation
feedback copied to clipboard

[your-first-webgpu-app] Code clarity improvement, compute shader

Open sp-droid opened this issue 1 year ago • 3 comments

I'm in the process of adapting the code to a rectangular grid and I have a minor suggestion:

  • This code (to get the absolute index from the 2D index) in the compute shader is hard to understand visually:
return (cell.y % u32(grid.y)) * u32(grid.x) + (cell.x % u32(grid.x));

Could be better (and isn't it more performant too?) this way:

return cell.y * u32(grid.x) + cell.x;

The original was causing issues for me when adapting it to the rectangular case actually.

It's also possible to calculate the color of each cell in the vertex shader, then send it to the fragment. I think it makes sense because cell colors are uniform anyway

sp-droid avatar Feb 20 '24 17:02 sp-droid

@toji What do you think of this proposal?

beaufortfrancois avatar Feb 21 '24 10:02 beaufortfrancois

@beaufortfrancois @toji @sp-droid

The tutorial suggests this as a solution to wrap around out-of-bounds indices but I am not sure if it is correct:

fn cellIndex(cell: vec2u) -> u32 {
  return (cell.y % u32(grid.y)) * u32(grid.x) +
         (cell.x % u32(grid.x));
}

In this screenshot, I am highlighting from the suggested tutorial code the various types we are dealing with from computeMain down to cellIndex

image

Taking an example of computeMain being called with cell equal to vec3u(0, 0, 0), then when cellActive(cell.x-1, cell.y-1) is called during the activeNeighbors computation, isn't it equivalent to calling cellActive(max value of u32, max value of u32) (assuming u32(0) - 1 leads to max val of u32 in WebGPU Shading Language)?

If so, then in fn cellActive(x: u32, y: u32) -> u32 we get return cellStateIn[cellIndex(vec2(max val of u32, max val of u32))];

That is a vec2, not a vec2u, so then we mess with that x and y value even further... At this point I am not so sure the cellIndex function will work out properly, but let's say fn cellActive was fixed to use vec2u for the cellIndex call. Then we would have fn cellIndex performing this:

return (max val of u32 % u32(grid.y)) * u32(grid.x) + (max val of u32 % u32(grid.x);

That's not going to return the correct value for arbitrary grid sizes

lhiginbotham avatar May 24 '24 15:05 lhiginbotham

@toji gentle ping

beaufortfrancois avatar May 27 '24 06:05 beaufortfrancois