Liquids optimizations


So, I finally have some spare time to write about what's going on with the game. Well, actually, this post is a little outdated, since I've already implemented all that stuff about a month ago, but anyway, I think it's worth describing.

So my previous post was about liquids and the challenges they pose, this post is about solutions. I started my liquids implementation by using LiquidFun, which is a Box2D extension made by Google. It was a nice start, but it had its own problems, like it could handle thousands of particles, but I needed hundreds of thousands. It also had some particle stability issues, like when the particles are inside simple (e.g. rectangular) volume everything is fine, but if you want to use some smart-ass volume like worm-pipe you're in trouble because particle pressure will almost never even out and liquid will be extremely jittery.

After some experimentation and though I came up with a solution where I modify the engine to freeze inner particles of a liquid, so that no calculations are made for them at all:

Here blue particles are frozen ones, red particles are border particles, i.e. they don't move, but take part in inter-particle collisions. White particles are the only active ones. The trick here is that there's an "activity radius" for white particles, so that for example when there're more than 3 active particles in a row all the rest get frozen toward the "center" of the liquid cluster. And on the other hand, when this white layer starts getting thinner it automatically activates particles from inside the liquid.

Further more, I'm also freezing particles that are in contact with static bodies, thus, this makes open water surface the only thing that's active. Those optimizations allow me to have ~50.000 particles without worrying much about performance on an average machine:

And that's not even multi-threaded yet, it still runs inside game loop. Making it multi-threaded and applying one more optimization (which is pretty hard to implement, but it's possible, I'm not going to go into details on this one here) will allow me to have >100.000 particles easily, but at this point there's no need in that, 50.000 turned out to be more than enough. Another positive side effect of particle freezing is that the liquid can now occupy really complex volumes like worm-pipes without any jitters. The thing is that since the inner particles are frozen there's no impulse propagation throughout an entire volume, so things even-out really fast.

Get The Mission: Demo

Download NowName your own price

Comments

Log in with itch.io to leave a comment.

I love this idea, it's genius :) Have particles wake up neighboring particles when there's activity.  And the side effect that everything settles not only makes sense, but that's a requirement for game physics for things to have a movement threshold where they stop and are not processed until the next interaction occours, and LiquidFun didn't have this and you've added it.