Great work Gabe!
Incredible job, love the breakdown and can't wait to see what you make next!
We’ve decided to prepare a breakdown of two tutorials from Guerrilla Games on generating rivers and cables in Houdini. Two senior artists showed how Houdini was used to help create some of the dazzling environments featured in Horizon Zero Dawn. There are two guides here — Ben Schrijvers gave a detailed look at a river tools system and Vladimir Lopatin discussed his work on a cable generator.
The breakdown is based on the video below:
Ben Schrijvers, a Senior Visual Effect Artist who has worked on Horizon Zero Dawn, Killzone Shadow Fall, Killzone 3, Killzone 2, Superman Returns, X-Men: The Last Stand and other titles, showed how the team used Houdini to create most of the river tools using the Houdini plugin inside of Maya to allow the environment artists to create and modify the rivers.
The team has also used Houdini to do prototyping for the clouds and an animation system for crowds and the robots in the distance, the cables, the lightning and hacking.
Let’s take a closer look at the rivers now. The artist has been experimenting with Houdini 16 and the height fields and he was trying to get it working with some core principles of the river tool.
What he got in the end is a river running through terrain. Start with a curve and a terrain, obviously, to tell where you want the river to be. You want your river to make sense when it comes to dealing with gameplay. You want the full control, but you want to make it look natural.
The curve snaps onto the terrain. It’s not a difficult thing. The artist is just sampling the height and the height goes into the vertical component of the position feeding the position back. He is also sampling the gradients of the terrain.
He added some vertical axis because it’s a flat volume that game him the correct normal so this gives him the position and the normal of the terrain. For Loop slides the terrain and it is based on the amount of iterations, so when we move this down we see it looks more like the income curve.
The artist then sampled a terrain, making it slide sideways. Ben took the previous point position and the current position to get a vector along the curve, unnormalized the vector and it now goes into a little strip network which is connecting other stuff on the bottom.
Step by step, you will make your river go upstream. It goes up a mountain and then it goes down again. Ben made a node that sort of prevents water from flowing uphill, so it’s only allowed to go down. To do that you need to go looking through the points, one by one.
Python gives you an easy way to look through the points in the order of the curve. Take a minimum height and set that height each iteration. This is the core function – the river will never go higher, it will only go lower. Rather than going over the hill, it cuts the hill. The river reacts to different little hills – it automatically picks a nice location to make it look natural.
The next step is to create the width of the river. Set up the line of the river using the normal. This is a little bit more complicated.
Take the point number and subtract one to read the position of the previous points that gives you a vector along the curve.
Smooth your normal attribute to smooth cross-section alignments. The river width is then controlled by three things. First, set up a ramp parameter, then a scale factor on top of this ramp. Measure the slope of the terrain to compare the vertical components that we get here by the length of the horizontal components which gives you a certain value.
Make sure you river is more narrow in the canyon so all that is coming out is like a scale which is a three-dimensional vector.
The next step is to build the river because it’s still a flat profile so we have to give the river some depth. The artist is actually creating curves again to be able to grab the outside edges and project them on the terrain again using the same trick by sampling the volume.
Step by step you have some water finally, it looks a bit synthetic, so use a custom network that will add some noise for depth. The artist used a mountain node that’s very useful for adding noise to terrain. But now you have some sharp edges, so you need a way to fade out the new terrain. The artist has added an alpha channel and it’s adding alpha as a point attribute to the mesh in order to sample the point attributes. It’s fixing those edges.
Use the intersect to get the value and the UV coordinates of the polygon it has hits
The artist has actually not used this noise when working on Horizon. He sampled the terrain and let it slide down. He has also done that for the edges, so the edges are also notified by the terrain itself. This way the whole thing gets integrated better.
The last thing here is to build a cascading feature. It’s not a good option to have two streams slide down as a one continuous thing. Do it in steps! Make the water accumulate, use reservoirs, let it widen and go through cascade areas – that will give you more realistic results.
Yes, the real game example would be way more complex – it’s all about the water depth, edges with certain angles for players to climb in or out of the water. Still, this example give an understanding of some core principles.
The tool used for production has a lot more controls to change various attributes on a local scale like the width and the river depth. In Maya all the parameters are automatically generated, which gives the artists a lot of control.
Vladimir Lopatin, a Houdini artist who has worked at Guerrilla for 10 years, showed how they used Houdini general pipeline tools for different kinds of cables, generating various patterns such as robot brain patterns, electricity and lightning effects.
This short tutorial will take you through the process of how the artists generated cables for the game. The process involves a few stages:
- Generating the cable geometry suitable for simulation
- Using a finite element solver to get the sense of realism to the cables
- Deforming cable geometry in a way that doesn’t lead to artifacts
It was important to have nonintersecting cables so they had to be generated in a way that would guarantee that there is no interactions. In order to achieve that the artist has taken the bounding box of the original mock-up geometry and turned it into a volume, then scattered point clouds.
This is a basic setup for any path searching algorithm which allows to construct paths from a set of route points to the endpoints. The artist did some filtering which removed unnecessary edges.
The artist deleted the longer stages just based on the certain absolute value. He constructed a set of attributes necessary to drive the path searching algorithm, chose a set of points as starting points, released some noise to notify the initial locations for the path searching algorithm and to have a control in order to generate more cables later if necessary.
In order to generate cables in such a way that they don’t intersect the artist used SOP solver which constructs a cable by cable, step by step, and that’s the nature of the SOP solver which is rather handy for this particular task.
You basically use a path searching algorithm to construct path from the route points to the endpoints and convert this cable into a mesh which becomes a bounding object and selects points in the original point cloud.
Every cable selects a set of cables which it occupies and these cables get extracted from the input mesh, leaving you with a point cloud which has part of it extracted and that part is your first cable.
The second cable will be generated through the point cloud which has these first cable points extracted. It cannot grow through the space occupied by the original cable.
In this case there are 131 cables. Now we just need to clean up, get rid of the points which are not cables essentially, ending up with the splines generated by the path searching algorithm.
Then you turn them into the poly wire and that’s how you get your cables which are ready for the simulation and this set of cables is guaranteed not to intersect.