Fluid Dynamics - Curl Noise

I had another go at using Curl Noise to approximate fluid flow. I have been following this paper somewhat

Basically a grid is generated and at each point a noise value is obtained (just a scalar value). Then from this noise the fluid flow vector field is derived (just by taking the curl) and so you get turbulence over the whole grid. My noise is crappy (just a function like sin(x*y) so bear that in mind).

Then a mask is added on top which is by default 0. When the mask is 0 you see no turbulence but when the mask is non-zero you can see through it to the turbulent layer underneath. As the microbes move they leave a trail of high mask values behind them (proportional to their speed) which is why they have a turbulent trail.

The mask values then diffuse (using the heat equation, if I were a pony and had one trick applying the heat equation spuriously would be it) and decay over time so after a while you cant see the turbulence anymore.

This implementation (code in the the prototypes repository - marked aug15) is stupid in that it generated the turbulence everywhere whereas it would be much more efficient to only generate it where the mask is non-zero. Anyway what do you guys think? Is this the sort of thing you are imagining with fluid flow?

Fantastic job! Sorry for taking over a week to reply, I’ve been on vacation. Overall, I think your prototype looks great—the most turbulence is located right behind the moving balls and it slowly diminishes as it gets farther away. I also really liked the part where the paths of the two circles crossed. I do, however, have a couple questions:

First of all, the turbulence behind the ball is located in almost a straight line, while in nature it would diffuse, creating a sort of cape behind the moving object. Is this a limitation of the algorithm you are using, or is it possible to fix it? I believe changing the water flowing path into a triangle would greatly add towards the realism.

Second, in the video you showed, are the moving cells at all affected by the created vector field, or is it purely cosmetic?

Regardless, I think adding this to the game with a decent shader would be fantastic.

Dude take your time with all this stuff, this is a long project, there’s no rush.

  1. Yes. You can basically make the mask do whatever you would like. You could remove a triangle behind a cell, I was trying to get it to work with diffusion just because there is the question of how long the cell has been moving. A cell that has just started moving will have a small bow wave and one that has been moving a long time will have a large one. I’ll mess around with the parameters a bit and see if I can get it to look better.

  2. The cells are unaffected by the vector field right now. The turbulence is very small scale so it would feel a bit odd, I think, to be affected by it. Maybe bacteria should be affected by it. I think this is kind of a gameplay issue. You should move how it is fun to move rather than something which is purely realistic. Being affected by the fluid could be part of that. We can try it.

  3. I had a go this afternoon. I tried implementing a wave equation not a heat equation. It does give bow waves but also has a horrible tendency to blow up, which kind of sucks. I’ll keep poking at it. I think it needs someone better than me to do it really.

  1. Okay, you do that. Good luck!

  2. Yeah, I see your point. I was just wondering since it was hard to tell from your simulation. I think that the plan is to have currents that would affect cells. compound clouds and bacteria. I think this could easily be accomplished by adding a single vector that changes over time (possibly connected to a noise function) to the vector field you created.

One thing to remember is if you add the same vector to everything you won’t be able to notice it. It will basically be a Galilean transformation.

When I get a chance I’ll do a more conventional fluid setup and see how that looks.

@tjwhale: I am going to go ahead and commandeer this thread if you don’t mind. With the membrane more or less finished, I am moving on to the next most pressing graphical “issue” in Thrive. Namely, the unrealistic compounds and lack of a fluid simulation. Drawing inspiration from the above work and a couple research papers, I came up with this:

Edit: Oh my god. I just realized my video is in 240p. :anguished:


This just looks awesome (well, to me at least). Anyway, after spending a couple of days working on fluid simulations for Thrive and a good way to represent compound clouds I think I finally got somewhere.

So far I have:

  • Found out how to use libnoise
  • Implemented curl noise fluid dynamics
  • Heavily optimized my initial implementation
  • Figured out a way how to get compound clouds to retain their shape and look like clouds instead of ribbons

What I have not done:

  • Fluids are currently confined to the screen and are unable to go across the edge. Likewise, if the player moves the camera, he will notice that there are no particles outside the screen.
  • No matter how much I tried, I could not get the fluids to go around objects.
  • Allow the player to initiate a wake of turbulence behind him (will probably just use @tjwhale’s prototype and add the noise)
  • Added sprites to the points (this will make the fluid look like at actual fluid instead of a bunch of points)

What I am going to do know:

  • My first step will be to create a dedicated CompoundCloud class that will allow me to spawn as many clouds of different colors as I want, wherever I want.
  • Create an EmmiterClass that will allow me to generate CompoundCloud classes (I could then add this emitter to bacteria or geothermal sites to constantly generate compound clouds)

And now for the video that you’ve all been waiting for I’m sure (This time in HD):


That is amazing. I love it.

In the paper (in the top post) they have a section on boundaries and they offer two options. One is to make the noise 0 on the boundary of an object and then grow smoothly as you move away from it. The other is to make the boundary an iso-contour of the noise (so the boundary of the object has the same value of the noise all around it). The use a ramp function for this which they specify. This causes the fluid to move perpendicularly to the boundary and so to slip round it.

A simple way of doing a wake is just to have the microbes add to the noise in the place that they are sitting in. Though that will give a straight line rather than a wake.

Great stuff :smile:

:slight_smile: Thanks! I’ve tried using the iso-contour option, but that didn’t really seem to work. However, I must have skipped over the noise 0 at boundary part, so thanks for reminding me!

In the paper they were saying it doesn’t need to be 0, just that it needs to be constant (if you want the fluid to slip by (non-penetration boundary condition)).

Also I love what you’ve done to keep the cloud together as a cloud, looks very natural.

I don’t think we should add boundary conditions – compound clouds will flow off the edge of the simulated area, for example, so we shouldn’t bother bounding them there; and microbes that swim through compound clouds will have to absorb compounds, so we probably shouldn’t set boundary conditions that cause the flow to go around the microbes. Also, if we add boundary conditions for moving objects, we’d have to recalculate the curl field every frame, and that’s expensive

I think, aesthetically, we might want the noise to be in a higher octave. From what I was imagining when I suggested curl noise, I thought the diffusion of a cloud could look like dozens of thin, twisty wisps of compound streaming out from the center, rather than one large blob streaming along. You’d need to go 2 or 3 octaves up for that kind of behaviour, but if we just go up one octave (like, double noise resolution) we might get something sort-of in the middle, where a cloud of compound splits along several nearby trails that still kinda stick together for ease of gameplay (if you want to keep the sticking-together behaviour), instead of one blob following one path.

Though that’s just my preconception, and this looks really cool, and would make for some very interesting gameplay.

Here’s another idea for an optimization: instead of using tons of points for a cloud, use a couple control points streaming along, and we can try using the ogre particle system (or hack together our own extension) to generate particles which move around those control points. If those particles move in twisty, random-ish paths, all the better, it could increase the apparent noisiness of the cloud’s motion much more cheaply than having orders of magnitude more points in each cloud.

And an idea for your prototypes: instead of having lots of points floating around to show the flow, maybe do something like what tjwhale did upthread, use fixed lines. And if you don’t add anything that changes the curl field every frame, then you can also make all those lines stay fixed the entire time it’s running. Lets you see flow direction, but reduces calculations so it’s easier to see how fast the actual compound-cloud computations are.

It looks really awesome, by the way!

Short progress report: Got everything factored into classes, will now transfer this to Ogre.

That makes sense, if fluids flowed around microbes then it would be impossible to absorb them. I was thinking more of allowing for things like rocks. Speaking of recalculating curl every frame, I actually did that in my first prototype and everything worked perfectly fine.

I tried increasing the octave count, but that resulted in a lot of clumping and unnatural and edgy boundaries. Even when I changed it from 6 to 7. Might be because of my implementation, but it looks really bad.

Using a few control points would be good, but what I have so far isn’t really computationally expensive. Eventually, I was thinking of using semi-transparent billboards to create realistic clouds, but a paticle system might also work.

I, personally, think its a lot easier to see fluid flow when there actually is flow instead of just a slope field. Plus, these points are always going to be there to simulate currents, even after I port it to Ogre (well, they’ll have decent looking textures such as bubbles and billboards).

Here’s a couple of images:


So I did some calculations and timing. A cloud of 5000 particles takes 0.01 seconds per frame (not counting the initial calculation of the velocity from curl). Thrive currently runs at around 60 fps on my laptop, which is around 0.0166 seconds per frame. Having one cloud in the game will come close to halving the fps, which is obviously not ideal. We could theoretically not re-calculate the velocity of every particle each frame, but this would be at most a 90% increase in speed and we would still see a significant drop in frame count. I am honestly willing to give the fluid sim/compound clouds/rendering combo at most 0.005 seconds per frame, which would give me 50 fps. Since we will be simultaneously getting rid of particle emitters as well, which currently clutter the fps, the speed would be even faster.

Let’s calculate this now. If we plan on having anywhere from 5 to 20 clouds on the screen, we can dedicate 0.00025 seconds per cloud. From the above measurement, one particle takes 0.01/5000 = 0.000002 second to move, so we can have 125 particles. Let’s round down to 100 just in case. That’s actually not a bad number for seed particles, now let’s see if we can use these to create realistic looking cloud motion.

Here is another video:

I finally ported my prototype code into Thrive. They are randomly spawned and despawned, and all the compound clouds (which are marked with the purple nucleus model) follow the same dynamic velocity field. I will now attempt to let AI microbes also absorb the compound clouds (right now only the player cell can) and give everyone compound points for doing so. Then I will work on getting good graphics using a particle system and, hopefully, we can release 0.3.1 before New Year.

1 Like

That’s cool!

Are you getting reasonable frame rate?

What do you think about having the water current move the cells around? It could be an interesting type of terrain and the effect could be quite mild (though it might be interesting to experiment with an unpowered microbe moving in exactly the same way as the compounds (though I suppose if you floated in exactly the same way as the compounds you could never collect any of them (though maybe that’s not true due to mixing))).

Not sure if it’s a good idea or not, I guess that can only be answered when we have some idea of gameplay. I do quite like the notion of drifting gently down stream.

The framerate isn’t too bad. I kind of went overboard with the amount of compound clouds and I didn’t remove any of the current compound emitters which significantly drop framerate and got 25 fps.

We could experiment with water currents for cells after I finish the clouds. In fact, I have a density parameter which we could use (so we can have the currents not affect the cells as much as they affect the less viscous clouds). Although, on the other hand, I don’t think there are too many currents at the scale we are talking about.

You guys ready for the Christmas release of 0.3.1? After working and failing with particle system for the past week, I finally got the effect I wanted, see below:

You know what the best part is? The framerate drop was extremely minor (3-4 fps), and I haven’t really done any optimization yet.

1 Like

That’s awesome.

Fantastic work! Is it possible to make the cloud not all absorbed at once? So you “suck” up the compounds as you pass over them?

@NickTheNick: I’m not quite sure yet, but I’m working on it.

Here is a newer and better video, btw: