LODs not working at all

I created 2 LODS (0 & 1) for a tree mesh. I added another material for testing and set LOD1 to use the newly added material slot for the leaves of my tree.

In the preview window, I selected LOD1 to preview and it only displays the mesh & materials used for LOD0. I change the material slot for LOD0 leaves while previewing LOD1 and it changes the material for the leaves in the preview, so I can confirm that the preview window is displaying LOD0 even though I have LOD1 selected!!!

I put 200 instances of the tree in my level and set LOD1 screen size to 0.5. None of the instances are using LOD1.

There is a serious bug in Unreal Engine 5.3.

I will create another project and see if LODs are working in a new project, but at this point, none of my LOD tests are working at all for any meshes I’ve created.

I’ve come to realize that there is indeed a bug in Unreal Engine. If I use a very simple material for LOD0 and a different material for LOD1, the LODs do work, but if I use a material instances for LOD0, it won’t switch between LOD0 and LOD1 (even in the preview pane).

…

Okay, so now with further testing, not even simple materials will allow LOD1 to work anymore. Unreal Engine is so buggy with the LODs, I swear. I JUST WANT TO USE 2 DIFFERENT MATERIALS FOR LOD0 AND LOD1. WTF AM I SUPPOSE TO DO HERE??? THE EDITOR WILL ONLY DISPLAY LOD0 IN THE PREVIEW PANE, EVEN IF I SELECT LOD1. WTF IS GOING ON HERE?>???"??? DO I HAVE TO DEVELOP MY OWN LOD SYSTEM BLUEPRINT???


Another test. Used a cube in Blender. Added subdivision surface modifier. Cube is now a ball. Saved ball as LOD0.fbx. Reduced modifier. Cube is now a low poly ball. Saved as LOD1.fbx. Removed modifier & saved cube as LOD2.fbx. Imported LOD0.fbx as a new asset into Unreal Engine 5.3. Added LOD1 by importing LOD1.fbx directly into the LOD0 asset. Also added LOD2 via LOD2.fbx. NONE OF THE LODs ARE DISPLAYING IN THIS SIMPLE EXAMPLE!!! I’M NOT EVEN TESTING MATERIALS ANYMORE. LITERALLY NO LODs ARE WORKING IN MY PROJECT. WTF IS HAPPENING TO UE5.3???


Okay so I tried the above in a new 5.3 project and LODs are working. I wonder what kind of fuckery I must have done to my game project that broke LODs? Now I have to migrate all my assets to this new game project. Oh joy.


OMG! If I disable Nanite for my mesh, everything works just fine. You should probably include that in the documentation for using LODs. WARNING: LODs will not work if you have Nanite enabled for your mesh.

Honestly, I don’t know why you even have LOD settings displayed when Nanite is enabled in the first place.

2 Likes

Having similar problems with LODs not working at all in just one project, how did you turn nanite off per mesh? I’ve tried everything else above and no luck.. It also stopped working for my grass foliage

Hi @swaggod,

Yes, this is expected behavior. Nanite is a separate rendering system that replaces the need for LODs. However, LODs are still used for collision meshes, which is why the LOD options are still exposed for Nanite static meshes.

If you are going to use Nanite for your project, it’s really important to understand how it works and when to use / not use it. Here is the full Epic documentation on Nanite, which is a great starting point.

In general, Nanite does not handle masked overdraw well at all, so a lot of people either convert their foliage to non-Nanite (which isn’t very performant), or model the foliage geometry precisely so masks are not required.

All of that being said, if you are still looking to disable Nanite on your foliage, you can bulk-enable/disable Nanite from the content browser by right-clicking:

This is a newer feature, so if your engine version does not have this, you’ll have to open up the static meshes and disable Nanite here:

Good luck! Let me know if you have any other questions.

Thanks for all the info, so modeling each blade of grass will really be more performant than masked billboards? I’m still confused why it would work in one project but not the other, but I’m using UEFN so don’t have access to those nanite settings sadly.

I can provide you with some additional context, just because it’s good information to understand.

Nanite replaces the traditional rendering pipeline with its own separate rendering system. This includes lighting and shadows, shaders, polygons- all different.

In a normal rendering pipeline, every vertex needs to be computed individually. This gets really expensive, because each vertex needs to hold its position, normals, texture coordinates, and color. That’s quite a lot of information for a 1,000 tri mesh. Now, passing that information along to a material also increases the complexity, as that material has something called a Vertex Shader and a Pixel Shader. Any logic done on the Vertex Shader (usually by default things like World Position Offset, lighting, and skinning) has to be computed per-vertex, so the more vertices, the less performant those calculations are. This is why games usually want your meshes to be as low-poly as possible, and use LODs to make objects even more low-poly at a distance. In game rendering, every vertex matters. This is actually the same reason we use normal maps, because it allows textures to fake the lighting calculations done by vertices at a pixel level, without requiring super detailed geometry.

Now, Nanite throws all of this out the window. Nanite uses what it calls a “cluster” system, which breaks detailed meshes into groups of triangles, and these clusters are individually culled based on occlusion and frustum. This allows groups of triangles, even within the same mesh, to be culled based on visibility. Cluster size and complexity is also changed based on screen size, eliminating the need for LODs since this process is essentially done per-cluster instead of per-mesh. This is also the reason that the lighting and material processing has to be so different, because the cluster system isn’t super compatible with traditional vertex methods. This is also why Nanite is designed for use in tandem with all next gen features- Lumen, Virtual Texturing, Virtual Shadow Maps, and Temporal Upscaling.

This is obviously a lot more complicated of a topic, as its a new method and gets very technical, but here is a fantastic breakdown of the system if you want to learn more.

As to why individually modeled geometry is cheaper on the system than masked materials- because of the way that Nanite determines clusters and visibility, it has a really hard time determining culling and LODing whenever there is overdraw, and overdraw happens more with translucent/masked materials than fully modeled meshes. Here is a great test that someone ran showing the overdraw differences. This is probably the weakest aspect of Nanite, since small meshes like leaves or blades of grass also cause lots of overdraw. In general, Nanite has no great solution for a scene with lots of foliage, but it is universally agreed upon that modeled geometry is at least better. Overall, just watch your overdraw, no matter what method you end up using.

Best of luck with your project. Let me know if you have any other questions!