Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible data racing between droplets #10

Open
stephen-hqxu opened this issue Jul 15, 2021 · 3 comments
Open

Possible data racing between droplets #10

stephen-hqxu opened this issue Jul 15, 2021 · 3 comments

Comments

@stephen-hqxu
Copy link

Really nice code and video, but there's one concern to me:

So basically in your GPU implementation each thread controls one water droplet, but what if two droplets descend to the same area at the same time and their erosion/deposition range overlap? Having two threads updating the same pixel at the same time can lead to data incoherence.

I tried the simplest solution by adding atomic operations but it's rather a brute-force approach and the performance is underwhelming, and strange enough the final terrain looks no much different from the original one, maybe the chance of getting overlap is small and it doesn't matter?

There is another erosion model called cell-based erosion that assigns one thread per pixel and tracks the total amount of water content in a cell then divides the content evenly based on the flowing direction. We can use a technique namely virtual pipe to store the content independently for every outflowing direction and sync with one thread per pixel later. Unfotunately in particle erosion it doesn't seem possible. I am really running out of ideas.

@steenish
Copy link

I have also thought about this, and I have implemented the cell-based approach with virtual pipes, but the stability of the simulation and the visual results are underwhelming compared to this particle-based one. I hate that this particle-based method leads to race conditions, but it seems like we just have to live with it if we want it to be fast.

@aparis69
Copy link

The GPU implementation of the repo definitely has a race condition - there is no check for multiple threads writing to the same index of the underlying array. It can be a problem if you are looking for robustness and reproducibility, but in the case of this implementation, the race condition seems to "even out" between all cells, which is probably why you don't see much difference between the race condition-free implementation and the original one.

One idea if you want to limit impact of the race condition: the random indices buffer, which decides from which cell to start on the GPU, could be constructed with "farther away" indices in world space to limit the chance that two particles will collide. Still no guarantee, because particles moves, but probably more robust.

Otherwise, to the best of my knowledge, having a pure GPU particle-based erosion has not been done yet.

@jordanwalker98
Copy link

You can fix all race conditions by doing two things:

  1. Move the droplet update loop outside of the compute shader, track each droplet using a structured buffer, dispatching the kernel repeatedly
  2. Convert the heightmap to and from an intermediate integer texture, you can use interlocked add on an integer texture to ensure that heights are accumulated properly per erosion step

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants