We’re noticing that with Nanite the materials play a much bigger role in the large scale performance, as much as 200-300%+ (don’t quote me) can be gained in a large scene with a lot of Nanite foliage by simply switching to much simpler materials on the meshes. From a distance a lot of assets could do with a material that has a simple color to resemble the true albedo.
Unfortunately we can’t find a good way of dealing with this issue. It’s AFAIK not possible to do runtime material simplification or do a material switch based on distance to the asset, and due to how Nanite is supposed to “not need any LODs” the only real option is to cull the assets which partially defeats the purpose of Nanite.
I suppose HLODs are supposed to be used in cases like this, but it just doesn’t work well and is extremely unreliable, not to mention baking down millions of assets that are often 1 million triangles in complexity just crashes the engine when testing (using a temporary mesh for the HLOD baking process then switching after could in theory work but HLODs are so finicky and broken anyways).
Can anyone think of a way to deal with this issue out of the box or is this another situation where we are at the mercy of Epic doing the right moves?
One way is distance meshes - kind of like HLOD, but single meshes - preferably single triangles even - baked in, simple materials, 1 draw call per instance, no collision… rdLODtools makes some types of these and I’ll be adding more in the future…
The problem I see with this is how do you switch meshes? Nanite has no LOD capabilities and from what I can see the only thing possible to relieve performance is straight up culling.
If doing something like reverse culling where an asset is only visible until x distance from camera would be possible (at least I haven’t found a way) we could add seperate non Nanite meshes that replaces the Nanite meshes when they are culled.
My only idea for now is to add a simple non Nanite triangle mesh, attach a cluster of very simple trees as a LOD to that triangle, generate the FTs, set up LOD distance so the triangle swaps to the simple tree meshes around the time the Nanite trees cull. If the triangle is below the landscape you will basically only see the LODs when they kick in. Not exactly very beautiful but in theory could work.
I was thinking more in the line of World Partition HLOD type placements, where it would just be a single “far LOD” in the partitions in the distance.
I can see the merit in having a simpler material switch in at a certain distance (using the existing geometry) though - that should be possible to implement - but after years of trying to match a lit mesh with a flat simple material in rdLODtools, I’m not too optimistic that you could get it to switch without a visible seam in your scene - you can match the distance up with where you change your shadow rendering types to hide it a bit, but it still seems to be defeating what Nanite is providing us with in the first place…
Can’t you just change the problem materials via blueprint without LoDs? You can easily calculate the screen percentage in the same way the LoD system does and do any behavior you want based upon this.
What kind of materials are you talking about here? Because I’ve only found this to be the case with Masked and WPO.
Masked Nanite is so slow that Epic doesn’t even use it, while WPO is so slow that they bake all of their animations to textures rather than calculate them per-vertex in the shader.
At the end of the day though large worlds really require HLODs in some form.
We’re talking about masked for the most part. We do model very close to the foliage opacity map so we can kill transparency after maybe 10-20m to avoid too much overdraw but we can’t model close enough to completely bypass the need for masked material as the assets would be so high poly it would cause other issues in the pipeline. Epic we’re able to do this because the assets are inherently simple which is far from the case with our assets.
Unfortunate considering we only need masked materials for close up, turns into a huge waste past 10-20m from the camera.
You can also take advantage of the fact that Nanite uses just one material draw call across any number of unique meshes. This means if you get all of your foliage textures into an atlas or array, many foliage items can share a call and potentially help negate some of that extra cost.
Not sure if you have looked into this already, but for meshes like grass, trees, rocks, leaves etc, where the world is open and large, it seems the expectation is to use the world partition system automatically activated in the UE5+ open-world template. This is a grid based loading system with things loading in and out, and there is a way to have an RVT with it on the landscape so it only updates as you approach. Another popular option is the same culling effect but a 180-degree view, so it has loaded based on range and rotations angle, so in the direction you are facing, it loads at a greater distance. Then you need to balance the range with the number of calls and draws.
It’s correct that you are supposed to use World Partition/HLODs and all that for things to properly function together but there is no way of properly testing this when the pipeline is broken, both WP and HLODs have major issues stopping it from being production ready for large open worlds. Besides that we can’t really stray away from the original purpose of Nanite with custom solutions as we should expect most of these problems to be properly addressed, at least if Epic ever wants to please the game dev side of the engine.
Hey! Not sure if you saw they are expanding Nanite for landscapes, as well as improving the optimizations by possibly removing pixel shaders altogether (On the roadmap)
As per the documentation, meshes that share the same material are batched together in draw calls with Nanite. I’d advice revising the foliage authoring pipeline and ditching Alpha masking in favor of full geometry foliage and atlasing as many foliage meshes texture in a single shared UV/Material.
A 4k texture can atlas 10s of foliage type, leaves,ferns, plants you name it. It should improve performance drastically, at least it did for me in foliage heavy scenes.