Back to Forge Log
Project FrontierUnreal Engine 5World PartitionTechnicalProcedural Generation

Project Frontier: Continental-Scale World Partition

4 min read
Project Frontier: Continental-Scale World Partition

The Scale Problem

"Open world" usually means 8km×8km. Project Frontier targets continental scale — 10,000km×10,000km of procedural terrain, streaming seamlessly. That's not a level. That's a planet.

Traditional world composition (level streaming, manual landscape tiles) collapses at this scale:

  • Tile count: 195,000+ 512m tiles
  • Memory: 40GB+ just for heightmaps at 1m resolution
  • Authoring: Impossible to hand-place content

We needed procedural generation that streams, not pre-baked assets.


World Partition + Procedural = Infinite Streaming

UE5's World Partition wasn't built for procedural — it assumes authored levels. We extended it:

1. Virtualized Heightfield Generation

Instead of storing heightmaps, we store generation parameters per tile:

struct FTerrainTileParams {
    uint64 Seed;                    // Deterministic per-tile
    FVector2D WorldPosition;        // km coordinates
    float BiomeWeight[8];           // Biome blend weights
    float TectonicUplift;           // Geological history
    float ErosionIterations;        // Hydraulic simulation depth
    uint32 FeatureHash;             // POI placement seed
};

Each tile generates on-demand on a background thread. The heightfield is a compute shader that runs in ~2ms per tile on RTX 4080. Zero disk I/O for terrain.

2. Hierarchical LOD That Actually Works

World Partition's HLOD system + Nanite landscapes = infinite draw distance.

LOD0 (0-500m)    : Nanite landscape, 1m resolution, full displacement
LOD1 (500m-2km)  : Nanite landscape, 4m resolution, simplified displacement  
LOD2 (2km-8km)   : Nanite landscape, 16m resolution, no displacement
LOD3 (8km-32km)  : Procedural mesh proxy, 64m resolution
LOD4 (32km+)     : Impostor billboard + atmospheric scattering

The transition is imperceptible because Nanite handles the geometry LOD, and our custom material LOD matches the silhouette.

3. Biomes as Compute Shaders

8 biomes, each a material function driven by the same parameters:

| Biome | Generation Cost | Key Features | |-------|-----------------|--------------| | Boreal Forest | 1.8ms | Needle-leaf canopy, permafrost cracks | | Temperate Deciduous | 2.1ms | Broadleaf clusters, seasonal color LUT | | Tropical Rainforest | 3.4ms | Multi-layer canopy, epiphyte geometry | | Arid Steppe | 1.2ms | Rocky outcrops, sparse grass clusters | | Alpine Tundra | 1.5ms | Scree fields, glacial striations | | Wetlands | 2.8ms | Water simulation, mangrove roots | | Volcanic | 2.3ms | Lava flows, ash deposits, fumaroles | | Coastal | 1.9ms | Tidal zones, dune formation |

Biome blending happens in the compute shader — no texture lookups, pure math. Transitions are geological, not painted.


Hardware Lumen on Planetary Scale

Lumen's software ray tracing on landscapes is expensive. At continental scale, we needed hardware RT (RTX) for the near field, signed distance fields for mid, atmospheric scattering for far.

The Three-Zone Lighting Model

Zone A (0-1km)     : Hardware RT GI + Reflections (Nanite landscape)
Zone B (1-10km)    : Mesh Distance Fields + Probe Volumes
Zone C (10km+)     : Precomputed Atmospheric Scattering LUT

Zone A uses Lumen's hardware ray tracing on the Nanite landscape mesh — 1 bounce GI, 2 bounce reflections, 60fps on RTX 4070.

Zone B switches to signed distance fields generated from the same heightfield compute shader. Zero extra memory — the SDF is a byproduct of displacement.

Zone C is pure atmospheric scattering (O'Neill/Bruneton model). The terrain is the atmosphere at this distance.

Dynamic Time-of-Day Without Rebuilding

The entire pipeline is time-of-day aware. The compute shader takes SolarAngle as a parameter:

float3 ComputeTerrainColor(float2 uv, float SolarAngle, float3 BiomeAlbedo) {
    float3 normal = ComputeNormal(uv);
    float NdotL = saturate(dot(normal, SunDirection(SolarAngle)));
    
    // Biome-specific BRDF
    float3 diffuse = BiomeAlbedo * NdotL;
    float3 subsurface = BiomeSubsurface(uv) * (1.0 - NdotL) * 0.3;
    
    return diffuse + subsurface;
}

No light baking. No time-sliced updates. Change the sun angle → terrain relights instantly.


POI Placement: Poisson Disc on Steroids

Points of interest (ruins, caves, resource nodes, anomalies) use hierarchical Poisson disc sampling:

  1. Macro (100km grid): Continental landmarks — megastructures, impact craters
  2. Meso (10km grid): Regional clusters — ruin cities, cave networks
  3. Micro (1km grid): Local POIs — individual buildings, resource nodes
  4. Nano (100m grid): Detail props — debris, vegetation clusters

Each level uses the parent's hash as seed — deterministic, infinite, no storage.


Early Access Metrics (Internal)

| Metric | Target | Current | |--------|--------|---------| | Terrain generation (tile) | < 5ms | 2.3ms | | Streaming latency (SSD) | < 50ms | 18ms | | Memory (100km radius) | < 4GB | 2.1GB | | FPS (RTX 4070, 1440p) | 60 | 72 | | Pop-in visibility | None | < 0.1% frames |


The Sandbox Philosophy

Project Frontier isn't a game you finish. It's a world you inhabit. The technology serves one goal: never remind the player they're in a simulation.

No loading screens. No tile boundaries. No "you cannot go further." The continent is the game.

Dispatch from the engine room — Frontier world systems lead