Documentation

Support

Asset Transformer SDK


User Manual

Python API

C# API

Changelog

Discussions

Asset Transformer SDK


LOD generation guidelines

Learn how to generate Levels of Detail (LODs) for optimal real-time rendering performance.
Read time 3 minutesLast updated 4 months ago

Why generate LODs?

Levels of Detail (LODs) are multiple versions of the same 3D model with varying polygon counts. Real-time engines automatically switch between these versions based on the object's distance from the camera, dramatically improving rendering performance. Key benefits of LODs:
  • Better frame rates - Distant objects use fewer polygons, reducing GPU workload
  • Larger scenes - Support more objects in a scene without performance degradation
  • Scalable performance - Automatic quality adjustment based on viewing distance
  • Memory efficiency - Only high-detail meshes are used when needed
Important
LOD generation is performed after optimizing your LOD0 (master model) and before exporting. Always optimize your LOD0 first using the optimization guidelines to establish the best quality baseline.

LOD generation vs optimization

While both LOD generation and optimization reduce polygon count, they serve different purposes and use different approaches: Optimization (LOD0):
  • Goal - Create the best quality model within performance constraints
  • Approach - Conservative reduction, preserve visual fidelity
  • Philosophy - Balance quality and performance for close-up viewing
LOD generation (LOD1+):
  • Goal - Create highly simplified versions for distant viewing
  • Approach - Aggressive, destructive reduction
  • Philosophy - Maximize performance, visual quality is secondary
Note
LOD generation is intentionally aggressive and destructive. Lower LOD levels may have visible geometry simplification, missing details, or simplified materials. This is acceptable because these versions are only used when objects are far from the camera.

1. Automatic LOD chain generation

The most common approach is to generate a chain of LODs using progressive decimation. Check the following example to automatically create multiple LOD levels:
from pxz import core, algo, scene, polygonaldef generateLODChainCommon(occurrences, count): partOccurrences = list() for occ in occurrences: partOccurrences = partOccurrences + scene.getPartOccurrences(occ) partOccurrences = set(partOccurrences) lodOccurrences = [[] for i in range(count + 1)] # init empty list of lists processedParts = list() for partOcc in partOccurrences: partComp = scene.getComponent(partOcc, scene.ComponentType.Part) if partComp == 0 or partComp in processedParts: continue mesh = scene.getPartMesh(partComp) if mesh == 0: continue if not polygonal.getMeshDefinition(mesh).triangles: continue processedParts.append(partComp) owner = scene.getComponentOccurrence(partComp) # returns the occurrence that "owns" the component name = core.getProperty(owner, "Name") occ0 = scene.createOccurrence(name + "_LOD0") scene.setComponentOccurrence(partComp, occ0) scene.setParent(occ0, owner, addInParentInstances=True, worldPositionStays=False) instances = scene.getInstances(occ0) for instance in instances: lodOccurrences[0].append(instance) for i in range(1, count + 1): lod = scene.createOccurrence(name + "_LOD" + str(i)) partClone = core.cloneEntity(partComp) scene.setComponentOccurrence(partClone, lod) scene.setParent(lod, owner, addInParentInstances=True, worldPositionStays=False) instances = scene.getInstances(lod) for instance in instances: lodOccurrences[i].append(instance) if len(lodOccurrences[0]) == 0: raise Exception("This process works for meshes only (requires the selected parts to be tessellated first)") return lodOccurrencesdef generateLODChainTarget(occurrences: list[int], ratios: list[int]): try: core.pushProgression(len(ratios) + 1, "Generate LOD Chain") lodOccurrences = generateLODChainCommon(occurrences, len(ratios)) for i in range(len(ratios)): algo.decimateTarget(lodOccurrences[i + 1], ["ratio", ratios[i]]) core.stepProgression() except Exception as e: core.popProgression() raise e core.popProgression()ratios = [50, 25, 10] # LOD1: 50%, LOD2: 25%, LOD3: 12%generateLODChainTarget([scene.getRoot()], ratios)

How it works

The script creates multiple LOD occurrences for each mesh:
  1. LOD0 - Your optimized master model (highest quality)
  2. LOD1 - First simplified version (50% of LOD0 triangles)
  3. LOD2 - Second simplified version (25% of LOD0 triangles)
  4. LOD3 - Third simplified version (10% of LOD0 triangles)
Each LOD is stored as a separate occurrence in the scene hierarchy, making it easy to export LOD groups for Unity, Unreal Engine, or other real-time engines.
Tip
Start with 3-4 LOD levels. More LODs provide smoother transitions but increase memory usage and export file size. Always test LOD switching distances in your target engine to ensure smooth transitions.

2. Advanced LOD generation

For the farthest LOD levels (typically LOD3 or LOD4), you should generate a single mesh with a single baked material to achieve optimal performance with just one draw call. Recommended approach:
  1. Single mesh
  • Merge and decimate - Combine all meshes into one, then apply aggressive decimation
  • OR use retopology - Generate a simplified mesh using retopology functions like Proxy Mesh
  1. Single material - Create a single baked material from LOD0 using the bakeMaterials function
This approach provides significant performance benefits:
  • One draw call - The entire object renders in a single GPU call
  • Minimal overhead - Use small resolution texture and a small number of polygons
Tip
Only apply this aggressive single-mesh approach to the farthest LOD levels. Closer LODs (LOD1-LOD2) should maintain separate meshes and materials for better visual quality during transitions.