Announcement

Collapse
No announcement yet.

Distance Field Flow Map

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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.
    Click image for larger version

Name:	Left4DeadFlowMap.jpg
Views:	1
Size:	33.0 KB
ID:	1155400

    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/publica..._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.

    Click image for larger version

Name:	DistanceFieldGradientDirection.jpg
Views:	1
Size:	17.7 KB
ID:	1155401
    Click image for larger version

Name:	DistanceFieldGradientDirectionResult.jpg
Views:	1
Size:	789.6 KB
ID:	1155402

    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:
    Click image for larger version

Name:	CustomDirectionToNearestSurface.jpg
Views:	1
Size:	510.9 KB
ID:	1155403

    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.

    Click image for larger version

Name:	Mesh.jpg
Views:	1
Size:	495.9 KB
ID:	1155404

    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.

    Click image for larger version

Name:	DotProductDirection.jpg
Views:	1
Size:	88.4 KB
ID:	1155405
    Click image for larger version

Name:	PerpendicularDirection.jpg
Views:	1
Size:	897.6 KB
ID:	1155406

    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!
    Last edited by Roel; 07-12-2015, 10:42 PM.

  • #2
    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?
    Last edited by BobJoel; 07-12-2015, 11:18 PM.

    Comment


    • #3
      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.

      Comment


      • #4
        Originally posted by Daniel.Wenograd View Post
        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.
        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.


        Anyway, this looks really cool!
        Broad Strokes | Jan Kaluza | Marketplace Release: 'Over 9000 Swords' Modular Melee Weapon System
        Currently available for freelance work
        Dev Blog & Tutorials | Twitter

        Comment


        • #5
          Originally posted by Kashaar View Post
          Ahum.

          "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."



          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.

          Comment


          • #6
            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.

            Comment


            • #7
              Originally posted by BobJoel View Post
              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?
              True, the slow thing is the amount of open world assets I use. My GPU is not happy with it.

              Originally posted by Daniel.Wenograd View Post
              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.
              Could be really awesome indeed! But it might also give strange results if you use it with DFAO and DFSS.

              Comment


              • #8
                Nice implementation

                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!

                Comment


                • #9
                  Originally posted by TheJamsh View Post
                  Nice implementation

                  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.

                  Comment


                  • #10
                    Those awesome rocks... :P
                    Artstation
                    Join the support channel
                    Gumroad Store

                    Comment


                    • #11
                      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
                      Lee Devonald
                      Freelance character artist, and generalist.
                      Portfolio: http://crazyferretstudios.com

                      Comment


                      • #12
                        ooh nice

                        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
                        Help me back! follow me on Twitter

                        Developer of Elium - Prison Escape

                        Comment


                        • #13
                          Yay nice! I'll keep watching the thread to see progress
                          MizuGames.com | [FREE] My Hair material | My Twitter

                          Comment


                          • #14
                            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
                            Ryan Brucks
                            Principal Technical Artist, Epic Games

                            Comment


                            • #15
                              This material can’t yet be used with translucent screen space reflections because it will take up to many texture samples.
                              You should be able to use the shared samplers to reduce sampler count in your material, to allow SSR to work

                              Comment

                              Working...
                              X