Distance Field Flow Map

Hi everyone!

I have been working on a way to dynamically create flow maps for water based on the distance field data. Here is the result:

IMPORTANT: The following material is made in the Unreal Engine 4.9 master branch from GitHub. This will not work in 4.8!
This material can’t yet be used with translucent screen space reflections because it will take up to many texture samples.

DOWNLOAD:
roelbartstra.com/resources/downloads/distancefieldflowmap.zip

Let’s start of by talking about flow maps and what they do exactly. A flow map is usually covering the entire water surface to give per pixel information about the direction the water is moving towards. This an example flow map from the game Left 4 Dead 2.

There is clearly a lot of saturated red and green and no blue. This is because we are providing a 2 dimensional direction in which the water should move. Red being the x direction and green being the y direction. We can pan the texture in this direction to fake water flow, making it feel much livelier.
I won’t go in too much detail on the actual flow map math. If you would like to know more about it, I would suggest reading Valve’s Siggraph talk about flow maps: http://www.valvesoftware.com/publications/2010/siggraph2010_vlachos_waterflow.pdf
In the past these flow textures were always pre-painted. This can be done with a variety of different tools. But the problem is, if something moves dynamically through the water, it will not influence the flow map. It can also end up being a pain in the *** if you have to make a ton of them for different levels.
In Unreal Engine 4.9 there will be a couple of new material nodes related to distance field data. The ones I used the flow mapping are called “DistanceToNearestSurface” and “DistanceFieldGradient”. At first sight the DistanceFieldGradient node seems to be what we want since we can normalize it and then it will return the direction. Here you can see masking the red and green channel from the Distance Field Gradient looks already very similar to a flow map.


Although it gives a results which looks like it could resemble a flow map, the flow will look strange when the directions changes too abrupt. To make a more “blurred” directional map I made my own direction to nearest surface based on the distance to nearest surface:

This way we can tweak the “smoothness” value easily. The smoother the value, the less accurate the direction will be.
Since this particular material is made for a river we first need to have an initial flow direction. Preferably something the artist can easily control. My current solution is to use the uv coordinates. You can see in the image below the uv coordinates are laid out straight even though the river mesh (purple thingy on the right) is curved.

We can transform the y (green) coordinates from tangent space into world space to get the directional flow based on the uv’s. We do this in world space since the distance field data we receive is also in world space. We can take the average between these 2 directions to quickly calculate the flow. This will mean if the directions are both the same, the river will move in the direction provided by the artist. If the distance field direction is going the other way, the flow will, in most cases, go to the side. Evading the object.

We can now use a dot product to compare this uv direction with the distance field flow, giving the following results.


If the distance field flow is perpendicular to the uv flow it will return 1 if it is in the opposite direction it will be zero. Anything in-between will be an interpolated value.
I have used this data to push the water upwards when it’s heading towards an obstacle, and downwards when the flow is moving away from an obstacle. It’s also used as a mask for the foam.

That’s all for now, I might go into more detail later on. In the mean time, enjoy!

1 Like

Certainly one of the coolest things I’ve seen done in the engine to date! I imagine the performance would be decent using distance fields?

Hmm. In theory, couldn’t you also use the distance fields with that green channel to get the displacement effect of water going up against the object? This could be the start of a very cool way to make realistic rivers.

Ahum.

:wink:

Anyway, this looks really cool!

I should learn to read and not get distracted by pretty videos. In any case, this is a pretty amazing use of distance fields! Might even be worth attaching an invisible static mesh to the player character to get it working on players too. Doesn’t need to be accurate, as long as it’s getting the general area most people probably wouldn’t notice.

Would it be possible to make a blueprint that bakes the flow map into a texture when needed? That way you could just sample the texture instead of dynamically calculating every frame.

True, the slow thing is the amount of open world assets I use. My GPU is not happy with it.

Could be really awesome indeed! But it might also give strange results if you use it with DFAO and DFSS.

Nice implementation :smiley:

You actually went about it much more simple than me, I was using DDX and DDY to do calculations based on the neighbour… quickly got out of hand. This is really nice though!

Maybe yours will give better results! Would be cool to compare them in the end. I might have some time this week to work a little more on it.

Those awesome rocks… :stuck_out_tongue:

this is incredibly cool, you should try to use the distance fields to calculate how close things are to each other and speed up water flow the closer they are :slight_smile:

ooh nice :slight_smile:

finally a good solution that solves the problems that depthbias always had!
the only thing is that there’s still parts where the flow is not quite there yet. most notably, the river surrounds the rock, but the back of the rock still has water flowing straight out of it. probably something that playing around with the values can fix though

Yay nice! I’ll keep watching the thread to see progress :smiley:

Very cool. This is one of the potential uses that I was hoping to experiment at some point. I am glad to see somebody trying it out and with Kite Demo assets no less :slight_smile:

You should be able to use the shared samplers to reduce sampler count in your material, to allow SSR to work

Very smart technique btw Roel, great stuff. The water flowing straight out of the back of rocks breaks the illusion sometimes. But on the sides of rocks it works great.

http://fat.gfycat.com/MeaslyFilthyIsabellineshrike.gif

My attempt at distance field based water flow. It calcs the tangent of the gradient against the water flow and uses that to warp the uvs.

Wow guys, that’s fantastic! So cool what can be done with shaders in UE4 right in the editor, I’m still amazed by it.

Yeah it looks really awesome, now please put it in the marketplace or release it anywhere else, I need a nice river for my game :slight_smile:

Yes I noticed that too, it is not pretty, but I will look into it later today to see if I can make it more natural. Thanks for the feedback!