UE5: Lumen + Landscape LOD = unplayable framerates

I’ve noticed once I introduced landscapes to my UE5 projects, performance took a huge hit. After spending a large amount of time tweaking all possible settings to distill the source of the slowness, it seems this issue is seeded in landscapes dynamic LOD having terrible performance with Lumen.

Simply having a base level with a 4033 x 4033 landscape with the most basic of materials and a directional light.

Landscape Max LODLevel set to “-1” (max avaiaible)
Holding still: 56 FPS
Moving camera looking around: 17 FPS

Landscape Max LODLevel set to “1” (Very weak LOD, resulting in way more vertices being drawn)
Holding still: 56 FPS
moving camera looking around: 54 FPS

If i change the global illumination away from Lumen (Or set it to be at medium quality), I don’t get the movement performance hit with landscape Max LODLevel set to “-1”.

So, it appears that the landscape LOD tessellation is triggering a lumen to do a lot of work, basically making these 2 major pieces of the engine incompatible in UE5. This seems to be a rather large issue, is there something I’m missing?

2 Likes

Bump

up

Any feedback or plans on making these compatible? I know in EA 5 landscapes were not affected by lumen, and they clearly did work to support them. It would be shocking if they just stop here.

Up.

Am I the only one using decent sized landscapes in UE5?

click landscape in the outliner, cast shadow, uncheck… thats the only thing I can think of as problems i have had with landscape.
It seems the old method was to put a plane under the landscape and set it to cast shadow untrue and leave the cast shadow on on the landscape, but my testing showed no increase in performance this way. Ive ran a 20k that was populated with veg and no partitioning or level instancing or anything at 60-80 fps, with landscape cast shadow on like 30-40

All I can say is that I experience the same.

Landscape w/material + virtual heightfield. Runs ~140fps in 4.26.2

4.27 it drops to ~85fps

5.02 w/lumen and nanite I’m in the 60’s. No changes to the code or the materials, just a straight up import into the new version. I did rebuild the shader-caches and whatnot, working backwards, but no matter what I update the core performance is just, I hate to say it, crap.

Given the performance disparity, Unreal is burning the cycles I would have burned to populate my world, hence, literally unplaybale for me in the newer versions…

It’s a 2k heightmap on a landscape 2033x2033 units in size. It’s nothing special, not even any grass and it still tanks in the newer version.

Giving this another bump. Still having to use the maxLODLevel 1 work around which is resulting in a very large number of verts being rendered.

When using the heighmesh, I set my landscapes to not render at all in the main-pass; they don’t need to. The normals/lighting is applied on the heightmesh after sampling the material from the RVT.

Collision is the only thing you really need from the landscape, that and it’s role as an outsized render-target for the VHFM.

I get the same slowdown if I have the landscape set to “From Virtual Texture” in draw in main pass. I don’t understand setting it to “Never”, as it will then simply not render the landscape. What am I missing?

Landscape material outputs:
→ Runtime virtual texture output carries whatever you need to push to the RVT. Typically this is BaseColor, PBR-stuff, Normal + WorldHeight.
→ the landscape MATERIAL output doesn’t need PBR stuff, I run my texture-coordinates and landscape-hole-material on this.
→ WPO matters. The heightmesh has no collision, so you run collision on the actual landscape. It’s still there, just not rendered…

When you set up your landscape, since it’s never actually going to be seen in the game, you don’t need to render it in the main pass. As well, since it’s never going to be rendered, it won’t need to be lit on the LANDSCAPE, so set your landscape material to UNLIT.

As long as the PBR stuff is on the RVT, when you sample/apply the RVT-information on the heightmesh, THEN it will be lit (b/c you will actually see the heightmesh) with all the attendant bumpyness you get from using it’s height/displacement features. Recall that you only output the height to the RVT, it’s never actually applied on the landscape. In order to get that rock sticking up to make an actual shadow, we leverage the fine-grain deformation in the heightmesh. The landscape is more a glorified render-target.

Disable lighting completely, as again, you won’t be seeing the landscape.

ref:

Tested, totally works, enjoy the free FPS:

Hey Frenetic, thanks for the tip on using Virtual heightmesh (VHM) for rendering. I had no idea it existed and there is basically no documentation for it.

I spent a few days experimenting with it. It’s crazy impressive the number of polygons you can render with it.

Ultimately, I was able to get it to perform a few FPS worse than setting the terrain with a maxLODLevel of 1, but better than if I left that at the -1 default.

While the VHM looks good at a distance, I was noticing shadow artifacts when looking up close. For example, see the banding just to the left of the player here:

I was unable to find any way to resolve these shadowing issues.

The ability to add detailed height displacement is cool, but as I can’t get that detail updated to the landscape collision I can’t turn it up very high. The Landscape has that “Bake” option, but the landscape itself just doesn’t have the polygonal resolution needed in my case.

So, with the lighting artifacts, the minimal gain with detailed height displacement, VHM still being experimental, and negligible performance differences… I think I’m going to not use the VHM option.

The hope is still Epic somehow sees this and can address the performance concerns with lumen + landscape LOD.

So, from my experience:

1 - One can absolutely set the size-values of the height-rvt too high. I am using a 2k heightmap on a landscape 2033x2033 and have size settings of 10, 1, and 2. If I set the values higher than this, I can see the same stair-stepping you are getting on your lighting (and the mesh). I believe very high values will be more viable when nanite comes to landscapes/VHFM.

BTW, I can also confirm at higher resolutions there is also a significant performance penalty. I can step up a few values from the above settings before I get the stair-steps but the visual fidelity is only visible EXCEPTIONALLY close.

IMHO, there is surely a ‘sweet-spot’ you might have to fiddle to find. Larger tile-counts are better here vs larger tiles. Since the heightmesh uses a tiled-lookup, more tiles means better granularity (smaller sections) of landscape it has to troll through. This helps reduce unwanted overhead for stuff you might not see.

If I had to guess, the stair-steps are an artifact of setting the resolution of the height-rvt to something beyond the pixel-size of the source texture, but I’ve not tested…

2 - DeriveNormalZ works best when used before rendering to the RVT. Whenever I used DeriveNormalZ after sampling the RVT (in an effort to save a channel), I kept seeing artifacts pop up. I don’t believe that the RVT/VT’s are well suited to feed DeriveNormalZ. Unsure if you are using here but it had similar visual effect as what you showed.

3 - Otherwise, make sure you are using worldspace normals when using RVTs.

4 - The collision is a bit mucky since the mesh is not 1:1 with the landscape, which is why it’s best used for small details, rocks, etc. You can always make your landscape larger than you need and scale it down to increase the vertex-density (on top of import settings). However, the fact that you can clip through the mesh, helps let things like deform-able snow and the like work.

Finally, admittedly, I am working in 4.26.2 as my heightmesh and/or material seems to break in v5. I realize this is not apples to apples with what you are doing, but the suggestion I made should still apply. I feel v5 is just-slower in many things out of the box…

Thanks again Frenetic, good call, my normals were messed up, I got it to now look better with out that artifact’ing.

I tweaked looking for an optimal size for the height VT.

Unfortunately it’s still not more performant than then standard landscape with maxLODLevel 1, just a FPS or two slower. But still a good exercise to go through and a tool to have in my back pocket.

This. In 4.26 the difference between tessellation and heightmesh is night and day. A tessellated landscape runs in the 60/70 fps on my machine @ 4k res The heightmesh is 140+.

I can say for sure the heightmesh is surely more performant vs tessellation and offers a much better resolution/fidelity. However, it does come with some caveats (which in hindsight are really close to zero in cost) and yes, is still, ‘experimental’.

I’m VERY bullish on this particular tech. It really does make landscapes a snap and allows one to ‘just use a texture’ to drive a lot of the deformation, etc. The real-time shadows from actual mesh-deformations is also a great benefit.

Glad I was able to help somewhat; good luck.

1 Like

An update, we’ve abandoned trying to use Virtual heightmesh. It had nearly the same performance with lumen global illumination, and introduced virtual quality artifacts on highly varied points (peaks) on the hightmesh at distances.

This landscape + lumen performance continues to be an issue. I’ve tried things like breaking the landscape into several smaller landscapes, that did not resolve the performance issues.

So, it turns out this performance problem with landscapes and lumen is only when using hardware raytracing in lumen. When disabling hardware raytracing for lumen, the odd behavior goes away, frame rates double, and I don’t have to set the MaxLOD to 1 on landscapes.

1 Like

Thanks for the tip, will keep it in mind.

No joy for me on performance gains, but the material for my landscapes is functioning again in 5.1.p2/ :smiley:

TRS, the new temporal-AA solution halves my framerate…