Nanite and Animation LoDThreshold not working together

I’m encountering an issue currently with nanite for skeletal meshes and animation optimizations.
When I’m enabling nanite for a skeletal mesh, LoD stops getting calculated, Get predictedLoDLevel returns always 0, it makes sense for geometry since it doesnt need it anymore but for animation and CPU optimization its a pain since then we loose the feature to disable heavy load nodes in the animgraph based on LoDs or remove bones like facial bones or dangling physics bones.

I’ve dug through the code and I believe it all comes down to FSkinnedSceneProxy and the property NumLODs there are plentyu of checks in this struct that checks for NumLODs > 1 but haven’t seen anywhere where this variable is set and its initialised to 1 so MeshObject->UpdateMinDesiredLODLevel(View, GetBounds()); in FSkinnedSceneProxy::GetViewRelevance is never called.

Is this a bug, intended or am I missing some undocumented obscure flag somewhere?

1 Like

Seems like you found a genuine limitation in the current Nanite skeletal mesh workflow. Nanite removes the usual geometry LOD path, but animation LOD still needs those values for things like AnimGraph optimization and bone reduction.

Your code investigation around FSkinnedSceneProxy and NumLODs sounds like the likely cause. I’d test with preserved mesh LODs and check your engine version for fixes, but this may need an engine-side change. A small repro project would be useful for a bug report.

seems like adding this line

NumLODs = RenderData->LODRenderData.Num();

to the constructor seems to get things working