Repository navigation
HLOD And World Partition
Hierarchical Level of Detail (HLOD) generation and world partition grid for efficient rendering and streaming of large open worlds.
Source: SparkEngine/Source/Engine/HLOD/HLODSystem.h
Not wired (2026-09):
HLODSystemis no longer initialized by the gameplay lifecycle and has no per-frame producer or renderer consumer. The API below describes the class; nothing in the shipped engine drives it. See Stub and Abandoned Features.
The HLOD system addresses two core problems in large-world rendering: draw call reduction at distance and memory management through spatial streaming. It combines hierarchical LOD generation (merging nearby entities into simplified proxy meshes) with a uniform world partition grid that loads and unloads cells based on viewer distance.
At build time, HLODBuilder groups entities into spatial clusters using grid-based binning. Each cluster gets multiple LOD representations: LOD0 (original meshes), LOD1 (merged geometry with reduced draw calls), LOD2 (decimated proxy mesh), and LOD3 (billboard imposters). The system selects the appropriate LOD level based on the cluster's screen-space size.
At runtime, WorldPartitionGrid divides the world into uniform cells. As the viewer moves, cells within the load radius are streamed in and cells beyond the unload radius are released. The hysteresis between load and unload radii prevents thrashing at cell boundaries.
HLODSystem (singleton)
|
+-- HLODBuilder (build-time)
| +-- EntityEntry[] --> BuildClusters() --> HLODCluster[]
| +-- GenerateProxy(cluster, targetTris) --> HLODProxy
| +-- GenerateImposter(cluster) --> HLODProxy (billboard)
|
+-- WorldPartitionGrid (runtime)
| +-- WorldBounds + cellSize --> uniform grid
| +-- AssignEntity(id, pos) --> place in cell
| +-- UpdateStreaming(viewerPos, loadR, unloadR)
| --> load nearby cells, unload distant cells
|
+-- LOD Selection
LOD0 (full detail) --> screen size > 10%
LOD1 (merged) --> screen size > 3%
LOD2 (proxy) --> screen size > 1%
LOD3 (imposter) --> screen size < 1%
| Class | Description |
|---|---|
HLODSystem |
Singleton managing HLOD generation and world-partition streaming |
HLODBuilder |
Build-time tool for generating clusters and proxy meshes |
HLODCluster |
Group of spatially-close entities with per-LOD triangle counts |
HLODProxy |
Simplified mesh data representing a cluster at a specific LOD |
WorldPartitionGrid |
Uniform grid that partitions the world into streamable cells |
WorldPartitionCell |
Single cell with entities, load state, and priority |
HLODBuildSettings |
Configuration for cluster size, triangle targets, and thresholds |
auto& hlod = Spark::HLOD::HLODSystem::GetInstance();
hlod.Initialize();
// Populate entity data
Spark::HLOD::HLODBuilder& builder = hlod.GetBuilder();
std::vector<Spark::HLOD::HLODBuilder::EntityEntry> entities = {
{1, {100, 0, 200}, 5.0f, 1000},
{2, {110, 0, 205}, 3.0f, 800},
{3, {500, 0, 500}, 10.0f, 2000},
};
Spark::HLOD::HLODBuildSettings settings;
settings.clusterSize = 128.0f;
settings.lod1TargetTriangles = 5000;
settings.lod2TargetTriangles = 500;
builder.BuildClusters(entities, settings);
hlod.BuildHLOD(settings);auto& grid = hlod.GetGrid();
grid.Initialize({{-2048, 0, -2048}, {2048, 512, 2048}}, 256.0f);
// Assign entities to cells
grid.AssignEntity(1, {100, 0, 200});
grid.AssignEntity(2, {110, 0, 205});
// Per-frame: update streaming based on camera position
hlod.Update(cameraPosition);
// Get loaded cells for rendering
for (const auto* cell : grid.GetLoadedCells())
{
// Render entities in cell
}| Method | Description |
|---|---|
Initialize() |
Set up with default radii (load=1000, unload=1500, view=2000) |
Update(viewerPos) |
Advance streaming and LOD selection |
BuildHLOD(settings) |
Generate HLOD clusters from builder data |
GetVisibleClusters(pos, dist) |
Query clusters within view distance |
SetLoadRadius(r) |
Set cell streaming load radius |
SetUnloadRadius(r) |
Set cell streaming unload radius |
| Method | Description |
|---|---|
Initialize(bounds, cellSize) |
Create the grid over world bounds |
AssignEntity(id, pos) |
Place an entity in the appropriate cell |
RemoveEntity(id) |
Remove an entity from its cell |
UpdateStreaming(pos, loadR, unloadR) |
Load/unload cells by distance |
GetLoadedCells() |
Get all currently loaded cells |
GetCellAt(pos) |
Look up the cell at a world position |
| Method | Description |
|---|---|
BuildClusters(entities, settings) |
Group entities into spatial clusters |
GenerateProxy(cluster, targetTris) |
Create a simplified proxy mesh |
GenerateImposter(cluster) |
Create a billboard proxy |
| Setting | Default | Description |
|---|---|---|
clusterSize |
128.0 | Grid cell size for HLOD clustering (world units) |
lod1TargetTriangles |
5000 | Triangle budget for LOD1 merged meshes |
lod2TargetTriangles |
500 | Triangle budget for LOD2 proxy meshes |
imposterResolution |
256 | Texture resolution for billboard imposters |
imposterDirections |
8 | Number of capture directions for imposters |
screenSizeThresholdLOD1 |
0.10 | Screen fraction threshold for LOD1 |
screenSizeThresholdLOD2 |
0.03 | Screen fraction threshold for LOD2 |
screenSizeThresholdLOD3 |
0.01 | Screen fraction threshold for LOD3 |
| Load radius | 1000.0 | Distance to begin streaming cells |
| Unload radius | 1500.0 | Distance to release streamed cells |
- Seamless Area Manager -- Higher-level area streaming that works alongside world partition
- World Origin System -- Floating-point origin rebasing for large worlds
- Render Graph -- Manages render passes including HLOD proxy rendering
Published from 2b03dc797148. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers