I don´t know if you already resolved the problem, its already a bit ago.
What i´ve done is creating a quad tree, each node represents two different quality levels, the full detail and one of the parent (if not all 4 children can be displayed at full, then the parent mesh can be displayed)
Most if the stuff is done in async, as this was killing my performance (generating vertices, triangles, normals etc.)
After the task is done, i can create one to two new nodes per frame, with rock solid 120 fps.
Async snipped (reduced):
TFuture<FLandscapeGenerationTask> GenerationFuture = Async<FLandscapeGenerationTask>(EAsyncExecution::ThreadPool, [this]
{
FLandscapeGenerationTask GenerationTask;
GenerationTask.FullMesh = GenerateLandscapeMeshSegment(GenerationTask, MeshTesselation);
GenerationTask.ParentMesh = GenerateLandscapeMeshSegment(GenerationTask, MeshTesselation / 2);
return GenerationTask;
});
ProcessingTasks.Add(CallbackNode, GenerationFuture.Share());
A few numbers:
Numbers of vertices: 30 per site, 900 total
Numbers of tris: around 5000
Numbers of UV, normals, tangents: each 900
if i split the tree, each children has only the half site length (4 children), so i double the quality with each deeper level in the tree.
At level 1 its 900 vertices, if you would replace the level 1 with the level 8 children (4096 of them), i end up having 1920 vertices for one site and 3686400 overall.
But not all are displayed all the time for sure, its only around the player based on the distance.
Hint: Make the collision only were you need them, and set:
NewMesh->SetCollisionUseAsyncCooking(true);
NewMesh->CreateMeshSection(0, MeshData, true, EUpdateFrequency::Infrequent);
NewMesh->SetMaterial(0, Quadtree->Material);
NewMesh->LastRenderTime = GetWorld()->GetTimeSeconds();
NewMesh->RegisterComponent();
to have async cooking of collision (before creating a new section or registering the compontent)
Cheers,
Maik