Static Lighting and Nanite - Custom Fallback Settings or Use Nanite

TL;DR: Improving UE5’s ability to give more granular control to Fallback Bake Meshes when using Nanite.

Hi All,

I hope that this post doesn’t repeat existing discussion, but I haven’t found anything yet.

In short, I’d like to ask if Epic has plans to provide more control to users when it comes to baking lighting using Nanite enabled meshes. If not, I’ll make a case for this feature’s strong utility:

Currently, Lightmass and GPU Lightmass, to my understanding, use Nanite Fallback meshes. However, if you’re using static lighting with the aim of achieving high realism in next-gen games, this introduces some relatively noticeable artefacts. Especially in mid-poly models (which are a surprisingly fantastic use case for Nanite).

There is a workaround to this:
You must adjust the relative error of the fallback mesh, to increase its complexity and make it more similar to the Nanite mesh. This solves the Lightmass baking issue, but at the expense of a functioning fallback mesh. As a result, if you plan to ship a game that supports both DX11 and DX12, your non-nanite builds will be very geometry heavy.


The current workaround to this, with a relative error set to 0

You could, in theory, auto-generate LODs for every mesh in the project, and force the game to display LOD1 as its maximum LOD at runtime, but this doesn’t seem very precise to me.

The solution that I would love is this:

Option A) Have a setting somewhere in UE5 that allows GPU Lightmass to use Nanite meshes globally. Either in the GPU Lightmass settings panel, or per-mesh.

Option B) Have a separate Fallback Mesh that’s generated for Light Baking, stored only for the editor, that doesn’t need to be shipped. Include these settings inside the Nanite Settings area in Static Mesh, as an example.

As I write this, I recognize that there’s a fair bit of work above to lay some new systems to substitute this before provisioning Lightmass or GPU Lightmass for a bake. However, for the next few years at least, Virtual Textures, responsibly used Nanite and GPU Lightmass come together to form a really fantastic way of making games that look next-generation. For platforms like VR, that can’t quite run Lumen just yet (at least on most machines that our users would be likely to have), this is our best choice when using UE5 for projects. Same again for mobile. In short, I believe the Static Lighting workflow has a lot of utility left, before the industry moves to full realtime lighting in a few years (if ever).

If this already exists in some form, I’d love to know about it. It not, I’d love to support on getting it built somehow.

Furthermore, if anyone has any better workarounds than the one that we’ve been using, I’d love to hear that as well.

Thanks for enduring the wall of text :slight_smile: Keep up the good work, Epic & everyone else reading this!

p.s. Here’s a bonus image that puts this workflow to the test, specced to run on PCVR:

What was your PC’s specs? And how was the performance? I’m digging into this topic out of curiosity and in a hope to understand uncharted parts of the Nanite system.

Bumping this topic because I’m running into the same problem. Was hoping that ‘r.RayTracing.Nanite.Mode 1’ would be the fix for this issue but it’s not.

1 Like

We actually have a workaround now.

  1. Set the Nanite Fallback relative error to be 0, so the fallback has the exact same quality as the Nanite mesh. We now have a polygon-perfect LOD0

  2. Add an aggressive LOD profile to the mesh. We have created a couple of our own for high-poly and medium-poly Nanite assets. LOD1 might be between 1% and 6% of LOD0.

  3. Add a MinLOD profile per-platform. Now, for specific platforms, the extremely large LODs will never be rendered if you need to fall back from Nanite.

Finally, you need to make sure that you add r.StaticMesh.StripMinLodDataDuringCooking=1 to your config. It isn’t really exposed as a command, but works very well in 5.3. Haven’t tested in 5.4 yet. This command make sure that you don’t cook those massive fallback LOD0s, so that you don’t have a lot of mesh data in the project, even if it isn’t rendered.

Its worked beautifully as a pipeline to start at Nanite, and work down to support simpler platforms, whilst having great static lighting. You’ll still be somewhat constrained by the simpler platforms with regards to level design complexity, but the meshes scale well.

Hope that helps a little :slight_smile:

It isn’t the beautiful and seamless Static Lighting design flow that I’d like. I think we have another 5 years of static lighting being relevant at least, until we can pull off realtime lighting at Mobile and XR friendly framerates. So I’d love for Epic to do one last push to get GPU Lightmass ready for production, with Nanite-friendly static lighting.

Quite a clever workaround BUT if you build your project once to test it, don’t you have to repeat step 2 (and 3) again?

You don’t have to re-add the Minimum LOD settings, as they’re saved in the Static Mesh’s data. Each time you build, it will check to see if there is a Minimum LOD and if the StripMinLOD command is set to true, then act accordingly. You have to make builds to check that your fallbacks are working properly with Nanite set to false, and you have to add MinLODs to every asset you intend to function this way. But you don’t need to re-set the MinLOD settings each build :slight_smile:

Nanite is quite performant out of the box, especially as a fast and efficient way to render mid-poly assets. We’ve tested the above level at 120fps on a range of machines including an RTX 3060 laptop. We also tested high-resolution XR (quest 3 at 100%) on the 3060 laptop, and the scene ran nicely with Nanite.

We’ve even had Nanite working on a GTX 980 for the scenes, and far bigger ones (though no Lumen). It runs quite well but for the older hardware, I would recommend using DX11 and lower settings. Nanite won’t run with DX11, and you will need to use classic performance techniques.

@ahume, thanks for the extra info. Will test it if it works in my workflow / in my projects which are combinations of lumen streaming levels (which I use during dev) and GPUlightmass streaming levels (lighting scenario, which I use when showing the project to clients).

Edit: My goal was to get some extra performance if the relative error = 1 could be used for the high poly objects in the Lumen levels. Lumen uses the fallback in its calculation so lower polys=better BUT using this relative error also generates black artifacts in the GPUlightmass levels.

I’m using a laptop with 3060 GPU. I can run the project with Lumen and Nanite in Quest 3. However, My performans is not quite good. I suspect it might be due to the low RAM. I had to use DLSS to improve the performance and it kinda worked with no problem.

Static Lighting on the other hand didn’t work. I probably missed a setup step or a checkbox somewhere. If you have a blog post on that or a link that you can refer to would be great.