Liquid Layers
grantkot.com
grantkot.com
Why?
Having thousands of particles, all in need of doing the same operations on them in parallel screams GPU to me. It is just way harder to program a GPU, vs a CPU.
But yeah, once you need to do graphics on top, that 3x pretty much goes away and is just additional frametime. I think they should work together. On my desktop stuff, I also have things like adaptive resolution and sparse grids to more fully take advantage of things that the CPU can do that are harder on GPU.
The Wasm demo is still in its early stages. The particles are just simple points. I could definitely use the GPU a bit more to do lighting and shading a smooth liquid surface.
Yes, because of the very limited numbers of CPU cores. With a GPU you can just assign one core to one particle.
Here is a simple approach to do it with WebGPU:
https://surma.dev/things/webgpu/
It uses the very simple approach, of testing every particle with EVERY other particle. Still very performant (the simulation, the choosen rendering with canvas is very slow)
I currently try to do something like this, but optimised. With the naive approache here and Pixi instead of canvas, I get to 20000 particles 120 fps on an old laptop. I am curious how far I get with an optimized version. But yes, the danger is in calculating and rendering blocking each other. So I have to use the CPU in a smart way, to limit the data being pushed to the GPU. And while I prepare the data on the CPU, the GPU can do the graphic rendering. Like I said, it is way harder to do right this way. When the simulation behaves weird, debugging is pain.
The O(n^2) approach, I fear, cannot really scale to much beyond this number, and as soon as you introduce optimizations that make it less than O(n^2), you've introduced tree search or spatial caching that makes your single "core" (WG) per particle diverge.
Well, like I said, I try to use the CPU side to help with all that. So every particle on the GPU checks maybe the 20 particles around it for collision (and other reactions) and not 14000, like it is currently.
That should give a different result.
Once done with this sideproject, I will post my results here. Maybe you are right and it will not work out, but I think a found a working compromise.
Another reason I did it on CPU was because with WebGL you lack certain things like atomics and groupshared memory, which you now have with WGPU. For the Diligent Engine spatial hashing, atomics is required. I'm mainly using WebGL because of compatibility. iOS Safari still doesn't enable WGPU without special feature flags that user has to enable.
But currently I will likely proceed with my approach where I do transfer data back and forth between CPU and GPU, so I can make use of the CPU to do all kinds of things. But my initial idea was also to keep it all on the GPU, I will see what works best.
And yes, I also would not recommend WebGPU currently for anything that needs to deploy soon to a wide audience. My project is intended as a long term experiment, so I can live with the limitations for now.
In this case there is no long range interaction (aka gravity, electrodynamics), therefore you would go for a pure p2p implementation.
Then in a p2p, if you have very strong coupling between particles that will insure the fact that neighbors stay neighbors (that will be the case with solids, or with very high viscosity). But in most case you will need are rebalancing of the tree (and therefor the memory layout) every time steps. This rebalancing can in fact dominate the execution time as usually the computation on a given particle represent just a few (order 100) flop. Then this rebalancing is usually faster to be done on CPU than on GPU. Then evidently, you can do this rebalancing "well" on gpu, but the effort to have a proper implementation will be huge ;-).
It's like a visual stim toy
I will see if I can bring it to WebAudio.
It's possible to simulate using a grid instead, and that computes pressure very precisely, but it has a downside of adding inaccurate viscosity.
And there are tricks that combine both approaches to balance out the errors.
There are also some large density ratios between the materials which further increased the difficulty, and would also increase the number of pressure projection iterations on a grid. I tried to simulate buoyancy without cheating (e.g. giving different materials different acceleration to gravity)
From the description of "WebAssembly Liquid Simulator" https://www.youtube.com/watch?v=phXwC6HxWEQ
Incredible stuff.
Sometimes for sandbox I feel like 2D can be more fun because people can target particles they interact with better.
Maybe WebXR will be good for the 3D version.