Procedural Roads in TerrainFX

During the final weeks of the year at TGA I was working with creating a digital asset that would allow us to procedurally place out light chains and various spline assets in our maps. This project builds on the methods I learnt during that project.

road_step1.png

This project was completely unplanned and arose more out of interest than need. Primarily I will focus on breaking down what I did to create a road that adjusted its underlying terrain to match. It all starts with two parts, a terrain, and a curve. To make it easier to draw the curve along the terrain you have, it is easiest to branch off and convert the heightfield to geometry. Next the curve is resampled and each point has its y-vector replaced with the global y-axis vector (so that the road surface points up). After that a line is copied to each point and stitched together to a ribbon that will make up the main road geometry.


road_step2.png

At this point the node tree into two streams. In one stream I handle generating the actual road geometry while in the other I handle the creation of the road shoulder, something that I use to later create masks for the terrain, trees, and to generate points along the road where I can place railings or snowpoles.


road_step3.png

Once the road spline has been treated and all the pre-requisites are setup its time to start working with a part of TerrainFX called masks. Using the road shoulder mesh I can create a mask that follows along the curve, but is wider than the actual road mesh (this can be adjusted through a simple slider). This mask is the basis for everything that follows. On the left image you can see the mask on the heightfield as it is after projecting it from the curve's mesh, and on the right is the mask that I later use to place out trees in the environment. All these change dynamically when you modify the curve, and to my surprise when creating this, it does not take too long to recalculate.


Disregarding my silly box names; above is the core of the dynamic road setup, the part where all the masks are generated and applied. Because of how Houdini works I can use the mask I get and create even more of them to use when choosing where I want to have trees. I can then scatter points into those masked areas dynamically and copy instanced trees out to each one.


road_step5.png

Finally its as simple as merging together the terrain, road mesh, and trees into a single output node, or separate if you want to process them even more. The heightfield can be baked to a texture and used in Unreal, the road mesh can be exported and imported in Unreal as well. The only thing I have yet not looked into how to migrate to an engine are the trees. However most current game engines have solutions for painting out foliage, and as such it would not be needed unless one wanted to set up a completely automated pipeline for making maps in Houdini.