Issues with Static Meshes: LOD material swap and Nanite LOD looks overly simplified

Hi everyone,

I am generating Static Meshes via code and I am running into two issues I cannot quite explain. I am attaching a video in the post to show both cases and the meshes I am referring to.

Context

  • These meshes are created at runtime / via code, not imported the usual way (probably it doesn’t mind)
  • The assets have multiple autogenerated LODs.
  • I am testing with a car: body, wheels, etc.

1) Wheel LOD material swap

I have two very similar wheels. One of them works perfectly in all LODs. The other one looks correct in the higher LODs, but in the last LOD the materials get swapped: the tire material and the rim material are exchanged.

So:

  • LOD0, LOD1: looks correct
  • Last LOD: tire uses rim material and rim uses tire material

Both wheels are generated in the same way in code, so I am trying to understand what in the generated mesh or in the LOD setup could cause that material index mismatch only in the lowest LOD.

Questions:

  • Is there anything specific I should be doing when building LOD sections/material slots in code to guarantee the material order stays consistent across LODs?
  • Could this happen if the last LOD has a different number/order of sections than the higher LODs?
  • Is there an example or recommended pattern for creating multi-LOD static meshes entirely from code so the material array stays aligned?

2) Car body with Nanite looks permanently low-poly

On the car body the LODs look fine if I do not enable Nanite.

However, if I enable Nanite on the generated mesh, it looks like it is always in a very low-poly state, as if it was picking an over-simplified version. Visually it is much worse than the non-Nanite version.

So:

  • Non-Nanite: LODs look OK
  • Nanite enabled: the mesh looks overly simplified all the time

Questions:

  • Are there extra steps required when creating a static mesh from code so that Nanite data is built correctly?
  • Is Nanite taking the lowest LOD as the source in this case?
  • Is there a way (from C++/code) to force a proper Nanite build or to specify which LOD Nanite should use as the source?
  • Any known limitations when the mesh is not imported through the usual pipeline?

Additional info I can provide

  • The generated assets
  • The video I mentioned (already attached)

Thanks in advance!

Hello,

1) Wheel LOD material swap

Is there anything specific I should be doing when building LOD sections/material slots in code to guarantee the material order stays consistent across LODs?

-In code, you have to ensure the material indexes are consistent across all LODs and section count.

Could this happen if the last LOD has a different number/order of sections than the higher LODs?

-Yes, I noticed that LOD 3 is missing a section where highlighting reveals that from LOD 2, section 0 and 1 were merged in LOD 3.

This results in the following sections having another material than what it should be. This most likely happened due to the autogenerated LOD merging for performance reasons.

Is there an example or recommended pattern for creating multi-LOD static meshes entirely from code so the material array stays aligned?

-Here’s a small code snippet of someone setting section’s material index directly: Setting the material of a UStaticMesh built from Mesh Descriptions at runtime - #4 by ChenYiZh_0210

That being said, since the LODs are autogenerated, they might not have the same number of sections still, and may require a less aggressive reduction.

2) Car body with Nanite looks permanently low-poly (here’s an example / tool someone made for making nanite meshes: https://www.reddit.com/r/UnrealEngine5/comments/1b6p0b9/ive\_made\_a\_tool\_to\_create\_nanite\_meshes\_at/, with open source code)

Are there extra steps required when creating a static mesh from code so that Nanite data is built correctly?

-It should be the same process as a UStaticMesh aside from enabling the nanite flag prior to building the mesh.

There is a function in StaticMeshBuilder.cpp called PrepareNaniteStaticMeshBuild that may contain extra prep for data possibly missing from your mesh. Also ensure there is enough detail in the mesh with a high poly count.

Is Nanite taking the lowest LOD as the source in this case?

-Nanite uses LOD 0 as the base - ensure that nanite is enabled before any reduction takes place. That being said according to the docs, LOD is auto handled and is rare to have a loss of quality. (https://dev.epicgames.com/documentation/en\-us/unreal\-engine/nanite\-virtualized\-geometry\-in\-unreal\-engine?application\_version\=5\.6\#differences\-between\-a\-nanite\-mesh\-and\-static\-mesh)

Another possibility is it might be using a nanite generated fallback mesh with default settings: https://dev.epicgames.com/documentation/en\-us/unreal\-engine/nanite\-virtualized\-geometry\-in\-unreal\-engine\#fallback\-mesh

This is most likely the cause as when I view the model without showing fallback, it remains okay as shown in the below screenshots.

[Image Removed]

Is there a way (from C++/code) to force a proper Nanite build or to specify which LOD Nanite should use as the source?

-It should be using LOD 0 as the source, but I don’t believe there is any override for this. You could check to make sure that LOD 0 contains your highest detailed version of the mesh.

Any known limitations when the mesh is not imported through the usual pipeline?

-Runtime or procedural meshes generated might lack some derived data unless properly setup manually.

In addition to the limitations of imported, there are some limitations of nanite in general as listed here: https://dev.epicgames.com/documentation/en\-us/unreal\-engine/nanite\-virtualized\-geometry\-in\-unreal\-engine\#supported\-features\-of\-nanite

Please let me know if you have any additional questions or comments!

Regards

Hi,

Wanted to check-in to see if the above information helped out, or if the issue is still occurring for you?

Please let me know!

Thank you