Overview
In this blog we are going to cover a topic which is used in many games. If you play games you have definitely encountered a scene or mission which has a lake, river or ocean which has flowing water in it. This can be very heavy on the system if done with the traditional method like simulating water mesh.
Having water or any kind of simulated fluid in a scene can greatly beautify the scene or helps in storytelling but having so much simulated fluid can impact on performance in real time applications.
To overcome this problem we use flow maps. Flow maps moves UV coordinates in a way that we feel fluid or texture are moving.
1. Creating Flow map
There are different ways to create flow maps using photoshop, krita, GIMP etc. However what we are going to use here is flow map painter. Which is created by Tech artist Teck Lee Tan. It is much easier than photoshop or GIMP.
Here I have created a flow map by just up and down strokes. You can take your time and create a flow map however you like.
Now, To export the map first click on flip red as we are using this in UE4 and click on bake to texture.
2. Importing into Unreal Engine
Now create a project if you haven’t by going into epic games launcher and start UE. upon project creation pop-up choose blank or your choice of template and create project. It can take some time so be patient.
Once the project is open import the flow map image and your water texture or water ripple normal map by right clicking in the content browser and click import or just drag and drop from the file browser.
After importing there are some changes that need to be done. Open your image and zoom there is a chance that we have a gradient issue.
This is because of compression, to solve this change the compression method to Normal Map. This will solve the gradient issue and change the color range from 0 to 1 to -1 to 1.
3. Creating shader
Unreal Engine provides different flow map functions but we are here trying to understand the math inside that function and making our own function.
First create a shader by right clicking in the content browser, give it any name and add texture sample Node. Select the flow map we just created. We need only the Red and Green component because the flow map contains only these two channels so mask out others.
Now we add a constant that controls the flow strength and multiply it with a flow map. Now we add this newly created flow to the UV coordinates. At this point if you add the flow map direction to UV coordinates you will see the texture looks like it is flowing but it froze at single frame.
To move this texture we have to add a time node and clamp its value then multiply it with flow before adding it to UV Coordinates.
At this point our flow is working but it has some ugly looking pop to fix this we use the two different phases of time. Right before the frac we add 0.5 constant to it and create the same node tree as before.
Now at this point we can see both textures look the same but one is offset by 0.5. Now we have to lerp between these two textures in a way that in the first phase when the first texture is popping the second texture blends in and in the second phase when second texture popping first texture blends in.
For that we have to add a linear interpolation node and to create a mask we take the value from the first frac node and multiply it with 2 and subtract 1 from it and take the absolute value of it. Which gives the result like ping-pong back and forth between 0 & 1.
4. Creating Function for Reusability
Now we need to create this shader as a function so we can use it any time we need. To create a function we just have to convert the shader logic to function.
5. Using Function in Shader
To import a function in your material right click or press tab and search for the function you created if it doesn’t appear in the search. Go to the function and check the expose to the library.
Now add the function and connect the inputs and outputs.
Here we can directly apply texture coordinates to UVs. This multiply function is just for the scaling function.
Here’s the result you will see after applying the material.
Here’s a Final Output of our Fluid Motion…
Read: Simplifying RecyclerViews with binding adapter & data binding
Conclusion
Flow maps are great for real time effects like flowing water or fluid. This cheap trick can save lots of computational power especially in mobile devices. However if your scene contains close up shorts or scenes for the production or it is cutscene or anything which is not real time then it is recommended to use simulated fluid.