Mesh LOD 2025

MeshLOD_Ork_gif_2

Hi everyone,

As you have probably seen in Unity’s roadmap, we have been working on a new runtime level of detail (LOD) system called Mesh LOD, which is a specialized solution to reduce vertex pressure on the GPU while minimizing additional memory usage.

We are excited to announce its release in Unity 6.2 alpha 8, marking the first foundation of our new Mesh LOD system. While this marks an important milestone, we want you to know that we are already hard at work improving and building on it. Your feedback will be invaluable in guiding us as we refine and enhance the system further. This is just the beginning, and we’re looking forward to growing and evolving it together with your input!

Level of detail systems, such as the LOD Group component, reduce rendering complexity of an object by rendering less complex versions of that object, typically as the object becomes smaller on the screen. As a result, this reduces the number of GPU vertex operations needed to render distant objects, while still maintaining their perceived aspect.

Unlike LOD Group, where each LOD is a set of distinct Renderer(s), Mesh LOD keeps all LODs within a Mesh without creating new GameObjects, components or assets such as a Mesh Renderer. Manual settings are also kept at minimum in order to make it easy to configure and use. Mesh LOD is a foundational rendering technology, adding to the existing LOD Group, and allows you to write your own generator and tools.

For more technical information about LOD within Unity please refer to the documentation.

How does Mesh LOD work?

  1. Mesh LOD runtime

All Mesh LODs reside within the Mesh’s index buffer, which is uploaded as usual. For every instance of the Mesh on-screen, the LOD to be rendered is determined by a LOD Selection Curve stored on the Mesh (Mesh.lodSelectionCurve). This curve maps the relative size on screen of the mesh bounds, adjusted by quality settings, to a LOD. The selected LOD can be adjusted on each renderer component.

A correctly configured curve’s objective is to select the best LOD that can fulfill both criteria:

  • Generate the least amount of (visual) error compared to the reference mesh when displayed on screen.
  • Have the lowest geometric complexity

The Mesh LOD system then adjusts the draw range to match the selected level.

  1. Mesh LOD generation

A key benefit of Mesh LOD is the ability to automatically generate levels of detail at import time. Automatic LOD generation inside the Editor provides multiple advantages:

  • LOD generation can be a very time consuming manual process; auto-generation reduces the time spent authoring LODs.
  • This results in a simplified workflow, by removing the need to use an external DCC and to manually re-author your LODs each time the full detail model is modified, thereby reducing iteration times.
  • It reduces the risk of manual error by saving LOD quality settings in your project and by letting you focus only on the most detailed version of your models, while relying on the system to automatically keep the lower LODs in sync.

You can preview the generated Mesh LODs in a Mesh Preview window. If you wish to limit the LOD count to a maximum, you can do so by modifying the appropriate setting in the importer window and re-generating the Mesh LODs.

This lightweight generator is intentionally constrained to minimize memory usage by reusing existing vertices. Without explicit LOD count limit, it generates as many LODs as possible, through clustering and edge collapse, until the mesh cannot be simplified anymore. As a result it has a low memory footprint, and works better with high poly count / organic meshes. Quality might be more limited when reaching low vertex count or with meshes that have disconnected vertices like trees.


Example of generation limitation

You can read more about the current limitations and controls available to get the best results in the documentation.

  1. Mesh LOD API

We have exposed a C# API to enable flexibility when using Mesh LOD. It allows you to create your own tools, add your own generator or take control at runtime. The generator can be called with the API from C# in the Editor. But you can also set your own Mesh LOD data using the C# API in either Editor or in your game at runtime.

using UnityEngine;
using UnityEditor;

public class MeshLODWindow : EditorWindow
{

    Mesh m_Mesh;

    [MenuItem("Tools/Mesh LOD Generator")]
    public static void ShowWindow() => GetWindow<MeshLODWindow>("Mesh LOD Window");

    void OnGUI()
    {

        m_Mesh = EditorGUILayout.ObjectField("Mesh", m_Mesh, typeof(Mesh), false) as Mesh;
        if (GUILayout.Button("Generate LODs"))
        {
            if (m_Mesh != null)
                GenerateAndSaveMeshToProject(m_Mesh);
            else
                EditorUtility.DisplayDialog("Error", "Please assign a Mesh before saving.", "OK");
        }
    }

    void GenerateAndSaveMeshToProject(Mesh mesh)
    {

        var path = EditorUtility.SaveFilePanelInProject("Save Mesh", name, "mesh", "Choose a location to save the mesh");

        if (string.IsNullOrEmpty(path))
            return;

        Mesh meshCopy = Instantiate(mesh);
        MeshLodUtility.GenerateMeshLods(meshCopy);
        AssetDatabase.CreateAsset(meshCopy, path);
        
    }
}

Example to create a tool that generates LODs from a mesh

When to use Mesh LOD?

Mesh LOD is ideal to use during the early stages of production or while prototyping, offering an efficient way to start achieving your LODs. It allows you to quickly test ideas and concepts before committing. As you progress, you might need to transition to other LOD solutions to solve other issues, for example if:

  • You identify assets which do not produce the desired results given the generation constraints, for example trees or already-low poly meshes.
  • You have a need to optimize something other than vertex pressure. In those cases, you may prefer solutions that provide billboards, HLOD, imposters, specific culling or switching between different materials.
  • You are using LOD stripping to remove the more detailed LOD(s) from a build, but you identify that the LODs generated with Mesh LOD may not have high enough fidelity to serve as the maximum LOD, for lower-end platforms.

Comparison to LOD Groups

Mesh LOD is not a replacement for LOD Groups. Each system excels in specific contexts and are in fact complementary. They can be combined in a scene, with some objects using Mesh LOD and others using LOD Group, or even on the same object. However, for now, we recommend avoiding the use of both solutions on the same object, as it creates a complex workflow.

LOD Group is the solution that provides the most versatility. Each LOD needs to be imported and is a new object with a set of renderers. It allows you for example to use billboards or meshes with different materials. You can also define when the object needs to be culled. One of the drawbacks is that it has an impact on memory.

LOD Group works both on GameObject and Components and has per-level selection controls.

You can find more information about LOD Group in the documentation.

What’s next?

As mentioned in the introduction, this is the first foundational step of the Mesh LOD system.
While this version introduces important capabilities, we recognize there are current limitations, and we are actively working to address them as part of our ongoing development process.
For example, one of the improvements already on our roadmap is the addition of debug functionalities. It will allow you to better understand which level is currently visible in your scene.

To learn more about all limitations please refer to the documentation.

As we are working to improve the system, please don’t hesitate to provide feedback in this thread.

53 Likes

First, I’m excited about this for various reasons. I’ve always wanted a hands-free LOD generator if only for replacing “long-distance” objects with a more optimized version no matter how ugly (not as ugly as that tree though). :slight_smile:

But I can’t help to be :open_mouth: seeing that in official example code.
Specifically the creating an asset with CreateAsset also implies it was “saved”. And doing so with the AssetDatabase also has the new asset imported and loaded, thus it’s also “refreshed” aka up-to-date.

Unless there’s something else going on that I don’t see, this ought to be sufficient:

        Mesh meshCopy = Instantiate(mesh);
        MeshLodUtility.GenerateMeshLods(meshCopy);
        AssetDatabase.CreateAsset(meshCopy, path);

:wink:

11 Likes

That is… totally correct :sweat_smile:.
Thank you so much for pointing that out. I’m modifying the example :slightly_smiling_face:

4 Likes

Something to be appreciated. Thank you very much

3 Likes

Thank you!

Is it possible to react to the LOD being switched during runtime? For example, I might want to enable/disable a script on the renderer depending on its LOD.

3 Likes

As CodeSmile said, I too am excited about this for various reasons! The automatic authoring experience is bound to great.
I’ve looked over the documentation, and I’ve got a few questions to follow up with!

The following systems do not support Mesh LOD selection. These systems always select LOD0 with the Mesh LOD feature.

Is it safe to assume we should not enable Mesh LODs on these types? e.g. for VFX meshes, because we won’t be able to obtain any benefits of those?

All Mesh LODs reside within the Mesh’s index buffer, which is uploaded as usual.
https://docs.unity3d.com/6000.2/Documentation/ScriptReference/UnityEngine.MeshLodRange.html

Then, does the the index buffer obtained by the mesh have any indicator via c# to which indices belong to which LOD level? do we have any access for manual mesh runtime building / manipulation, to set these?
The MeshLodRange link is uhh, leading to a missing page :sweat_smile:

Mesh LOD supports the LOD cross-fade feature only when the GPU Resident Drawer is enabled in a project.

Any particular reason for this limitation? would this also apply in the case of skinned meshes?

Using Mesh LODs with Skinned Mesh Renderers does not reduce the workload related to calculating mesh deformations.

I understand the relation between LOD0 and how Mesh LODs work, so its reasonable to expect there to be no performance win here

  • Is it possible to extract the Mesh LODs as their own HLODs? so we can reap the automatic authoring benefits while still using HLODs?
  • Do you have any numbers on the general performance cost of skinning vs rendering a mesh? is this a significant reduction in the benefits or is it still beneficial to use Mesh LODs in the case of skinned meshes?

Mesh LOD only supports meshes with triangle topology.

I was under the impression unity converts all faces to tris on import, does this refer to ‘keep quads’? if yes, does this mean that ‘keep quads’ and ‘mesh lods’ are exclusive features to each other, or, do Mesh LODs simply not touch quads? (such as in the case of a mesh that has both, for whatever tarnished reason)

Unity doesn’t provide functionality to visualize which Mesh LOD index is being rendered.
At runtime, the Mesh LOD feature selects the appropriate LOD automatically depending on the size of the mesh on the screen

So what value is actually used to determine which LOD will get picked when saying ‘size on screen’? renderer’s bounding box? renderer’s position? does scale play into this properly? if bounding boxes, are there any traps as to how a mesh might get authored to to have inflated bounding box that chooses LODs wrong? (such as a thin pole, placed 45 diagonally to inflate AABB bounding box?)

Separately from all this… Yay! New settings for Mesh Importers! Do AssetPostProcessors get access to them? Separately, can I piggyback on this new addition to bring up that… Trying to add new data to FBX imports is absolutely miserable ?, I’d love if that could be passed along to whoever is touching the importers at this time :person_bowing: :folded_hands:

And, lastly, what is the expected primary benefit of Mesh LODs? From the initial read I assume it is

  • Levels with different high-detail objects that aren’t split to small pieces, and are spread all over the map
  • Better prototyping, as long as you don’t have to change scripts when the mesh changes
  • Meshes with relatively flat surfaces, who’s LODs won’t deform their shapes much
    So mechanical / industrial style levels? Any other hidden beneficiaries?

Thank you for the work on Mesh LODs! :person_bowing:

4 Likes

I wonder if mesh lod support submesh and multi materials(different materials for different submesh or many materials with one submesh)

I would like to add an imposter to the last LOD, is there a way planned to do this?

12 Likes

This is great and we actually have a really strong use case for this but it would need to work at runtime as well. Do you have runtime generation of LODs on your roadmap? This would be magnificent and enable so many use-cases with user-generated data in mind.

3 Likes

Does it currently work with ECS? And if not, are there any work-arounds to make it work with ECS?

1 Like

Just to confirm @DoctorShinobi, you would like to know if there is a high level callback when the LOD is changed?
If that is indeed the case, today there is no call back. Adding a call back could add overhead, so currently it was not in our backlog. But we can maybe add properties like activeLOD to help you with these type of use cases.

With the current version though, you can already calculate the currently selected Mesh LOD using the selection curve. We do not have an exposed method in Mesh or Mesh Utilities to do this, but InstanceCuller in SRP core has a function called ComputeMeshLODLevel that does and is public.

1 Like

Just to clarify, do you mean working an ECS project that uses Entities Graphics or an ECS project with Game Objects?

MeshLOD currently does not work with Entities Graphics. You can find the list of the current limitations in the documentation here

1 Like

Nice to see built-in LOD solution!

Can you spill the beans on what the MeshLOD solution is built on? i.e. does it build on for example technology from PIXYZ (that Unity owns!), or something like meshoptimizer, or completely internal to Unity algorithm/solution?

7 Likes

Adding imposters as the last LOD is not planned yet but it is definitely a great area to explore, as there’s a lot of potential there. Don’t hesitate to vote for the official feature request in the public roadmap.
3D Imposter are still under consideration.

7 Likes

Are there plans for integration with Entities Graphics? If so, is there an ETA?

2 Likes

Voted, I would also be interested to see if there is a way to use the last LOD of MESHLOD with amplify imposters. Because it would be faster than using the normal unity LOD system.

7 Likes

Hey Aras
I’m glad you like the fact that we added a built-in LOD solution :smile:

Just to clarify that part, Mesh LOD system should be considered as 2 distinct parts: the runtime and the generator. It does not build on external technologies but it is not a complete closed system.
Solutions like Pixyz are generators that could use the API to provide Mesh LOD data and make use of the Mesh LOD runtime system.

The generator we provided is designed to make full use of the Mesh LOD runtime system capabilities. As such, it is constrained to re-use vertices. Other generators could decide to generate LODs that add vertices. Flexibility was one of the biggest requirements for this feature.

@Churd Yes, there are plans for integration with Entities Graphics but I’m afraid we don’t have an ETA for it right this moment.

2 Likes

Right, I’m interested in what is the generator. The approach that does not introduce or move vertices, and “just” produces a different index buffer for different LODs (either several static levels, or “sliding window” progressive mesh style) is a pretty common approach.

Was just wondering whether the generator that is currently used in 6.2 something based on existing library, or completely developed internally at Unity. Why I am wondering? Mostly because while doing something “that mostly works” is fairly easy (you take classic Hoppe progressive meshes paper from 1996 and implement that), there’s a ton of possible corner cases where getting “good automatic LODs” is hard. Architectural buildings with lots of small details at right angles; skinned character models; etc. etc. – and some existing LOD generation libraries (even open source ones) have spent years improving and polishing these cases already.

5 Likes