Nanite - Material Switching based on Distance (LODs Replacement)

With Nanite, Masked Materials are much more expensive.

I would like to have a material be opacity masked closeup, but at a certain distance just become opaque.

Traditionally, this would be easily achievable, by just assigning a different Material for a LOD.

With Nanite, this option no longer exists.

The context is wanting to have a much cheaper material in the distance. Especially nanite hugely benefits from opaque materials. So being able to have an opaque blend mode in the distance, where the difference can’t be perceived, would be a big performance win.

1 Like

Hi TheRealBiomes,

I don’t have anything definitive I’m afraid - but AFAIK the distance nanite meshes are Impostors which have to be masked anyway.

Hi RecourseDesign,

Thanks for your answer.

So, in a traditional non-nanite LOD Pipeline, x-trees, sprites or imposters would indeed be used.

However, for nanite, imposters would not be necessary. It would be possible to have a regular mesh, that approaches the shape and silhouette of the mesh very closely. That is thanks to nanite’s triangle per pixel paradigm.

It would make it possible, to disable masked materials completely. Without any difference in visuals. Or almost none. But the performance savings would be very high.

You could use a blueprint that swaps meshes at a certain distance, but RecourseDesign is right, when Nanite meshes are only a few pixels, they are swapped with impostors.

2 Likes

I found something definitive: (I didn’t realize they were quite that small though)

At very small scales, even low-genus objects run into visual changes caused by over-decimation. Nanite overcomes this by pre-rendering 12×12 pixel imposter images from 144 different view directions in advance and using the image that most closely aligns with the current view direction if the object’s on-screen bounding box is less than 12 pixels in size. That solution requires memory for the set of imposters and can result in popping, so the Nanite devs have expressed a desire for something better. It also doesn’t do much to help with grass, leaves, hair, screens, blinds, and other large objects made from the cumulative visual effect of many small pieces.

https://cs418.cs.illinois.edu/website/text/nanite.html#case-study-nanites-approach-to-lod

1 Like

EDIT nvm. Solution was already given by ZacD :+1:

Thanks a lot everyone for the answers.

I was not aware, that nanite turns assets into imposters when they get smaller than 12x12 pixels.

However, that is not a solution at all for the problem.

If we assume fullHD, that would be equivalent to a screen size of 0.011.
If we assume 4k, that is a screensize of 0.0055.

But there is a lot of assets at screen sizes in the range of 0.2 to 0.011(or 0.055).

These assets would often benefit hugely from not being rendered with a masked blend mode.

Hence a way to switch out the material or the material blend mode, at a certain distance, would be extremely helpful for optimisation of open world levels. Especially those that feature lots of masked materials.

1 Like

I had my benchmarking level open anyway so did some tests and you’re right - it can save a good amount of GPU time - but it does introduce a different type of internal lighting - you don’t notice the opaque branches of leaves, you notice the shading of everything is suddenly darker…

The link below is just a comparison slider between masked and opaque foliage:

3 Likes

Thank you very much for doing a test and even creating the comparison picture!

So, this is of course an art, not an exact science.
It will hugely depend on your content, the lighting, the camera position and so on.

We have noticed, that for some of our content, we can confidently disable masked, after like 20 meters for most of our assets.

That comes with a gigantic performance boost.

I wish there was a way to do this. I’m sure there are other areas, where this added flexibility is beneficial.

1 Like

Is there a CVAR to disable at least all masks on all materials in the scene ? So you can at least disable all those for testing purposes.
Sort of like a : r.TextureMasking.Disable 1 or something

There’s r.Nanite.AllowMaskedMaterials

3 Likes

Is this new in 5.3? This CVAR doesn’t exist in 5.2.

1 Like

Yeah, it seems to only exist in 5.3.

Curious, but this would also benefit world position offset… i ahve powerlines that sway in the wind along with airconditioner fans that spin in the material. How could i set up an lod to disable world position offset for nanite meshes? It is quite expensive for nanite.

It is quite expensive for nanite.

*Nanite is quite is expensive.

Have you tried to see if just turning off Nanite helps or did you already reach the threshold of overdraw hell in terms of tri-count?

Nanite for me is important. I have materials that are layered that have a near 0 vertex shader cost… using vertex colro to blend edge wear and dirt build up via baked ao… and baked curvature…

Not to mention basically 0 draw calls since most things in my scene use that material…

Also i found the solution. (in unreal engine 5.3 there are options for lumen invalidation and world position offset disable distance per static mesh…

there is command r.Nanite.AllowProgrammableDistances default value 1 , but i cant figure what is it for. description is Whether or not to allow disabling of Nanite programmable raster features (World Position Offset, Pixel Depth Offset, Masked Opaque, or Displacement) at a distance from the camera. its look like what we need but i cant find any info how to use raster features?

When creating a standard instanced static mesh using an actor, there are both Min Draw Distance and Nanite Pixel Programmable Distance settings in the details panel. These sort of work but there are issues. The biggest issue is that this only works on blueprint actors, as these descriptors don’t seem to be exposed to PCG or the foliage tool static mesh spawners.

The Min Draw Distance setting can theoretically be used to spawn two meshes in the same spot - one being drawn near and the other being drawn far. By setting the Min Draw distance of the far proxy (ie opaque mesh) as the same as the max for the nearby hero asset (ie masked mesh), they can seamlessly swap at the desired distance.

The Nanite Pixel Programmable Distance disables any pixel programs (such as opacity masking) beyond a certain distance.

Spawning an actor in PCG with a max Nanite Pixel Programmable Distance set does seem to work, but is not appropriate for foliage and many other cases. It also doesn’t seem to impact the shadow pass properly in my test (mesh still appeared masked in shadows after switching opaque in main).

The Min Draw Distance setting didn’t seem to work properly with actors spawned in PCG.

Hopefully these descriptors can be exposed to PCG and the foliage tool and also hopefully LOD style features (such as swapping meshes, materials, shadow casting) by distance is added to nanite in the future. Using nanite shouldn’t mean losing legitimate optimization options that LODs provided. For example, nanite draws into VSM at unlimited distance, which can lead to many small objects being rendered to shadow depths needlessly. LODs easily allow shadows to be disabled by screen-size.

In the meantime, the best I can come up with for foliage is to use the distance or screen size in the material to lerp opacity to 1. This is still more expensive than a truly opaque material, but I’ve found a masked material with an opacity of 1 to be measurably less expensive than a partially or fully masked mesh - so it is better than nothing.

Also consider the shadow pass when using CSM or VSM. You can make your mesh opacity=1 using the shadow pass switch. This might save some time when drawing the shadow depths.

Another descriptor that is unfortunately missing from the PCG mesh spawner is the checkbox for “Draw in Main Pass.” You can use this to disable shadow casting on the mesh, but then spawn a shadow casting proxy mesh (invisible in the main pass but not the depth pass) in the same location with a fully opaque material and even simpler geometry if you like.