Houdini Heightfield Normal Map
Introduction
The most common way to generate a Houdini heightfield normal map is to convert your existing height field terrain to a mesh two times - one high res and one low res, and then bake you your normal map. The conversion to mesh likely takes quite a bit of RAM and the baking process is slower than the alternate approach presented here. A typical setup is shown on the right.
The alternate way to generate a Houdini heightfield normal map using vex and re sampling is memory efficient and extremely fast. First, we will go over the data flow. After that, we will wrap this all up in a Houdini Digital Asset (HDA) so that we can reuse this method whenever we wish. A big shout out to Paul Ambrosiussen for being a huge help on figuring this out.
Note: The new mapsbaker from SideFx Labs now also supports the described functionality.
Also if you want to skip the brain dump, just download and use the HDA.
Data Flow
Inspect all the parameter settings of the nodes above in the slider below.
Prepare Height Field
Use the copy height field layer node to create 3 new height field volumes called Cd.r, Cd.g and Cd.b
Down Sample Height Field
Fast and memory efficient. Create a low res version of the incoming height field.
Calculate Normals
All nodes in the right stream right are reference nodes, which means a change on the left side updates the right also.
Compute Normals
The difference between low and high res normals
COPS
Bring the result into cops and write map to disk
Important Notes, Tips & Tricks
Create a Houdini Digital Asset
Once you have the dialog, this is what I set mine to. I always follow this syntax when creating digital assets:
namespace::name::version
This is very useful, because it allows you to find your tools via Python and other pipeline tools that we will be building in the future.
In the basic tab, we set the outputs to 0 because this digital asset will only write a normal map to disk and will not output data back in the graph. I also found some icon to communicate that the tool will create a new image map.
For the parameters, you can drag and drop parameters into the parameter list from the nodes in our graph. Reference the image below.
- Down sample the height field - as this decreases, the more pronounced the normal map.
- The switch input - we will drive a switch between generating a normal map based on a flat heightfield and thus get a very pronounced/full normal map. The other mode will generate a differential normal between the higher res height field and the down sampled one. Create a toggle for this.
- Some controls over smoothing the normal map.
- These controls are created by dragging toggles into the parameter list. These toggles will be read by our vex code and based on the setting, flip X and Y direction of our normal map.
- The output path and the button to write the normal map is on the rop output node inside the COP2 network.
Organize the parameter interface.
Put the disable when expression on the export button { copoutput == "" } so that the export can not be triggered without a path.
Put the expression in the switch node so that we can drive it from our HDA UI. Click the "Select Input" label - this switches the parameter to expression mode. Type in - ch("../fromPlane") and hit enter.
Next select the "low_compute_normal" node and change the code to this:
vector dx, dy, n;
dx.x = 1;
dx.y = 0;
dx.z = volumeindex(1, 0, set(@ix, @iy, @iz));
dy.x = 0;
dy.y = 1;
dy.z = volumeindex(1, 1, set(@ix, @iy, @iz));
n = cross(dx, dy);
n = normalize(n);
@Cd.r = -n.x;
if (ch("../flipX")==0)
{
@Cd.r = n.x;
}
@Cd.g = -n.y;
if (ch("../flipY")==0)
{
@Cd.g = n.y;
}
@Cd.b = n.z;
Test your attributes while seeing the normal map update in the composite view - slightly faster than baking 🙂 Download the HDA below to drop it into your own Houdini environment. Pick it apart or straight up use it to generate your own Houdini heightfield normal map.