Tool overview

A road-generation HDA built in Houdini. Editing a spline in Unreal Engine controls the road path and wheel-rut shape. Rocks, trees and gravel can be configured around the road, with adjustable asset types, counts and scale. When the path changes, the terrain is raised, flattened or carved to follow it, and environment assets move out of the way so the road stays integrated with its surroundings.

The HDA and environment asset settings in Unreal Engine.
Scene result.
Scene result.

Road path and terrain projection

Draw the road path with a Curve node and sweep it into geometry with a diamond-shaped cross-section. Project it onto the terrain with HeightField Project and combine it with the original terrain using a Minimum operation, producing a base road surface that blends into the landscape.

Curve and Sweep build the road cross-section.
The road and its raised edges after projection.

Directional terrain and vegetation masks

To match the south-low, north-high slope in the reference, a directional gradient mask is generated on the base terrain, with a slider controlling where the folds appear so the ground rises toward the north. The mask is combined with HeightField Pattern to add rhythmic undulation. Vegetation only grows on higher, gentler ground, so HeightField Mask by Feature uses slope and elevation to build the tree mask, excluding steep slopes and low areas.

Directional gradient mask and terrain undulation.
View VEX code · heightfield_wrangle2

Builds the directional gradient mask: maps the terrain from one side to the other into 0–1, then shapes the gradient with a ramp to control where the ground rises.

heightfield_wrangle2.parmVEX
float ramp = fit( @P.z, -200, 200, 0, 1 );

@mask *= chramp( "ramp", ramp );

Tree and rock distribution

Directional scattering is driven by the mask formed by the road and its raised edges. To place large rocks at the mask centre and smaller shrubs and gravel toward the sides, instance scale is not set in Scatter; Copy to Points with a VEX expression scales instances by the mask gradient so size falls off smoothly from centre to edge. Large rocks change the ground material, so the same approach creates separate material regions for them, widened with HeightField Expand Mask to separate them from the sand. Smaller stones, shrubs and grass are then scattered around the rocks for extra detail.

Tree distribution mask and scattering.
Material regions around large rocks.
Node networks for rocks and nearby vegetation.

Grass distribution and mask integration

Grass uses the inverse of all previous masks to avoid trees, rocks and shrubs, then is blurred, smoothed and slightly shrunk to break up hard edges for a natural, random coverage. Finally, all points and masks are merged and checked, redundant areas removed, and material IDs and mask layers are reassigned and renamed to match the Landscape blend material in Unreal Engine 5.

Grass distribution mask.
All masks and points merged to match the Landscape material layers.

Demonstration video

Road tool demo

Technical content adapted from the author’s portfolio and project files.

Next projectSci-fi metal surfaces