Procedural Rivers of Lava

I wanted a river to flow down a tunnel in my game, Crystal Flux. At first I had my friend Peter Severud reverse engineer the lava in Epic’s Elemental Demo. It looked great but came with limitations:
-I would have to be careful with UVs and make each asset for every bit of lava I placed in the world.
-It was hard to bend some of the geometry around parts of the tunnel, even using spline mesh assets.

Flash forward about a year when I’m finalizing the materials for the lava levels, I decided to take another approach. This time I would use material shaders to get the look I wanted. In the first image I just used simple math nodes to get a river to line up on the bottom of any geometry I threw at it. If the dot product against the vertex normal is greater than .85 then make it white. Though some layering of the same technique we get a blur river with white shore line at the bottom of the tunnel… not bad!


But we can do better. This is when I added those fancy “World Aligned Blend” nodes to make the edges of the river fade and give more color (also later used for displacement). The neat thing about this node is that you can plug in a normal map to break up the edges for a more natural look.


With the parameters I’ve just shown we can then easily adjust how large or deep the river looks.


Adjust the noise and we can dial in how much the river twists and bends.


I’ll skip ahead to my final video of the material because the rest is more specific for my scenario.

Hope this is useful in your projects. Questions or suggestions welcome! If you are in the Seattle area and would like to see it in more detail I will be going over it at my monthly workshop this Saturday 9/17/2016.

This is great! Thanks for posting this breakdown. How is the flow direction controlled?

In my final material I control the UVs of the textures by first projecting in the Z axis and then adding a parameter “flow” which I adjust in my Tunnel Blueprint. You can also control the flow by just adding a “time” node to the UV coordinates but it doesn’t work well with seams.