Dispatching empty compute shader turns entire canvas transparent

https://playground.babylonjs.com/#FZORY6#1

Dispatching the compute shader in the above example turns the canvas completely transparent (only for frames that the shader was dispatched). The compute shader is empty, and does nothing. This issue only happens if we call one of the update functions on the UniformBuffer ‘shaderParams’ at some point between shader creation and dispatch (so updateMatrix(), update(), etc.).

Am I missing something? I couldn’t find anything related to this in the documentation or elsewhere, and my code structure is based on the Boids example.

Note that I’ve verified that the canvas is transparent as opposed to say, white, by putting a background behind it in previous tests.

cc @Evgeni_Popov

Welcome aboard!

You must be coherent between the resources you declare to be in your compute shader (the bindingsMapping parameter of the ComputeShader constructor) and what you really use in the shader.

In your case, you declare 4 resources but don’t create / use them in the shader code.

I updated your sample to declare and use the Params struct:

Simply declaring params in the shader code is not enough for WebGPU to consider you use it. That’s why I used the special syntax _ = params to instruct WebGPU that I use params (even if it’s not true!). When you add your code, you will really access the properties of params at some point, so you will be able to remove this declaration.

2 Likes

Thanks! While it makes sense that they have to match, a message-less fail condition is very confounding. My takeaway is that when rigging up a compute shader, I need to add bindings one-by-one and run each time to confirm that everything is working (or at least do that when debugging).

For posterity, my understanding is that you need:

  • Binding entry in the bindingsMapping table. Group and binding must match with:
  • Binding attribute in the shader source. Type must correctly match:
  • Calls to setUniformBuffer, setStorageTexture, etc. in the JS code. Uniforms struct fields must match the order in which addUniform was called in JS.
  • All bindings must be “used” within the shader source, which can be guaranteed with a _ = varname; or _ = arrname[0];.

…and if any of those don’t match, dispatching will crash the engine for that frame. :stuck_out_tongue_winking_eye:

Well, it was not message-less. You get these warnings in the browser console with your first PG:

logger.ts:107 BJS - [21:28:04]: WebGPU uncaptured error (1): [object GPUValidationError] - Bind group layout index (0) doesn't correspond to a bind group for this pipeline.
 - While Validating GetBindGroupLayout (0) on [ComputePipeline (unlabeled)]

/#FZORY6#1:1 Bind group layout index (0) doesn't correspond to a bind group for this pipeline.
 - While Validating GetBindGroupLayout (0) on [ComputePipeline (unlabeled)]
logger.ts:107 BJS - [21:28:04]: WebGPU uncaptured error (2): [object GPUValidationError] - [Invalid BindGroupLayout (unlabeled)] is invalid.
 - While validating [BindGroupDescriptor] against [Invalid BindGroupLayout (unlabeled)]
 - While calling [Device "BabylonWebGPUDevice0"].CreateBindGroup([BindGroupDescriptor]).

It may not be very clear for someone who doesn’t know WebGPU, but at least it points to something being wrong somewhere :slight_smile: .

1 Like

Hah, figures I would have the console warnings turned off and forget to check them :joy:. Smh.