Level of Detail Optimization with LOD Groups

The two biggest drains on your game’s frame rate are script execution and geometry, and you can save a ton of geometry by using LOD groups to make your objects swap to simpler versions or cull (hide) when you get far away.

Here’s how I applied this to the numerous red chairs in the ITU Copenhagen level in Code Hero.

Modeling the original

  1. I made the high-poly chair to match photos of the ITU as closely as possible.
  2. I placed the groups of tables and chairs in every hangout room overlooking the ITU lobby and it looked like the photos.
  3. I tested my game on a MacBook and suffered huge frame rate drops.

Modeling the low-poly LOD 1

SketchupLODLayerGroups.JPG

  1. I returned to the chair models and added a second layer called LOD 1.
  2. In LOD 1 layer, I duplicated the original group of objects from the chair and pasted them in place onto the new layer with the old layer hidden.
  3. I drew a new set of super simple squared polygons over the existing chair back and legs.
  4. I matched the materials with the paint can and eye dropper.
  5. I re-enabled the high detail layer to make sure my models matched up as perfectly as possible, adjusting chair leg endpoints to get a better fit.
  6. Then I saved my changes and since it is in Sketchup 2015 format it auto-reimported into Unity.

Updating the prefab

lodgroupituchair154poly

  1. My prefabs still had the old chair geometry with the new changes in Sketchup not visible.
  2. I clicked on the original ITU Chair prefab in the Project panel.
  3. I dragged the new ITU Chair model onto it to overwrite the old version with the new one including the LOD 1 group of objects.
  4. I placed the chair prefab into the scene.
  5. I clicked Add Component button and chose LOD Group.
  6. In the LOD Group component, I clicked on LOD 1 and dragged the low LOD group from inside my model into the LOD group on the inspector.
  7. I clicked on the LOD 0 in the inspector and dragged the high LOD group from inside my model into the LOD group on the Inspector.
  8. In the Inspctor panel I clicked Prefab / Apply to migrate my new LOD grouped chair to all the instances of the chair prefab in the scene.
  9. I deleted and replaced any straggler chairs that weren’t using the prefab.

Testing

lodgroupsituchair

  1. I hit play and moved around checking that the switch from rounded to square geometry was as subtle as possible with no visible shifting of position, just straightening of lines. Notice the chairs in the foreground are smooth and the ones in the back of the room are straight. Chairs in the extreme distance are hidden, which I could change by making my lowest LOD still render the simple chair renderers.
  2. I checked my profile by clicking Stats in the game view and basked in the reduction of chairs from 1550 polygons to 154 each, for a reduction of about 150,000 polygons from the scene.

There’s more to optimize

Next step is to apply a mesh combiner on the chair geometries to make sure all the groups from Sketchup get turend into a single draw call. We’ll share that guide next.

 

Here’s the full LOD Group docs from Unity:

LOD Group

SWITCH TO SCRIPTING

As your scenes get larger, performance becomes a bigger consideration. One of the ways to manage this is to have meshes with different levels of detail depending on how far the camera is from the object. This is called Level of Detail (abbreviated as LOD).

LOD Groups are used to manage level of detail (LOD) for GameObjects. Level of Detail is an optimisation technique that uses several meshes for an object; the meshes represent the same object with decreasing detail in the geometry. The idea is that the low-detail meshes are shown when the object is far from the camera and the difference will not be noticed. Since meshes with simpler geometry are less demanding on the hardware, performance can be improved by using LOD judiciously.

LOD Group inspector

LOD Group inspector

Properties

The different LOD levels are visible in the horizontal bar with the camera icon just above it (LOD: 0, LOD: 1, LOD: 2, etc). The percentages in the LOD bars represent the fraction of the bounding box height relative to screen height where that LOD level becomes active. You can change the percentage values by dragging the vertical lines that separate the bars. You can also add and remove LOD levels from the bar by right-clicking it and selecting Insert Before or Delete from the contextual menu. The position of the camera icon along the bar shows the current percentage. The percentages in the LOD bars represent the thresholds at which the corresponding LOD level becomes active, measured by the ratio of the object’s screen space height to screen height. Note that if the LOD Bias is not 1 the camera position is not necessarily the actual position where LOD transits from one to another.

When you click on one of the LOD bars to select it, a Renderers panel will be shown beneath. The “renderers” are actually GameObjects that hold the mesh to represent the LOD level; typically, this will be a child of the object that has the LODGroupcomponent. If you click on an empty box (with the word “Add”) in the Renderers panel, an object browser will appear to let you choose the object for that LOD level. Although you can choose any object for the renderer, you will be asked if you want to parent it to the LODGroup GameObject if it isn’t already a child.

From Unity 5, you can choose Fade Mode for each LOD level. The fading is used to “blend” two neighboring LODs to achieve a smooth transition effect. However Unity doesn’t provide a default built-in technique to blend LOD geometries. You need to implement your own technique according to your game type and asset production pipeline. Unity calculates a “blend factor” from the object’s screen size and passes it to your shader.

There are two modes for calculating the blend factor:

Percentage: As the object’s screen height goes from the current LOD height percentage to next, the blend factor goes from 1 to 0. Only the meshes of the current LOD will be rendered. Cross-fade: You need to specify a Transition Width value to define a cross-fading zone at the end of the current LOD where it will to transit to the next LOD. In the transition zone, both LOD levels will be rendered. The blend factor goes from 1 to 0 for the current LOD and 0 to 1 for the next LOD.

The blend factor is accessed as the unity_LODFade.x uniform variable in your shader program. Either keywordLOD_FADE_PERCENTAGE or LOD_FADE_CROSSFADE will be chosen for objects rendered with LOD fading.

For more details on naming conventions see the Level of detail page.

Look at the example of SpeedTree trees to see how LODGroup is configured and how the SpeedTree shader utilizes theunity_LODFade variable.

At the bottom of the inspector are two Recalculate buttons. The Bounds button will recalculate the bounding volume of the object after a new LOD level is added. The Lightmap Scale button updates the Scale in Lightmap property in the lightmaps based on changed LOD level boundaries.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s