LODs (Level of Detail) are essential part of game art. Well done LODs will ensure a smoothly running game with unnoticable switching.
There are couple of things you want to accomplish when making LODs:
- lower the number of drawcalls (this helps CPU)
- keep the appearance (this helps us to look like proffesionals ;) ...and prevents self-shadowing.
- simplify shaders - get rid of unnecessary effects like paralax, detail map, alpha blend and alpha test and so on (this helps GPU and Memory)
- lower the number of triangles (this helps GPU but is usually not a bottleneck)
With DX11 drawcalls are a big issue, so lowering it is more important than anything else. The second most important thing is for the LOD model to look as close to the original as possible. Since models are being switched while player is approaching them it is important for this switch to be unnoticable.
While LODs are great and all, it is also unwise to have too many of them on an asset. Because:
- switching LODs requires resources (streaming)
- during the switch both models are being rendered
How many LODs an object should have depends on the object. For small objets with low material ID count and reasonable geometry none are needed. Actually it is better not to have them! During the switch the engine has to render two objects and then blend between them. Also determining whether to switch or not takes some small amount of time. In case the model is of medium size and can disappear in some distance one LOD is just fine. And then two LODs are reserved for big objects like buildings, structures and so on. But this is just a basic guideline. In case you're not able to make good looking LOD while lowering drawcalls or triangles significantly it might not be worth doing it and vice versa, if you can save a lot by having more LODs, go for it.
In any case LOD1 has to have all the shapes of LOD0 present. This is because of SVOTI which uses LOD1 for voxelization purpouses. In case you omit something, that part won't oclude the rest of the world around it.
You have two main options for creating LODs in regard to lowering the drawcalls. Strip them or bake them. What to use depends on the original object.
When to strip:
- the object doesn't have a lot of materials
- getting rid of some materials won't be noticable from distance
- no expensive shaders are used or can be simplified (for example you can always switch off paralax, but truning off second UVs can be quite noticable)
When to bake
- LOD0 has a lot of materials
- object doesn't have big surface visible from distance (because baked lods have unique pixels in textures and you don't want to end up with 2k textures)
- most of the surface is not alpha tested... if only some parts are, it's better to bake two texture, one with alpha and one without. (you want to minimize the number of pixels on the screen that are alpha tested)
With both approaches you will end up with lower tricount. Make sure it's at least 66 % of the original, otherwise you won't be able to export it from max, but as always less is better. However keeping the visual similar to previous LOD is more important.
Naming conevntion of LOD meshes in 3ds Max: $lod1_XXX, $lod2_XXX etc., meshes are linked to the LOD0 mesh. In case of using Merge node, link the LODs directly to the Merge node
For more information, please see Cryengine Documentantion:
- LOD baking –
Tips for LOD baking
- Parts not visible from the distance (interiors, bottoms of the roof etc.) must use much less textures space, you have to downscale them in UVW editor manualy.
- Windows, doors - when LOD has removed windows and doors, you need to paint them into baked texture manually, just with some dark color (dark grey/black for windows, brown/grey for door)
- In texture, gaps between elements must be filled. Don't leave it black or white. You can use Dilation checkbox of LOD Generator tool in Cryengine or fill gaps manually (Flaming Pearl Solidify Photoshop plugin works the best ).
- If you can't omit alpha test, try to bake it on it's own smaller texture and use second material ID just for the alpha tested parts. It is usually a good trade-off.
- Last LOD (which will be used as uberlod too) must not have used alpha.
- When using alpha test, save diffuse texture as AlbedoWithCoverage and set AlphaTest checker in material accordingly so there are no black edges visible.
- LOD material - when baking ddna, you need to set specular and smoothness as usuall (don't leave it to default zero), when baking ddn, smoothness should be around 30, specular as usual. However ddna is strongly recommended.
- For baked LODs, do not use shadow proxy.
- Make sure the normal map looks as is should. It can be easily overlooked in regular view with certain lighting, but using normal view should show all problems.
- Check LOD mesh for holes in geometry. Typicaly roof, when looking from the bottom, you can often see through. If it's complex object, for example basefloor+interior+roof, you should check how the parts work together.
- Think ahead. If you create compound object (for example pile of logs), you can create LODs of single logs and build LOD while making LOD0 pile.
- Work with smooth groups. If original mesh have rounded corner with one smoothgroup and you will reduce it to sharp corner, you need to separate smoothgroups as well.
- When baking, creating new textures for subsequent baked LOD makes sense only if it is needed because of geometry changes. Doing it to make the texture smaller is not necessary. This is what mipmap streaming is for.
- Try to make LOD mesh as similar to previous LOD as possible. Sometimes the LOD mesh is slightly bigger which can cause self-shadowing artefacts during switching (see Talmberk tower here)
- Make sure that shadow proxy generating don't turn off shadows of LOD materials - LODs should cast shadows.
- In 3ds Max, put LODs into proper layer to keep the scene organized.
- In 3ds Max, move LODs under the original mesh (or Merge node) and set them different wireframe color (colors are now set automatically during max file opening).
- In editor, test LODs with LodRatio set to 255!
- Check LODs under different lighting/light orientation.
- Don't be too aggresive when deleting bottom faces – sometimes the object can be seen from the bottom even from the big distance (for example in Uzice, lots of houses are placed in the steep slope thus visible from the bottom)
- Unless the objects is very specific (Monastery for example), you must always assume someone will use it in the way or in the place you didn't intend/presume to. For example cart can be used upside down, so even the bottom part must look ok in LODs.
- If the LODs are not working for no reason, check for proper hierarchy in 3ds Max
Uberlod model is just a copy of the latest LOD. The tricount can become important here, as the actual merged uberlod cannot exceed 64 000 indicies or it won't be exportable. However if you keep it in hundreds it should be fine. Small objects doesn't need (must not have) uberlod model.
When creating uberlod model, use "_uberlod_" prefix.
- When repacking texture elements of uberlod, you MUST NOT rotate the elements. You can only translate and scale them, otherwise normal map will not work.
- Same as for LODs, interior parts should occupy less texture space.
More info regarding uberlods to be found here.
Some bad LOD examples
The LOD here saves a lot of triangles (from over 5000 to about 140), which is nice, but drawcalls are more important and it fails there (4 -> 3). It also keeps the alpha test altough it is hardly noticable. The appearance is quite different with support beams jumping in front of the wicker as well. Better aproach here would be to bake the LOD with mesh closely copying the silhouette while omitting the alpha test. Using up to 500 tris to mitigate the loss of alpha is totally okay here as it's still saving tons of geo. Fences like these are used often and in great numbers so saving another drawcall on them is a big deal.
These LODs are just badly baked. You can see how the normal channel changes between these models. From originaly flat wall it becomes round. Also the texture size of first LOD is quite low and the second LOD is thus not necessary.
LOD 0 LOD1 LOD2
LOD0 could already be optimized by lowering the amount of overdraw on those water lilies. But the main problem is, that this quite expensive object is not loosing any drawcalls between LOD0 and LOD1. Both the lilies and a decal masking the seam between grass and dirt could go away. Second LOD is not necessary and third could become the second, again loosing the decal, leaving us with 2 drawcalls.
Here, the LOD0 is already using four kinds of similarly looking grayish planks adding up to 6 drawcalls in total, but since it's the most imporant object in the whole game it probably deserves it. However for such a small object with a lot of drawcalls baking the first LOD is a must. With that done, the second LOD won't even be needed and we save a lot. During every switch this model generates 12 drawcalls, which is just too much. Also since all of these comes with doors in game, you can easily map the interior smaller in the UVs saving a lot of texture space which makes high quality LOD with little geo and texture space possible.
In this example of LOD1 mapping, you can see how interior (red) parts take way too much texture space.
Always check the baked LOD texture result. This is definitely not OK.
LOD1 is missing front part of the roof, you can see through, interior takes too much texture space a you can also notice strange black area on the beam:
As usually, set proper edges orientation:
For baked LODs, do not use one smoothgroup for angular objects. Baked normal map usually don't have enough resolution for compensation and the result looks very bad:
LOD1 beams tips have one smoothroup which is causing them to shine (compare to beams in LOD0 on the left)
Round objects (typicaly various beams) must be mapped in one piece (use ordinary cylindrical mapping, not automatic flatten!). Otherwise weird texture seams will happen
Skewed elements take too much texture space, make them horizontal/vertical: