Notes on Procedural World Generation of Ubisoft’s Far Cry 5
procedural-generation
game-dev
notes
In this presentation from 2018, Etienne Carrier details the procedural pipeline developed for Far Cry 5 using Houdini and Houdini Engine, focusing on its objectives, tools, user workflow, underlying mechanics, and lessons learned during development.
- Introduction and Challenges
- Objectives of the Procedural Pipeline
- Procedural Tools Developed
- User Workflow: Filling an Empty Map
- Under the Hood: Houdini Engine and Data Exchange
- Cliff Tool: Detailed Breakdown
- Biome Tool: Populating the World with Life
- Lessons Learned
- Conclusion
Source Material
Introduction and Challenges
- Etienne Carrier, Technical Artist at Ubisoft Montreal (3 years), presents the procedural pipeline developed for Far Cry 5.
- Challenge: Terrain undergoing constant changes during the project’s 2.5-year development.
- Manual content placement (e.g., forests) becomes incoherent with each terrain iteration.
- Repainting content manually after each terrain change is tedious and difficult to maintain consistency across a large world with multiple users.
- Locking terrain early is unrealistic as iterations are crucial for game quality.
Objectives of the Procedural Pipeline
- Develop a macro management tool to:
- Fill the world with natural-looking content.
- Ensure content consistency with terrain topology, adapting to changes (e.g., forest distribution remaining coherent despite terrain adjustments).
- Automation:
- Utilize Houdini, Houdini Engine, and nightly builds on build machines to fully refresh the world daily.
- Build machines process different map sections, ensuring up-to-date world data each morning.
- Deterministic Generation:
- Ensure the generation yields identical results with the same inputs, regardless of the build machine used.
- This is crucial for seamless map junctions and nav mesh generation.
- User-Friendliness:
- Provide in-editor tools for on-demand procedural generation alongside the nightly builds.
Procedural Tools Developed
- Expanded beyond the initial mandate of biome distribution to include:
- Freshwater Tools: Generate lakes, rivers, streams, and waterfalls.
- Fence and Power Line Tools: Create fences and power lines along splines.
- Cliff Generation: Generates cliffs on steep terrain.
- Biome Tool: Spawns vegetation throughout the world.
- Fog Density Map Generation: Creates a 2D map based on terrain topology and content placement to influence the fog shader.
- Wall Map Terrain Generation: Generates a low-detail terrain representation for the world map, including miniature trees.
User Workflow: Filling an Empty Map
- Terraforming:
- Initial world machine pass followed by artist-driven terraforming using in-editor tools.
- Freshwater Network:
- Artists lay down a network of curves and splines to define rivers and other water bodies.
- Procedural generation creates the water surface, waterside assets, and terrain texturing based on spline parameters (e.g., width).
- Cliff Generation:
- Tool automatically generates cliffs based on terrain slope, with minimal user input.
- Includes features like exclusion masks for finer control.
- Often handled by nightly builds, relieving artists from frequent manual generation.
- Vegetation (Biome Painter):
- Artists paint sub-biomes (e.g., forest) using a painter tool.
- Main biomes automatically distribute vegetation (grass, trees) based on terrain data and sub-biome information.
- Recipes react to water proximity, altitude, and cliff erosion lines, spawning appropriate assets.
- Customization:
- Artists can override the natural distribution by clearing areas with grass sub-biome and adding elements like roads (using splines).
- Road generation clears vegetation and adds roads, requiring some manual asset placement (houses, vehicles).
- Biome painting can be further refined to create features like driveways using terrain textures.
- Forest sub-biome can be repainted to add trees around specific locations.
- Non-Destructive Workflow:
- Terrain can be adjusted at any time, requiring a refresh of affected procedural tools (e.g., cliffs, biomes).
- System maintains coherence and updates content placement automatically.
- Fence and Power Line Placement:
- Fences are generated along splines with fence type specified as an attribute.
- Power lines connect electric poles placed at spline control points.
- System supports multiple power line types and automatically handles snapping and transformer placement.
- Biome tool automatically clears vegetation obstructing power lines.
Under the Hood: Houdini Engine and Data Exchange
- Houdini Engine within Dunia enables seamless data exchange between Houdini and the engine.
- Inputs from Dunia to Houdini (via Python script):
- World information (name, size).
- File paths for assets and data.
- Terrain sector information (area to generate).
- Splines and shapes with metadata on geometry attributes (e.g., fence type on a fence spline).
- Inputs from Disk (file paths provided by Dunia):
- Height maps.
- Biome painter data.
- SPNG and 2D terrain masks.
- Houdini geometry from previously generated tools.
- Primary Input: The terrain itself, as generation is linked to specific terrain areas (sectors).
- Terrain Subdivision:
- Sectors are the smallest unit (64x64 meters), defining the minimum area for procedural generation.
- Baking Procedural Data:
- Users select a generation area:
- All (everything loaded in the editor).
- Local map section or sectors (under the camera).
- Frustum (sectors visible from the camera).
- Users select a generation area:
- Outputs from Houdini to Dunia:
- Entity point cloud (vegetation, rocks, collectibles, decals, VFX, etc.).
- Terrain textures.
- Terrain height maps.
- 2D terrain data (RGB or grayscale).
- Procedurally generated geometry.
- Terrain logic zones (IDs for post-processing and fog presets).
- Data Transfer: Outputs are saved as buffers in a specific format for efficient loading by the editor, avoiding large memory transfers.
- Tool Interconnectivity:
- Procedural generation is sequential (freshwater, cliffs, biomes, etc.).
- Tools export data to influence subsequent tools (e.g., freshwater generates a water mask used by the biome tool).
Cliff Tool: Detailed Breakdown
Previous Tech and Motivation
- Far Cry 4 and Primal had no dedicated cliff tech, relying on terrain and placed rocks.
- Worlds were designed to minimize large cliff surfaces due to visual limitations and the cost of manual rock placement.
- Far Cry 5 featured larger and more prominent cliffs, necessitating a new approach.
Cliff Tool Inputs and Geometry
- Terrain slope is the primary input.
- Surfaces below a defined slope threshold are deleted, creating the cliff input geometry.
- Cliffs serve as a visual cue for impassable terrain.
- Remeshing is applied to eliminate stretched quads on slopes, resulting in uniform triangles.
Stratification
- Geological stratification (horizontal lines in sedimentary rock) is simulated.
- Tool slices the input geometry into strata chunks with random thickness.
- Each strata receives a unique ID for color variation (debug view).
- Strata angle is controlled by user-painted RGB input on the terrain, with four presets available in the editor.
- Noise is used to split the cliff surface into two groups, each stratified with a different seed to break up perfect lines and create more natural patterns.
Geometry Generation and Export
- Strata are extruded with varying thickness and displaced using displacement maps.
- Triangle count reduction is applied for optimization.
- Geometry is split into individual meshes per sector (64x64 meters) for improved loading and streaming.
Terrain Shading and Data Transfer
- Cliffs are shaded using the terrain shader, inheriting textures from the terrain below.
- To avoid texture mismatch, cliff textures are transferred to the terrain beneath the extruded cliff mesh.
- Cliff mask and strata attributes are raycast onto the terrain.
- Strata attribute generates a color layer for macro tint variation, even when cliff mesh is unloaded at a distance.
- Cliff mask is extended using a flow simulation to create an erosion effect, retaining the original strata color.
- Crumbled rock entities are scattered on the erosion area and exported as a point cloud.
- Terrain texture IDs are generated from the erosion mask, using noise to blend two cliff textures for tiling variation.
Vegetation on Cliff Ledges
- Upward-facing polygons on cliffs are identified as potential vegetation areas.
- Raycasting checks for clearance above the surface.
- Trees and other vegetation are spawned on viable cliff ledges.
Cliff Tool Exported Data
- Cliff geometry with collision information.
- Point cloud for rocks and ledge vegetation.
- Terrain texture IDs.
- Cliff color layer for the terrain.
- Cliff mask.
Biome Tool: Populating the World with Life
Initial Steps
- Terrain is generated from the height map.
- Abiotic data (physical features) is calculated:
- Occlusion.
- Flow map.
- Slope.
- Curvature.
- Illumination.
- Altitude, latitude, longitude.
- Wind vector map.
- These attributes form the basis for biome recipes.
- 2D data from Dunia is imported:
- Biome painting (user input).
- Procedural data from previous tools (freshwater, roads, fences, power lines, cliff masks).
Main Biomes and Sub-Biomes
- Main biomes cover most of the world (75-85%).
- They automatically determine sub-biome distribution (e.g., forest vs. grassland) based on abiotic terrain data, creating natural macro-level patterns.
- Main biomes also handle specific rules:
- Replacing forest with grassland where power lines are present.
Sub-Biome Recipes
- Sub-biomes are processed sequentially.
- Each recipe contains ingredients (trees, saplings, bushes, grass).
- Core of each recipe is the generate-terrain-entities HDA (Houdini Digital Asset), responsible for:
- Vegetation scattering.
- Terrain attribute modification.
- Defining viability for each species.
Viability and Species Competition
- Viability determines the likelihood of a species growing at a specific location, based on favored terrain attributes.
- Species with the highest accumulated viability at a location “wins.”
- Example:
- Species A favors a specific occlusion range (power of 1).
- Species B favors a specific flow map range (power of 2).
- Species B will dominate where the flow map value is sufficiently high.
- Viability radius determines the influence area of a species, preventing other species from growing too close.
- Priority and priority radius allow finer control over species interaction:
- Priority is evaluated first.
- If priorities are equal, viability is considered.
- Example: Trees (priority 10) can have a smaller priority radius, allowing bushes (priority 0) to grow closer while still preventing overlap with other trees.
Combining Terrain Attributes for Natural Patterns
- Mixing various terrain attributes allows for complex vegetation patterns and fluctuating viability.
- Example: Combining occlusion, altitude, flow map, and noise to create specific growth conditions.
- Exclusion masks from previous tools (water, cliffs, roads) can be incorporated.
Controlling Asset Size
- Asset size is linked to viability, allowing for natural size variation within a species.
- Example: A conifer species can have multiple size variations (50m, 40m, 30m, etc.), each assigned to a specific viability range on the terrain.
- This creates a tapering effect at forest edges, with smaller trees at the periphery.
- Scaling percentage for each size prevents a staircase effect, allowing smooth transitions between sizes.
- Random scale can be added for further variation.
- Each size can have multiple variations (e.g., a dead tree variant), randomly selected with controllable weights.
Forest Canopy and Ecological Succession
- Age parameter (signed distance field from viability data) influences size distribution, mimicking forest canopy and ecological succession.
- It can be added, multiplied, or interpolated with viability to control its influence.
- Age maximum distance controls the depth of the forest border tapering effect.
- Age ramp can be used to profile the overall forest shape.
Scattering Density
- Density ramp controls the scattering density based on size, age, or viability.
- It prevents overlap issues with larger assets and manages performance by controlling asset numbers.
- Terrain attributes (illumination, slope aspect) can be mixed into the density ramp for finer control (e.g., reduced density on poorly lit slopes).
Instance Tinting
- Biomes with high color variation are achieved by tinting individual instances.
- Gradient color ramps are driven by viability, age, or terrain data.
- Example: Water signed distance field drives grass color variation near water bodies.
Instance Rotation
- Asset rotation is primarily based on terrain slope, aligning the forward axis with the slope.
- This allows for effects like grass leaning towards water due to the shore’s slope.
- Other options include:
- Flat horizontal alignment.
- Wind vector map alignment (e.g., for wheatgrass).
- Rotation jitter and offset on all axes for random variation.
Terrain Modification by Scattered Assets
- Scattered assets can influence terrain properties.
- Four types of terrain data can be modified:
- Terrain deformation: Height map adjustment (e.g., raising terrain around tree trunks).
- Terrain textures: Applying specific textures underneath assets (e.g., tree roots).
- Terrain data output (mask): Generating masks for reuse by other species (e.g., spawning rocks around specific trees).
- Terrain color: Blending colors with terrain textures (e.g., simulating terrain humidity).
- Each data type has independent signed distance field settings for controlling the influence area.
Terrain Deformation
- Masks generated from scattered assets can be combined with terrain data to control deformation.
- Example: Preventing terrain deformation near roads using the road mask.
- Displacement height deforms the terrain (e.g., raising it by 1 meter around trees).
Terrain Textures
- Masks generated from scattered assets determine terrain texture application.
- Example: Applying a “root” texture underneath trees.
- Texture selection is dynamically fetched from the engine via Python script.
- Mask scale controls the area of influence for each texture.
Terrain Data Output and Inter-Species Dependency
- Terrain data attributes (masks) can be generated from scattered assets and reused by other species.
- Example:
- Ponderosa tree outputs a viability mask.
- Forest rock species uses the Ponderosa viability mask to drive its spawning behavior, creating a dependency between the two.
Terrain Color and Humidity Simulation
- Terrain tint is generated and mixed with organic terrain textures, similar to the cliff strata color.
- This creates color variations (e.g., dry brown to lush green) without increasing the number of terrain textures.
- Neutral gray color allows for both darkening and lightening of the terrain texture.
- Terrain color and texture variations can transpire through grass, controlled by a mask on the grass asset.
Biome Tool Exported Data
- Entity point clouds.
- Terrain texture IDs.
- Terrain height map.
- Terrain color.
- Forest mask (used by fog and wall map tools).
Lessons Learned
- Responsibility:
- Procedural tools offer immense control over performance, gameplay, and art, requiring careful consideration of their impact.
- Balancing art direction (e.g., dense forests) with gameplay needs (e.g., AI navigation) is crucial.
- Elegant Design:
- Tools should open up possibilities and be adaptable for various scenarios.
- The biome tool’s flexibility is highlighted as an example.
- Simplicity:
- Avoid over-engineering.
- Strive for simple and elegant designs through iterative development and refinement.
- User Feedback:
- Listen to user needs and preferences.
- Sometimes manual control is preferred over automation (e.g., riverbed carving).
- Flexibility:
- Adapt to changing requirements and be prepared to deviate from initial plans.
- Balance:
- Find the right balance between control and automation.
- Excessive automation can lead to issues, while excessive manual control can be time-consuming and difficult to manage.
Conclusion
- The procedural pipeline significantly enhanced Far Cry 5’s development, providing efficiency, control, and natural-looking environments.
- Houdini played a crucial role in achieving the project’s goals.
- Collaboration and iteration were key to the pipeline’s success.
- The modular and flexible design allows for future adaptation and reuse in other projects.
About Me:
I’m Christian Mills, a deep learning consultant specializing in practical AI implementations. I help clients leverage cutting-edge AI technologies to solve real-world problems.
Interested in working together? Fill out my Quick AI Project Assessment form or learn more about me.