MeshLod        

 

This guide is for Ogre 1.10+ only! Previous versions have different interface!

What is Mesh LOD

Mesh LOD allows to swap the models to Low-poly models in far distance, which makes your game faster.
Ogre will automatically use Mesh LOD when you load a mesh file, which has LOD information in it. So basically you don't need to do any coding to use this feature, but you need to prepare your meshes!

What is Mesh LOD generator

Mesh LOD generator can generate Low-poly models automatically from High-poly models.

How to build it properly

You should be good to go with default CMake flags, but for tracing problems here are related CMAKE flags:

  • -DOGRE_CONFIG_ENABLE_MESHLOD: Enabled by default. If enabled, you can use LOD from a *.mesh file. If disabled, it will remove everything related to Mesh LOD. Reducing submesh size, entity size and reducing rendering overhead. MeshLodGenerator will force enable this option, so to turn this off, you need to disable building MeshLodGenerator too.
  • -DOGRE_BUILD_COMPONENT_MESHLODGENERATOR: Enabled by default. If this is enabled the MeshLodGenerator component is built.
  • -DOGRE_BUILD_TOOLS: Enabled by default. If you enable this and MeshLodGenerator then OgreMeshUpgrader is built.
  • -DOGRE_BUILD_SAMPLES: Enabled by default. If you enable this and MeshLodGenerator then the MeshLod editor sample is built.

How to use it for non-programmers

The best way to generate mesh LOD with visual feedback is to use the Mesh Lod sample in the Sample Browser.

  • Put your meshes and materials into Ogre/Samples/Media/models
  • Start up SampleBrowser and load MeshLod sample.
  • Select your mesh in the "model" combobox.
  • Change the "Reduced vertices" slider to the reduction where you want to create a LOD level.
  • Change the camera distance to the desired distance
  • Click on Add level to add the reduction amount with given distance
  • Repeat previous 3 steps to create all levels.
  • You can check the final mesh by clicking on "Show all levels". If you made the LOD perfectly, you see the triangle count dropping, when zooming out, while not seeing graphical errors.
  • If you are ready, click on "save mesh" to burn the LOD into the mesh file.



The fastest way to generate mesh LOD is to use OgreMeshUpgrader on the console:

  • Interactive mode: It will ask you for every LOD level detail and much more!
  • example: OgreMeshUpgrader -i athene.mesh athene.out.mesh
  • Generate autoconfigured LOD: no questions asked, just get instant performance.
  • example: OgreMeshUpgrader -autogen athene.mesh athene.out.mesh
  • If you don't use stencil shadows, I would recommend disabling Edge lists, because they increase the mesh file a lot! If you load the mesh, edge lists will also stay in memory and consuming resources.
  • If you use older Ogre version, but you want to use latest LOD generator algorithm for best quality, you can get it with -V option!
  • example: OgreMeshUpgrader -autogen -e -V 1.8 athene.mesh athene.out.mesh

How to use it for programmers

You can find lot of usage samples in Ogre. For example MeshLod sample, MeshLodTests, MeshSerializerTests, PlayPen.

initialize

NOTE: You can create it on the stack if you don’t enable lodConfig.advanced.useBackgroundQueue. Otherwise, when you free up the stack it will abort the LOD generation and you will not get any LOD for your mesh!

#include <OgreMeshLodGenerator.h>

...
new MeshLodGenerator();

usage

As a first step, I would recommend to read through OgreLodConfig.h to know all available options!
LodConfig inheritance (having a base/default LodConfig) can be done with copy constructor!

LodConfig config(mesh);
config.createGeneratedLodLevel(5, 0.5); // At 5 ogre worldspace units use 50% reduced mesh
config.createGeneratedLodLevel(10, 0.75); // By default, it is using DistanceLodStrategy and proportional reduction.
config.createManualLodLevel(15, "mesh_LOD3.mesh"); // Manual level created in blender, maya or 3ds max.
config.advanced.useBackgroundQueue = true; // Generate in background thread, later inject with framelistener.
MeshLodGenerator::getSingleton().generateLodLevels(config);

// Or you can use autoconfigured LOD:
MeshLodGenerator::getSingleton().generateAutoconfiguredLodLevels(mesh);

uninitialize

delete MeshLodGenerator::getSingletonPtr();

Extending MeshLodGenerator

Structure

MeshLodGenerator is built up of 6 components:

  1. LodData: The core of the algorithm, containing the Mesh network representation.
  2. LodCollapseCost: Provides an interface for collapse cost calculation algorithms (like curvature, quadric error, profiling, outside weight, normals)
  3. LodInputProvider: Initializes LodData based on a source (It can be mesh or buffered(for threading)).
  4. LodOutputProvider: Bakes the Lod to a target (It can be mesh, buffered, mesh+compressed and buffered+compressed)
  5. LodCollapser: This will reduce the smallest costing vertices to the requested amount of vertices. Creates/destroys faces.
  6. MeshLodGenerator: Frontend, which can receive LodConfig. It will create/run the required internal components to generate the requested LodConfig. Only this class is using the LodConfig.

Replacing a component

You can replace or inherit from any component by passing it to generateLodLevels() function as parameter.

virtual void generateLodLevels(LodConfig& lodConfig, LodCollapseCostPtr cost = LodCollapseCostPtr(), LodDataPtr data = LodDataPtr(), LodInputProviderPtr input = LodInputProviderPtr(), LodOutputProviderPtr output = LodOutputProviderPtr(), LodCollapserPtr collapser = LodCollapserPtr());


For example there is a hidden feature (which can't be enabled in LodConfig) to use Quadric Error Metrics instead of Curvature to calculate collapse cost:

gen.generateLodLevels(config, LodCollapseCostPtr(new LodCollapseCostQuadric()));

In the above example MeshLodGenerator will use every option from LodConfig, which is not related to collapse cost. This means outsideWeight, outsideWalkAngle and profile options will be ignored.

Internally MeshLodGenerator uses 2 steps:

  • _resolveComponents(): Creates the components which are still nullptr and configures them based on LodConfig.
  • _process(): Runs the components. This may be called on background thread depending on LodConfig.