LOD Baking

Overview

Our new LOD baking tool allows you to bake down textures for your LOD's in-engine so that each LOD uses a uniquely mapped texture set.

This way of creating LOD's has many benefits:

  • Much easier to create the LOD geometry as you can ignore UV borders, smoothing groups etc.
    • All that is required is a low-poly cage around the object which in most cases can be auto-UV'd.
  • Because UV borders and smoothing groups can be ignored, polycounts can be slashed.
  • Number of sub-materials (and consequently drawcalls) can be reduced to one or two.
  • Complex geometry with lots of holes in it (e.g. a ladder) can be baked to alphatest textures.
  • Expensive shader options such as Blend Layer / Dirt Layer are baked into the texture so the LOD sub-material can be super cheap!
  • Although more unique textures are required, these can be fairly low-res (512x512 seems to be about right for most medium-sized things) and except in cases where you are looking at one object far away and a different instance of the same object close up, all the original textures used for the object can be streamed out, so memory footprint at any given time shouldn't increase.
  • In many cases normal maps and specular maps are not really required for the LOD, which further reduces memory footprint.
  • And, it looks better!

When you consider that the original LOD1 for this object (made in the traditional way) was 3435 tris and still used 5 sub-materials, the benefits are clear.

A video of the results can be seen here:

Making your LOD's

Because by using this technique we are able to reduce polycount and drawcalls so significantly, in many cases you may only need to make one LOD level. On average our new LOD1s created using this technique were about the same polycount as the final LOD level when it was done "traditionally". Things that have very 'polygon-heavy' silhouettes or will be seen miles in the distance may require more LOD levels, but for the sake of this tutorial we will assume we are just making LOD1.

Just to be clear, when referring to LOD0, that means the highest detail model.

If you do need to make further LOD levels, you can just use exactly the same technique and bake unique textures for each LOD level. Remember that the further away something is, the smaller the baked texture can be!

Geometry

For simple objects with no alphatest materials or small detail that could be baked to alphatest (e.g. ladders), your LOD just needs to be a simple cage for the object, using as few polys as possible but also avoiding any significant areas of overlapping geometry because this will waste UV space and make your resulting texture look lower res.

The key thing is to preserve the volume and silhouette of the object whilst avoiding overlapping geometry, everything else is unimportant.

I would advise starting with a simple object like this one to get the hang of how it all works before attempting anything where you want to bake to alphatest, or re-use texture space or anything fancy.

Here is an example:

As you can see, even with all the geometry cut in rather than overlapping, the polycount can be massively reduced. Obviously this is quite a boxy example, but on average I was able to reduce most polycounts to about 10%-15% of LOD0 without significantly affecting the volume or silhouette.

In most cases I would generally advise rebuilding the LOD1 mesh from scratch rather than attempting to reduce the polycount of the LOD0 mesh, but this depends on the model to some extent. Models that are very topologically sound to begin with (eg characters) can potentially use the "Multires" modifier to reduce polycount and generate the LOD1 mesh, but for something like the example above it just generates a lot of issues and you are far better off building it manually, it doesn't take long.

The "Freeform" modelling tools in Max 2012 can be very useful for generating topology based on an underlying mesh - you can just kind of "draw over" the LOD0 mesh to create the LOD1 mesh.

UV's

Unless you want to do something special (like re-use some uv space or have different texture res in different places, more on which below) you can literally just apply an Unwrap UVW modifier and do a Flatten Mapping, or any other applicable auto-mapping technique that will give you unique UVs with no overlaps. Don't worry about UV seams or anything like that.

These were the settings I used - you can usually get away with the spacing being quite low which will give you a bit more texture resolution.

Material

Each LOD needs at least one unique sub-material. In most cases, one will be plenty but there are certain instances where you may require more:

  • When a sub-material on LOD0 is LOADS more/less shiny than the others - e.g. chrome and brick.
  • When you want to bake parts of the model down to an alphatest texture. This is handy for ladders, girders, railings, vegetation etc.
  • When a simple tiling texture (e.g. no blend shader / dirt shader) is used extensively on LOD0, it may be more sensible to just re-use these parts of the model on LOD1 rather than waste texture space baking them down.

Remember, the fewer sub-materials you have the fewer drawcalls your LOD will require, so use as few as possible!

So, add your LOD sub-materials to your object's material, and apply them to your LOD1.

Make sure every part of the LOD1 model you want to bake (usually all of it) has a special LOD sub-material assigned.

Export

  • Name your LOD1 geometry $lod1 and parent it under the render mesh as usual.
  • Export!

So to recap...

In a simple case like the air-con unit above, all you need to do is:

  • Build the LOD1 geometry.
  • Auto-UV it.
  • Create a new sub-material in Max (strictly speaking you can skip this step and just apply a new matID number to the LOD1 geometry, but its a bit tidier this way and will be clearer for anyone else working on the file after you)
  • Assign that material ID to the LOD1 geometry.
  • Parent the LOD1 geometry under the render mesh and name it $lod1.
  • Export!

Baking the textures

Setting up materials in the editor

Open the level your asset is in, or alternatively just drop it into a test level.

Select your asset.

Open the Material Editor (hit 'm').

Hit the "get material from selection" button to load the correct material.

Right click the material in the list and choose "Set number of sub-materials".

Add as many new LOD sub-materials as you need (one in the simple case of the air-con unit).

Name them assetname_lod1 or assetname_lod1_alpha if you are using an alphatest material.

  • The reason to add the assetname is just to distinguish between LOD's for different assets that use the same material.

You should end up with something like this:

Using the baking tool

With your object still selected, go to View -> LOD Baker

You should see a window like this pop up:

As you can see, the correct cgf is already referenced and the sliders to select the source and target LOD's will be set to LOD0 and LOD1 by default, which is what we want.

512x512 is a good starting resolution for most reasonably sizeable objects, but try out lower resolutions too to see if you can get away with it - you may be surprised!

Note that the TIFF baked out will be twice this resolution but will be setup to downsize on conversion to dds. This is just to get some free antialiasing/supersampling.

Unless there is some weird and very good reason to change them, leave the texture paths and filenames alone. The defaults are good.

We aren't baking an alphatest texture right now (more on that later), so leave the Bake Alpha Channel box unchecked.

We have to select the sub-materials on the lod that we want to bake (in case we are baking some parts non-alphatest and some parts alphatest, or in case we have re-used a tiling texture in the LOD that we want to ignore).

But for now we only have one sub-material, so tick Bake this sub-material on it. Then hit Bake and Save.

In a few seconds, some baked textures should appear below the options!

  • In certain cases (when shaders haven't been compiled) you may get odd/no results on the first bake. If so, try baking again before assuming it's broken!
  • If the LOD Baker complains about overlapping UVs, make sure you haven't got any nGons in your LOD1 model as these can show up as false positives.

If you want to get a better look at the textures, you can hover the mouse over them for a full size preview.

But even better, hit the Assign to Material button to assign the just-baked textures to your LOD sub-material and see the results in game.

Hopefully it will look perfect! If it doesn't there are a few possible reasons why below.

Issues with LOD transition
  • If decals appear too dark/opaque when the object is transitioning from one LOD to the next.
    • Don't worry, this is a known issue with the dissolve and will be fixed.
  • Shadows may also be slightly problematic during the dissolve transition as it will be using the shadow from LOD1 whilst drawing LOD0 or vice versa.
    • This is harder to address, but we'll try!
  • You can turn the LOD dissolve transition off by typing e_dissolve 0 into the console. This can be helpful to establish if the problem is with the LOD itself or the transition.
Issues with the texture bake
  • As mentioned before, the first bake of an object you do will sometimes give strange/no results due to shaders not being compiled.
    • Redo the bake - if redoing the bake doesn't make any difference, then this isn't the problem!
  • If the texture appears to have "missing bits", you can adjust the ray length parameters per sub-material. It works like this:
    !raylengthexample.jpg!** This should be fairly familiar to anyone who's ever baked a normal map - and you've all done that, right?
    • The LOD Baker moves out from the surface of the LOD1 model (following the normal) by the distance specified by Ray Start Dist
    • It then fires a ray into the LOD0 model and if it hits anything it writes out the diffuse, normal and specular value at that point to the baked texture.
      • However if it hasn't hit anything by the time the ray is as long as the distance specified by Ray Test Length, it will assume there's nothing there.
    • In the above example, you can see that the Ray Test Length needs to be increased to prevent a miss!

Once you have used the "Assign to Material" button once you can just keep re-baking the textures and they should update automatically on the object as they are already assigned. No need to do "Assign to Material" every time.

Issues with the material
  • You may find that your specular looks more or less intense on LOD1 than it does on LOD0. The main reason for this will be differences in the material setup.
  • Obviously you are often replacing many sub-materials with just one, and if they all have different settings it's never going to be perfect.
  • However, finding the "main" sub-material used on LOD0 and copying ONLY the following settings should work pretty well:
    • Fresnel settings.
    • Glossiness.

Optimizing the material

In very many cases, you will be able to remove the specular and normal maps without much visual impact and if you can, you should!

  • Performance is very often limited by pixel cost on the GPU, and removing maps makes the pixels cheaper AND saves memory!

In the case of the specular map, you will probably want to replace it by using the SpecFromDiff controls to generate a spec map from the diffuse.

  • In order to make these parameters appear you will need to remove the spec map from its slot and then check and uncheck a shader checkbox to reset the UI.
  • You can often get very convincing results using just a diffuse map and SpecFromDiff, so take the time to try it out.

More complex examples and advanced usage

Baking to alphatest

The LOD Baker supports baking to alphatest polys and this can be very useful for simplifying complex geometry with lots of little holes in (eg ladders, railings etc) or multiple layers of existing alphatest.

The watertower you can see in the picture at the top of the page and in the video is a good example of using alphatest baking.

It's generally a good idea to avoid having alphatest polys covering large areas of the screen because of the overdraw they create, so in some cases you may be better off leaving solid geometry as geometry if there are large spaces in between as on the girders at the bottom of the tower.

However, in this case the base was already covered with a lot of alphatest vegetation so baking the whole thing to a single layer of alphatest made sense.

As we don't want to use alphatest blending on opaque areas (because it costs more), it usually makes sense to have two LOD sub-materials and bake two separate texture sets.

Baking
  • After baking your opaque sub-material as normal...
  • Check the Bake Alpha Channel option and select your alphatest LOD submaterial for baking.
    • Remember to deselect the opaque sub-material too!
  • When baking to alphatest, any rays that 'miss' (see diagram above) will be regarded as transparent pixels and written to the alpha channel as black.
  • You may need to fiddle with the ray start dist and ray test length parameters to get the results you want.
  • In some cases, you may be unable to find ray values that work for the entire mesh, in this case:
    • Either bake the texture twice with different ray-lengths and put the working bits together in photoshop
    • Temporarily apply a new sub-material to the polys you want to use different ray-lengths, set the options differently per submat, and bake them both simultaneously.
  • Once baked, make sure and adjust the alphatest parameter on your alphatest LOD sub-material to see the results!

In most cases, using "two-sided" for alphatest is a BAD IDEA because it will be incorrectly lit the same both sides. A better option is to duplicate the geometry and flip the normals, then move one set of UVs (the side you don't want to bake from) out of the 0-1 range by exactly 1 so that it will use the same part of the texture but won't bake.

Re-using texture space

In two-sided cases as above and also in some cases where tiling textures or repeated geometry have been used, it's a bit of a waste of texture space to bake the LOD texture out entirely uniquely as the resulting bits of the texture will be the same for each repeat.

The legs are baked to alphatest boxes, but each face on the box is actually the same and then is repeated again for the other legs.

If we laid all the UVs out independently it would take up a lot of texture space for something we know is repeated.

Instead, we can simply layout each face in the same UV space and have them share the texture, like so:

If, as in this case, it isn't important which one gets baked you can just leave them overlapping and ignore the "overlapping UVs" warning in the LOD Baker. The LOD Baker will just choose a face at random to bake to.

If you want to control which face is baked, you can move the other UVs outside of the 0-1 range by exactly 1 (or 2, or 3 - any whole number basically). This way, they still use the same texture space but will be ignored when baking.

See Element Properties Rollout section on this page.

UV groups are a good way to preserve UV overlap while using the automatic UV packing functions in max.

Making some parts of the model higher res than others

Another thing you may want to do is maximise the efficiency of your LOD texturing by reducing the amount of texture space used for faces that are not very visible on LOD1. They need something on them or you would see holes, but the resolution is fairly unimportant.

In this case, you can simply scale the different UV clusters until you have the desired ratio between the highres and lowres parts.

Then repack the UVs using Pack UVs, but make sure Rescale Clusters is un-checked.

Overall the UVs will be scaled and packed as normal, but the difference in resolution between the clusters will be maintained.