June 04 2021
In this blog post, I will show you why, when and how you should use LOD in Unity.
Remember: Level of Detail (LOD) is not only about the poly count!
Let’s start with the obvious question: why might you need to use the Level of Detail technique in your Unity project?
Put simply, here are three reasons:
If you are in any of the three situations, then here’s your green light to use the Unity LOD feature.
Let’s see what exactly it is.
The Level of Detail you’d use in Unity is rather simple. It’s just about changing the mesh you render at different distances from your camera.
This is the logic behind using juicy LODs in Unity:
In reality, it’s not so much the distance from the camera to the object, but the size the object occupies in the screen in pixels.
But yes, that size is reduced when you move away from the object.
This is no different from real life. When you zoom in in a picture, you can see all the spots in someone’s face. That’s why it’s a good idea to shrink a bad selfie so that no one can see the wrong details.
The Unity LOD system has a series of “levels”:
You can introduce more LOD levels, but having three levels or even two is often more than enough.
Now, how do you use LODs?
The basics are straight forward:
Unity will then automatically switch between your LOD levels depending on its distance to the camera for you.
Let’s see those, step by step.
To generate the different versions of your LODs, you have three options:
The difference between them is the time you’ll put into them, the resulting quality you get and the flexibility you have in the process.
Here, it is all about editing your meshes in your favorite 3d software (Blender you said?).
There are universal modifiers that help you here, such as decimate/subdivide, but most of the time you have to edit the result to make it sexy.
This is more of an art thing and I am no artist, so let’s get into the programmer-friendlier way.
Here we enter in the realm of specialized LOD generation tools… often called “automatic LOD” (but that’s almost never the case).
The idea is simple: let smart software generate the LOD levels for you.
Here are some of them:
Some of them have Unity integrations that let you generate these meshes within the editor.
They are useful for doing quick performance tests and some results might work for production quality level. Very handy tools to have for us programmers.
If you can approximate a specific LOD level with a 2d image, you can be sneaky about it.
Just make an in-game screenshot of your target object, tweak it as you need and assign it to a new LOD level with a quad on it. You might need to give it an unlit shader to make it look as intended, but you get the idea.
In live lesson #3 of the Performance Taskforce, I show you how to do this within the 1-minute mark.
You’ll be impressed at the results.
Ok, so let’s assume you have your new LOD meshes. Now we have to…
Create an empty game object and add the LOD Group component into it.
That’s it.
Now, it’s time to tell Unity what meshes to use.
Again, this is straight forward. For each LOD level you want to have:
That’s it.
Once you have all your LOD levels set up, you need to tweak its distance thresholds.
Having multiple LOD levels won’t help you if they are used at the wrong distances.
Here, we want to change the distances at which the different LODs are swapped.
You can do this by dragging the vertical bars that separate your LOD levels in the horizontal bar you have in your LOD Group.
These distances are measured in % related to the vertical size they represent on the screen. This is not an important detail to know, but be aware that these distances are also related to the size of your object.
And that’s it!
If you did these steps right, you will have LODs set up correctly for that mesh of yours that was causing trouble. You’ll get a neat performance boost from applying LODs to further troublesome assets.
Now, that’s not all… Let’s get into the juicier stuff.
There are two project-wide settings in Unity you must be aware of:
These settings have their uses:
You can find creative ways of using these settings in your project :-)
Ok, LOD popping is one of the most visually annoying parts of using LODs in Unity.
LOD Popping happens when your user is able to see the abrupt transitions between LOD levels. This happens when your LOD levels are very different and the swaps change in noticeable moments.
To combat this, you can do two things:
Crossfading is just that, to do a smooth transition between your LOD levels instead of a rough, binary swap.
There are two main ways to achieve crossfading:
Here’s how dithering looks:
Both transitions may happen over time or over a distance overlap threshold. You can set that in your LOD levels in the LOD Group itself.
Crossfading has two challenges:
But if you know what you are doing and measure its cost, you will please your users and still be within your performance budget.
In live lesson #3 of Performance Taskforce, I show you the simplest way to achieve the crossfading you want… to never make your players suffer from LOD popping ever again.
You might be wondering: what are the side effects of using LODs in your project?
Are LOD levels compatible with lightmap baking?
Yes, they are.
Each LOD will have its own lightmap as you can see below. This will indeed incur in higher memory overhead if you end up with more lightmaps, so that’s another reason to be careful not to add too many LOD levels.
What about draw call batching?
How does using the Unity LOD affect draw call batching in Unity?
That’s a tough one.
The thing is, LOD levels usually have different geometry. And different geometry means, different draw calls.
Unless some sort of batching kicks in.
Which sort of batching can work? Let’s analyze some techniques.
So keep batching in mind when you implement LODs in your Unity level. As always, measure your draw calls with the frame debugger.
Oh, another thing to keep in mind is occlusion culling.
Here we are, the art of skipping the rendering of objects that are occluded by others.
In this case, when you bake occlusion culling, you must be aware that Unity does so by taking only LOD0 into account. That is, Unity uses the most detailed LOD level to calculate the visibility cells for further culling.
Normally, this will be fine for you. However, if your LOD levels differ greatly in shape and volume, then you might end up drawing more objects than you need (performance overhead but visually correct) or fewer objects than you should (visually incorrect, better performance).
For example, the usage below would be pretty inefficient for occlusion culling due to shapes differing greatly across LOD levels:
Let’s get into one of the hidden uses of LODs in Unity: saving draw calls.
Not only can you reduce vertex count, you can also reduce draw calls.
How?
Two ways:
This will give you substantial gains in CPU performance, especially in the area of rendering (the big green block you see in the profiler). You can see an example on how I do this in the lesson #3 of the Performance Taskforce.
So that was it for the more advanced usage of LODs.
As you saw, the Unity LOD system can give you substantial benefits in two main areas:
If you want to see a previous live session on LODs that goes deep into the how to of its advanced use cases, such as crossfading, make sure to enroll and watch week 3 of the Unity Performance Taskforce.
Ruben (The Gamedev Guru)