Scthe / frostbitten-hair-webgpu

Software rasterizing hair strands with analytical AA and OIT. Inspired by Frostbite's hair system: "Every Strand Counts: Physics and Rendering Behind Frostbite's Hair".
MIT License
33 stars 1 forks source link

Binding size error while running in chrome on apple m3 max: #1

Open UnfoldingSeed opened 2 weeks ago

UnfoldingSeed commented 2 weeks ago

Full error: WebGPU error [frame][validation]: Binding size (146847752) of [Buffer "hair-segments-per-tile"] is larger than the maximum binding size (134217728).

EDIT: I was able to fix by changing line 38 of "segmentCountPerTileBuffer.ts" from const size = entries BYTES_U32; to const size = Math.min(entries BYTES_U32, device.limits.maxStorageBufferBindingSize);

Thanks for sharing this awesome project!

Scthe commented 2 weeks ago

If I had to guess, your display has high resolution. Seems likely given you've mentioned apple m3 max. Some buffers in the app allocate size based on the screen size. The default limit for buffer size is 128 MB, which seems not enough. Before delving into technicalities, can you try resizing the browser window to something smaller? It's a crappy temporary solution, but at least you should be able to interact with the app.

I will have to think about how to handle this best. The issue is that the browser window can always be resized, so I don't know upfront what would be the render size. I could check display dimensions, but what if someone has 2 different monitors, etc. IIRC onnyxruntime, which is Microsoft's project that uses WebGPU to run neural networks in browsers sets this values to something crazy high.

A quick fix if you want to try:

If needed, the limits themself are set in src/utils/webgpu.ts. I've raised both maxStorageBufferBindingSize and maxBufferSize to 2 GB and rendered 4k x 4k image using offline mode (Deno).


EDIT

Seems onnxruntime sets device limits based on the adapter's max (2.1 GB for me).

const adapter = await navigator.gpu.requestAdapter();
const deviceDescriptor: GPUDeviceDescriptor = {
  requiredLimits: {
    maxStorageBufferBindingSize: adapter.limits.maxStorageBufferBindingSize,
    maxBufferSize: adapter.limits.maxBufferSize,
   // (...)
  }
};
Scthe commented 1 week ago

I've increased memory limits in https://github.com/Scthe/frostbitten-hair-webgpu/commit/f4b32dfe3776562d9c1b1206515f307fd489122f .

Precaution:

  1. Performance will not be great, the whole algorithm is resolution sensitive.
  2. There might be missing hair segments due to invalidTilesPerSegmentThreshold. There is a description in code with details. Basically, if the hair segment spans a lot of tiles, it is discarded. This prevents hair physics doing wonky stuff and tanking framerate to <1fps.