Create algorithm for fluid simulation?

Asked

Viewed 392 times

7

I want to create a simulation game with Unity and I need to simulate the movement of 2D fluids, I can’t think of a way to create an algorithm with enough performance to simulate a thousand particles and still have processing power left over for other tasks that require information about the velocity of the fluid.
Virtually the entire game will be based on thousands of particles suffering and applying forces within an invisible liquid medium in real time.
There is a force calculation tactic that does not require all particles to be searched?.

1 answer

11

Yes, there are some strategies. To begin with you don’t simulate the whole "ocean". You only simulate the area or region of the fluid that will have some contact with the player’s avatar (or an NPC). For example, suppose the player jumps into a pool. You will simulate the fluid only on the surface of the pool. The rest, below, is a blue region simply.

Another common strategy is to simulate fluid only in the visible region to the player (which depends on camera positioning). In the case of Unity, one solution may be to build a small box with the particle emitter of the fluid simulation and place it immediately under the avatar. By moving this area along with the avatar, he may have the perception of interacting with a larger liquid surface. Perhaps you need to control the interaction of the physics of external elements (otherwise, by "moving" the small pool along with the avatar the inertia will move the liquid unexpectedly).

If by chance the player’s view includes much of the surface of the liquid (it is running over the waves on the beach, for example), you may have built up the surface animation of the liquid out of the game, so it does not require as much processing. Anyway, the surface mesh scheme that Unity uses is pretty cool (and uses a lot of the GPU), so you hardly need it unless the platform is quite limited (mobile devices, for example).

Finally, if you want to fully control performance (and knowing that it’s a 2D game), it might be easier for you to implement something simple yourself. Don’t use Unity physics and calculate collisions yourself using large circular particles. The advantage of doing so instead of having a zillion small particles is that:

  1. The collision test is very simple, as just check the radii of the circles (any doubt about collision of circles, open another question - by all means, that my other answer here is a very simple example).
  2. Applying a filter over the rendered image, you easily turn a small number of circles into a "blob" that looks like the liquid.

This process works as follows: the balls are controlled by physics; to each frame, before presenting (to render), a gaussian filter or average to "blur" the image (easy to implement if not ready already - also fits another question) and then make a limiarization to "merge" everything and make it look liquid. Example of the process being executed:

inserir a descrição da imagem aqui

This image is of a great tutorial which includes code ready in Java (easy to port to C#).

P.S.: Still, note that you should not do this simulation for the whole "ocean". Just to the surface. Here is an example in Flash where one can see how this "magic" does not affect the perception in the final result. E here is an example in Webgl where you can "turn off" these steps and see how they affect the final result.

P.S.2.: The link in the above Gaussian filter may seem daunting by the equation, but it’s just a matter of calculating it. Its application is the same as described in the Sobel filter application in this other one of mine reply. The limiarization is also very simple. This other one of mine reply can be of some help (this, with code in C# same).

About particle collision testing, a performance-enhancing strategy is to use some data structure to keep information about the spatial position of each particle - I mean, beyond the mere x coordinate, y. Thus, you can limit the crash tests only to particles that knowingly are closer together.

A simple and straightforward way is to simply divide "the screen" into 4 quadrants. As the particles move, you update their positioning by getting them in/out of a quadrant. So in calculating the collision you only test with the particles that are in the same quadrant. This process can be improved with a more appropriate data structure. For example, if you maintain a Quadtree (in the case of 2D games; in the case of 3D would be an Octree) with the particles, can quickly decide the best regions for the test. A text about collision detection with Quadtree you can find in this document.

There are other techniques (read about the topics in the slides about "Space Subdivision" in this presentation), but then the subject extends a bit. Look for "collision" + "games" right here that there are other questions, incidentally.

  • Thank you, I will see the links, in fact the game will not have npcs, it will be totally based on charged and no charge particles in a non-visible global interaction liquid medium, so I need to simulate all particles simultaneously. No loss of performance. It seems interesting to use this quadtree.

  • 1

    Ah, good. In this case almost everything I mentioned doesn’t suit you. Sorry for the ear tugging... but why, you could have given more details on the question and facilitated my (and your) life right? Yes, in that case what you really have left is to use a Quadtree and separate the particles in comparison regions. Good luck! :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.