Great work Gabe!
Incredible job, love the breakdown and can't wait to see what you make next!
Simon Trümpler (also known as Simon or Simonschreibt) explained how he created the river simulation in Houdini & Unreal and shared some valuable notes. Make sure to also check his RealtimeVFX thread and his website where you can find even more awesome tricks.
- You can download the Unreal and Houdini Assets here. Here’s an Installation video.
- For the major part of the project, I followed tutorials by Ben Schrijvers and Andreas Glad.
- Don’t be afraid of Nodes and Scripts. It’s not as hard as it may look.
- For the water, I used a normal-map from the Unreal Starter content.
I’m Simon. I started programming with QBasic and Pascal when I was young (here are examples), realized that coding is hard, and changed to 3D art but always kept my interest for the technical side of making games which now culminates in being a VFX artist – a profession which combines art and tech very well.
Getting Acquainted with Houdini
Houdini and I became friends during the work on The Invisible Hours where I needed to make a small liquid simulation which could be paused, reversed and played forward in realtime (because in the game you can stop, reverse and forward time). This was the result:
I had no idea how to bring a liquid simulation into Unreal but luckily an amazing tech called Vertex-Count-Agnostic Morph Target-Based Fluid Animation was just implemented into Houdini and so I was able to get my fluid simulation into the game. The technology was originally developed by Norman Schaar.
If you want to know more about the implementation, you can watch this section of my talk “Cool Stuff with Textures”:
River Effect: Start of the Project
I wanted to learn how to make a procedurally generated river for the Realtime VFX River Challenge but had no idea how to start. Accidentally I stumbled across this amazing tutorial from Ben Schrijvers where he talks about the rivers in Horizon Zero Dawn. I was hooked and had to try it out!
By the way, there is another really cool Houdini river tutorial by Andreas Glad:
These videos where my main foundation and helped a ton to get everything started.
Very Complex Way of Building Terrains
The terrain was super complex. Let me illustrate the creation-process with a video to make sure everyone can follow along:
Source: Terrain Creation in Houdini
Just kidding. The shelf-tools make it very easy to create a terrain. I just set a smaller size and it was ready to go.
The first steps are 100% copied from Ben’s tutorial and they are fascinating. First, you create a spline and let it “fall down” on the terrain. This is done by reading the height of the terrain at the spline-point-positions and then moving the points to this height:
Next, you let the spline-points “roll” down the hill to integrate the river a bit better to the terrain:
Actually, they do not roll in a physical way. Instead, you use the underlying surface-normal and the normal of the point to calculate a local axis for each point (which points away from the spline and down the hill). Then, you move the points along the calculated axis a little bit (this process is documented very well in Ben’s video).
The next step is to make sure, that the river does not flow upstream in case the terrain directs it to (because there’s a little hill where the river goes along).
A little Python script makes sure that a spline-point is never higher in 3D space than the point before on the spline:
Another nice trick for a more natural appearance is to avoid continuous slopes but instead let the river flow in steps (for better visualization I show the river-geometry here, but actually we’re still only working with a single spline for now).
Finally, we reach a step where I contribute my own ideas: I add colors to the spline to mark where a slope is (green), where it starts (turquoise) and where it ends (red). This will help me later to blend different water-textures and place particle systems.
Let’s go a little bit faster over the river-geometry-creation since all of that is perfectly fine explained in Ben’s video. The most important point is, that only the outer edges of the river get aligned again with the terrain (like we did with the spline in the first place):
Deforming the Landscape According to the Flow
Again, it’s 100% Ben’s workflow but it starts by moving the terrain below the river geometry so that it does not intersect in any way:
Then, for every point in the terrain, you shoot a ray upward. If it hits the river geometry, this point will be moved upward to the hit-position:
Every point which didn’t hit anything gets its original height assigned again:
Here you can see how everything behaves now when you change your spline:
Then the terrain height-field gets converted into polygons and re-meshed. Now it’s ready for being used in Unreal:
I would also like to add some details about UVs, Materials, Flow-Maps, and more.
The river geometry you saw before was just used to carve the terrain. The actual river is a bit thinner, got UVs and was subdivided (note, that my slope-colors are still there):
Since the spline always varies in length, the UVs must adapt to that. Luckily this is very easy in Houdini. First, you create your UVs in the 0-1-UV-Space and then you measure the spline-length. This value can be used to scale the UVs. Here you see me changing the spline and in the lower part, you see how the UVs auto-adapt. Believe me, if you experienced this once, you never want to manually create UVs anymore!
Another detail: I wanted to make the river bed darker and wet. To do that, I shoot some rays from every terrain-polygon upward and if I hit the river, I assign a color to all points of that polygon. The created mask looks like this:
And here is an example of how much difference it makes when using the mask in a material to assign different diffuse and roughness values:
Generating the flow-map for the river is super easy with Houdini. You just tell a special node “This is my river geometry and this is the spline which indicates the river-direction” and boom, your river geometry suddenly has vertex colors assigned representing the flow of the river:
Another node can be added which makes the flow-map react to obstacles. Now the water can flow around them:
And the best thing: you can trigger the baking of the flow-map in Unreal! No need to switch back and forth between Unreal and Houdini. Just expose the Houdini-“Render”-Button as Parameter. Here you see me changing the obstacles and then render a new flow-map (note that the baking takes a longer time than in the gif):
To get some foam on the water around obstacles, I use a so-called “isoOffset”-node. It stores basically the distance to an object into the vertex color of the river. Then I spice it up with a little noise and the mask is good to go:
To make the foam-mask less static, I use a simple Photoshop cloud pattern which I move along the river and subtract it from the original mask. This adds a more interesting feel:
And since we’re talking about foam: The cascades get a simple foam texture too, which is only shown at the slope of the river (I masked this slope at the beginning with vertex colors when I was creating the spline). The foam structure is scrolling faster than the river water:
Because I stored where top and bottom of my cascade are, I can now filter those elements (these lines were used to generate the river-geometry), create a point in their center and copy a dummy-cube to this point which will be exchanged against a particle system in Unreal later:
For the particles around the obstacles, I’m using a nice node called “Intersection Analysis” to get the intersection of obstacles and river. Those intersection-edges have points. To a random number of those I copy a dummy-box again (which is exchanged against a particle system in Unreal later):
Here you see how it looks when I exchange the dummies in Unreal:
Exporting the Project into Unreal
The so-called Houdini Engine is a plugin for Unity, Unreal, 3ds Max, Maya, and Cinema 4D and executes the node networks you create in Houdini directly in the mentioned programs. So what I have to do, to make the terrain and river show up is to save my Houdini-File as Digital Asset. This can be imported and used like any other asset in Unreal:
Now, I can change parameters (which I exposed in Houdini) or change the spline to make the river take a different road:
The materials are still created and assigned in Unreal but you can pre-assign materials (check my tutorial about this below).
Of course, it’s not perfect yet. Further improvements would for example be: avoid placing obstacle-particles “behind” objects (away from river flow direction), setting the orientation of the obstacle-particles along the flow-map so that particles move into the direction of the flow, accept Unreal-Terrain as Input, improve performance of the node-network so that changes on the spline get calculated faster, narrowing/extending the river-width depending on the area (like in Ben’s video).
Should We Learn Houdini Workflow Alike?
Houdini has a steep learning curve. Besides, since the game dev tools are brand-new, sometimes you will find bugs, anomalies in the documentation or you’ll struggle to get the output as you want it to be.
But that’s a common situation for game developers, isn’t it? We’re often working with cutting-edge technology which has to be tamed first. Most importantly: you’re not alone. The Thinking Procedural Discord is full of very nice people which are eager to learn and help. You can even find Sidefx developers in those chats!
I can totally recommend checking out the software solution. Every day new amazing tutorials appear and the game dev tools are a great way to use the software not “just” for baking out some simulations into flip books but improving the workflow in a way, that classic workflows feel like stone-age.
Thanks to Damien, lKruel, mgw, Ambrosiussen, Glad and Julián (all from “Thinking Procedural” Discord! Wouldn’t have been possible to finish the project without you.
- You can download the Unreal and Houdini Assets here. Here is an Installation video.
- Discord: Houdini “Thinking Procedural”
- Houdini river Tutorial by Ben Schrijvers
- Houdini river tutorial by Andreas Glad
- Simon’s River Challenge Thread with more details
- Simon’s Talk containing the Liquid Implementation in “The Invisible Hours”
- Simon’s Unreal and Houdini Youtube channels
- Vertex-count-agnostic Morph Targets by Norman Schaar
If you found this article interesting, below we are listing a couple of related Unity Store Assets that may be useful for you.
Simon, VFX Artist
Interview conducted by Kirill Tokarev