Junliang Zhang did a breakdown of his procedural terrain created with the HeightField workflow in Houdini and finished in UE4.
In case you missed it
Learn more about terrain production
Hello, my name is Junliang Zhang, I come from Shanghai, China. I am a technical artist currently studying an Entertainment Arts & Engineering program at the University of Utah.
I studied a lot of procedural techniques in Houdini, shader production, Python scripting for Maya, rigging, lighting, ray-tracing, and rendering in order to make tools that I can improve the entire workflow, make it faster and efficient. As a technical artist, I have to learn all of the tools used by others in order to improve the pipeline and create a bridge between programmers and artists.
In the past three years, I worked at a couple of game studios in the United States, such as 3BLACKDOT and Game Mechanics Studio (as a 3D Environment Artist and Lighting Artist). I participated in the production of Dead Realm (2017), No Way Out–A Dead Realm Tale (2018), and some unannounced projects.
Now, let's move on to the subject of the article. I hope you'll enjoy this breakdown!
Procedural Forest Terrain
Procedural terrain is one of my research topics at the university, and the goal of this project was to create a procedural terrain with Houdini, generate all the different terrain shapes in real-time in the UE4, and study the HeightField workflow from Houdini to UE4. I finished the whole scene only in two days.
Excellent reference/concept art is always a great way to get started when you want to create something visual. It will help you find a lot of inspiration and new ideas while designing or texturing. I spent much time collecting as many references as I could. Eventually, I ended up with creating “The Witcher 3 Blood and Wine” art style for the final pitch.
Workflow in Houdini
First of all, I entirely generated the landscape with Houdini HeightField Node. I added “HeightField Noise Node” - it allows you to create some basic landscape shapes and height that can work as a base.
Then, I used “HeightField Erode Node” to reduce some noise and make the ground partly flat.
Next, I added “HeightField Distort Node” for the landscape variation and fine details.
If you want to create some interesting patterns, you can use “HeightField Pattern Node” that can blend patterns into your terrain very well.
When the basic landscape shapes and height are finished, it’s time to make masks for the landscape material layers in UE4. I created three different masks for the mountain top, mountain rock, and the base ground by using “HeightField Mask by Feature Node”. This is a very cool node that allows you to adjust the masks in several different ways by changing “Mask by Slop” and “Mask by Height” parameters.
When the masks are ready, it’s time to name them by adding “HeightField Copy Layer Node”. This node allows you to name the landscape material layers that can be recognized directly by the UE4 landscape system. You can type the name in the Destination blank.
When you have two different mask layers, you can combine them by adding “HeightField Layer”. This node provides a lot of cool features that can be found on the right side of the property tab:
- Layer Mode which functions as Photoshop's layer mode
- Remapping that allows you to blend two different HeightFields by adjusting scale and offset
- Layers - here you can choose what layers will be composited (mask/height). used the "mask" for the layers and changed the layer mode to “ADD” so that I could merge two different masks created before.
Then, I invert the mask from HeightField Layer by using “HeightField Remap Node”. In this node, I set Output Min to 1 and Output Max to 0.
After that, I used “HeightField Copy Layer” again for the final base ground layer and named it “Base”.
Then, I created “Attribute Create Node” to connect everything with the UE4 Material Instance system. The name was changed to “unreal_material_instance”. I modified the Class and Type to be “Primitive” and “String”. Finally, I added a String - its path will depend on the UE4 project path.
Tip: How does instance material in UE4 connect with Houdini?
Create a landscape instance material in the UE4 project. Right-click your landscape instance material and choose “Copy Reference”.
Here is what you get:
If you want to work with “Attribute Create Node” in Houdini to connect the landscape instance material in UE4, you have to modify this. Here is the solution:
Copy it to the String blank on the right side of the property tab.
Now, it’s time to create scatters. I created a “HeightField Scatter Node” and named it “Tree”. The scattering node is based on the mask that you created before. I used SteepSlopes mask layer.
Next, I created a new tube and added a “Color Node” as input into the tree “Scattering Node”. I set Primitive Type to Polygon and changed the “Color Node” to the green color.
At the same time, you can adjust some of the scattering settings, such as Coverage, Outer Radius, and Range. For the tree scattering, you have to turn off Match Normals with Terrain box. Otherwise, the tree trunk will follow the terrain direction.
Tip: How to set the pivot point on the bottom of the tube instead of the center?
Incorrect pivot point position:
Correct pivot point position:
Create a new tube with Polygon Primitive Type.
Hold left mouse on the Height and drag into Center Y-axis. In Drop Action, choose Relative Channel Reference.
Add “/2” behind “ch("height")”.
Now, the pivot point of the tube is correct if you adjust the Height value.
In the end, export your HeightField Terrain as an HDA file (Houdini Digital Assets). If you want to adjust some of the settings in real-time in UE4, you can expose them in the following way:
Tip: How to expose your settings into HDA for UE4?
Go to Assets >> Edit Asset Properties >> Choose your HDA file. Open the Parameters tab. Select all of the settings under the Root, set Invisible and apply it. Drag any settings you want to expose into the root. Apply and Accept when you're finished.
You can import your HDA file into UE4 or any other engines that support Houdini.
For more info about Houdini Special Attributes and Groups, please check out SideFX Houdini Engine For Unreal documentation.
Workflow in Unreal Engine 4
First of all, I imported my HDA file into UE4. For the landscape textures, I used Quixel Megascans.
As you can see in the picture, you can adjust many Houdini parameters on the right side. At the same time, you can replace your trees in the Houdini Instanced Inputs. You can also add more mesh arrays in Houdini Instanced Inputs by pressing “+”.
For the landscape, the material setup is very simple. I created five different texture material functions and connected them to the Layer Blend Node.
I used “LandscapeGrassOutput” and “LandscapeLayerSample” for the grass in the UE4 landscape material editor. It's the most common way to generate ground grass based on the mask created from landscape material layers.
Material Function Breakdown
For the landscape tiling, I used “Collection Parameter”. It is a straightforward and fast way to adjust tiling textures instantly out of the material editor.
You have to make sure to set all of your textures to “Shared Wrap” in the Sampler Source. Otherwise, you will see black colors on your landscape. I also created the outputs of the textures, just in case. You can skip this step if you don't need it.
Landscape Creation: Houdini vs UE4
Unreal Engine 4 landscape tool has a lot of restrictions compared to Houdini. I feel that Houdini gives me a lot of advantages including iteration, procedural modeling, physical simulation, and HeightField. Besides, it supports most of the game engines and texturing tools nowadays. With HDA, I don't need to go back and forth between Houdini and the engine, and that's a big plus.
To recap, I used three different ways of scattering in Houdini and UE4 for this project.
- First: I created a “HeightField Scatter Node” for trees and wooden logs. The scattering tool is based on the mask that was generated from the previous “Mask by Feature Node”. At the same time, I created a simple tube model and added a green color for the placeholder of the tree. Once I imported my HDA file into the UE4, it was automatically recognized as a mesh. After that, I could replace the placeholder of the tree with the assets in the UE4 project.
- Second: I used the scattering tool in UE4 which is called the Procedural Foliage Spawner tool. It helps to generate a lot of random trees which is a very convenient tool for scattering foliage or trees in a UE4 landscape.
- Third: I used “LandscapeGrassOutput” and “LandscapeLayerSample” for the grass and flowers in the UE4 landscape material editor.
Here's a tutorial for that:
Create a “Landscape Grass Type”.
Add some Grass variety by pressing the “+” button.
Assign the static grass meshes in the Grass Mesh slots.
Go back to the landscape material editor, create “LandscapeGrassOutput” and “LandscapeLayerSample” nodes, and connect them. Assign the “Landscape Grass Type” that you created in “LandscapeGrassOutput Node”.
Rename your “LandscapeLayerSample Node” as the mask that was generated from the landscape material layers. The name has to be the exact same as in your “Layer Blend Node”. Otherwise, it won’t work!
Extra Materials Used
As mentioned before, I used some organic scanned materials and textures from Quixel Megascans library because I wanted to create a super realistic environment. I usually choose such textures that can easily blend with each other in terms of colors and texture details. If I run into a color contrast issue, I will crank up or down the RGB color in the instance material editor to make sure all of the terrain textures have nice transitions between each other.
For the clouds, I relied on a simple tutorial created by Tony Arechiga.
In conclusion, I want to say that Houdini has been used in AAA open-world games for many years. Its workflow allows creating not only landscapes but also more complicated things such as buildings, physical simulation, dynamic city layout, etc. I think that smaller game studios can benefit from using Houdini in their pipelines, at least partly.
Finally, I would like to thank 80.lv and all their readers. I hope you enjoyed this breakdown and found some helpful information and ideas for your future projects! If you feel stuck, I would suggest you go outside and explore the real world - it might give you inspiration! And enjoy life!
If you have any questions or feedback, you can find me here: