Large landscape performance problem

hi everyone,

So recently I rented a large EC2 instance on AWS in order to build my world machine world: a 32km tiled world with 4x4 tiles with a 4033 resolution.

I then imported it to my game. The result looks great, as an example:

But the performance is really awful:

So I tried a few debugging, here is Quad Complexity:

Now if I try to load one tile with stat unit and stat engine, I get this which is OK:

Performance is OK, but if I try to load the whole map:

I get 1 billion tris! At some point it even became a negative value (int overflow I assume) !

Now if I try to run this in standalone, since there is streaming, performance is really acceptable (although 60fps without trees and objects might be a little bit low)

The problem with streaming is that sometime the landscape will just pop. Sure, I could increase the Streaming Distance, but there would still be problems, like when the player will climb the highest mountain in-game.

Is there a way to improve performance without removing the landscape from the view? Like adding more LODs (b/c there’s only 3 LODs on the landscape I believe) ?

Thanks in advance

Try remove landscape static shadows, reduce light bounces on world settings, tweak shadow and lightning settings, and your landscape material settings. So not sure what can be done in regards to streaming.

Thanks for your reply. I don’t think it matters since performance is almost the same in an unlit environment

If your not using it already, you should use World Composition, setup an appropriate streaming distance so that all levels are not fully loaded, then generate LOD for each of the landscape levels, so that the LOD level will appear when the level is unloaded. That way the full amount of polys are not going to be rendered.

Thanks! That was indeed what I was looking for :slight_smile: I’ve set up one LOD for each level, and it created the static meshes and all but now how do I use them. I mean, I then tried to Launch Game, but the levels will still pop up just before camera - but with the static mesh first and then landscape. I tried creating a new streaming distance group with high distance but it doesn’t change anything.

I would need to take a look myself again, been a while since I played with it, but I believe there is also a streaming distance for the LOD levels that you will need to configure.

You said that you need to adjust these manually but it seems bit repetitive work and perfect for automation. Have you automated that yet?
I am trying to now code blutility function that call landscape optimizer c++ function. Then by sust calculating height derivates in grid should be enough for LOD bias calculations. With stationary directional light I could even calculate can landscape ever cast shadow for anything so I these components should not cast dynamic shadows.

have you compared the performance of tiled landscape vs. regular landscape?
in my experience ] tiled landscapes always give quite less performance because their LOD cannot seem to reduce that much (even tweaking the LOD settings there seems to be a different limit)

ALandscape* l = ...
FVector lightDir = ...
for (ULandscapeComponent* c : l->LandscapeComponents)
    bool canCastShadow = false;
    // Checks if any triangle of component can cast shadow from that light direction.
    FLandscapeComponentDataInterface CDI(c);           
    for (int32 y = 0; y < c->ComponentSizeQuads; y++)
        for (int32 x = 0; x < c->ComponentSizeQuads; x++)
            FVector center = CDI.GetWorldVertex(x, y);
            FVector up = CDI.GetWorldVertex(x, y + 1);
            FVector left = CDI.GetWorldVertex(x + 1, y);
            FVector upLeft = CDI.GetWorldVertex(x + 1, y + 1);
            FVector n0 = FVector::CrossProduct(up - center, center - upLeft);
            FVector n1 = FVector::CrossProduct(upLeft - center, center - left);
            canCastShadow |= FVector::DotProduct(lightDir, n0) < 0.f;
            canCastShadow |= FVector::DotProduct(lightDir, n1) < 0.f;
    c->bCastDynamicShadow = canCastShadow;

This little code snippet checks if landscape components are casting shadows for absolute no reason. In our map 90% of landscape components never contributed to dynamic cascaded shadows but costed hefty amount of performance.
I am now calling this using blueprint but with source code access you can make landscape edit tools to call these kind of optimization functions every time you have finished edits.

Isn’t the LOD feature for tiled world supposed to do that? About components, I imported it from wm so no way to change them.

Nice :slight_smile: Is there a way you could release that as a plugin please? Thanks

DO you have any idea where it is? I can’t find any guide on their doc. Thanks

I just would want to avoid human errors and avoiding to do this every time landscape changes.(Which causes more human errors if you forget to update those.)
My code that checks dynamic sun shadows is also something that is really hard for human eye to do. Component have thousands of triangles but that super simple code can do it in milliseconds for entire landscape. It’s also optimization that does not affect quality at all. For next step I am going to compare lod levels against the original. If the error is within certain treshold is safe to use lower lod. It’s shouldn’t be super hard. I will post the resulted code when I am done.

You could also go go stationary lights once you put in trees etc. It renders dynamic shadows close to the player and static shadows far from the player IIRC.

Sorry I have never done any plugins and I don’t really have time to start learning those now. That code snipped should be really easy to use and improve. I kinda wished that some one else would already have done something similar.

Still I would argue that in typical scene where you have single stationary directional light and large landscape you should use automation to skip all components that can’t cast shadows.(see code above) For LOD bias selection human interaction may be right choice.

Hi, did you find solution for this? I made 9km^2 landscape but suddently getting some crazy triangle count. Getting 100 million when lit, but only 4 million when lit but selected in viewport. And only 800k when in wireframe view mode.

Not using level streaming with this map since first it seemed to work smooth without. Very lost what causes that heavy triss count. Its there even when removing all meshes, foliage and grasslayer.