# Levels of Detail (LOD)

> Learn the integrated LOD system in Babylon.js.

Source: https://doc.babylonjs.com/features/featuresDeepDive/mesh/LOD

Babylon.js comes with integrated support for level of detail.

This feature allows you to specify different meshes based on distance from the viewer (by default), or screen coverage.
For instance, here is how to define four levels of detail for a given mesh, with distance comparison:

```javascript
const knot00 = BABYLON.MeshBuilder.CreateTorusKnot("knot0", { radius: 0.5, tube: 0.2, radialSegments: 128, tubularSegments: 64, p: 2, q: 3 }, scene);
const knot01 = BABYLON.MeshBuilder.CreateTorusKnot("knot1", { radius: 0.5, tube: 0.2, radialSegments: 32, tubularSegments: 16, p: 2, q: 3 }, scene);
const knot02 = BABYLON.MeshBuilder.CreateTorusKnot("knot2", { radius: 0.5, tube: 0.2, radialSegments: 24, tubularSegments: 12, p: 2, q: 3 }, scene);
const knot03 = BABYLON.MeshBuilder.CreateTorusKnot("knot3", { radius: 0.5, tube: 0.2, radialSegments: 16, tubularSegments: 8, p: 2, q: 3 }, scene);

knot00.addLODLevel(15, knot01);
knot00.addLODLevel(30, knot02);
knot00.addLODLevel(45, knot03);
knot00.addLODLevel(55, null);
```

The first parameter used with `addLODLevel` defines the distance to the camera. Beyond this distance, the specified level is used.

Each level is independent and can have its own material.
By defining a level of detail as null, you disable rendering of the current mesh when it is viewed beyond the indicated distance from the camera.

When a mesh is used as a level of detail for another mesh, it is linked to it and cannot be rendered directly.

You can remove a LOD level with `removeLODLevel`:

```javascript
knot00.removeLODLevel(knot02);
knot00.removeLODLevel(null);
```

You can alternatively add LOD levels by specifying screen coverage cutoff limits. Screen coverage is computed as a ratio between 0 and 1 of the mesh's rendered screen surface area over the total screen surface area. This method has the notable advantage of being scale-independent compared to distance comparison, as a big object rendered from a long distance can still be big on the screen.

To specify that your LOD levels use screen coverage instead of distance, use:

```javascript
knot00.useLODScreenCoverage = true;
```

Now, all LOD levels cutoff values will be interpreted as screen coverages.

Be careful of two things, though:

First, values must be between 0 and 1 :

```javascript
knot00.addLODLevel(0.1, knot01);
```

Second, a bigger value means a bigger size on the screen, and thus a more detailed LOD. This is the opposite order from distance, where a greater distance means a smaller size and therefore a less detailed LOD:

```javascript
knot00.addLODLevel(0.7, knot01);
knot00.addLODLevel(0.1, knot02);
knot00.addLODLevel(0.01, knot03);
```

Try: [Playground: LOD Demo](https://playground.babylonjs.com/#QE7KM) - Simple example of using the LOD system.

## Using LOD and instances

By default, instances will use the LOD defined on the root mesh. You do not have to specify anything on the instances:

```javascript
const count = 3;
const scale = 4;

const knot00 = BABYLON.MeshBuilder.CreateTorusKnot("knot0", { radius: 0.5, tube: 0.2, radialSegments: 128, tubularSegments: 64, p: 2, q: 3 }, scene);
const knot01 = BABYLON.MeshBuilder.CreateTorusKnot("knot1", { radius: 0.5, tube: 0.2, radialSegments: 32, tubularSegments: 16, p: 2, q: 3 }, scene);
const knot02 = BABYLON.MeshBuilder.CreateTorusKnot("knot2", { radius: 0.5, tube: 0.2, radialSegments: 24, tubularSegments: 12, p: 2, q: 3 }, scene);
const knot03 = BABYLON.MeshBuilder.CreateTorusKnot("knot3", { radius: 0.5, tube: 0.2, radialSegments: 16, tubularSegments: 8, p: 2, q: 3 }, scene);

knot00.setEnabled(false);

knot00.addLODLevel(15, knot01);
knot00.addLODLevel(30, knot02);
knot00.addLODLevel(45, knot03);
knot00.addLODLevel(55, null);

for (let x = -count; x <= count; x++) {
    for (let y = -count; y <= count; y++) {
        for (let z = 5; z < 10; z++) {
            const knot = knot00.createInstance("knotI"),
            knot.position = new BABYLON.Vector3(x * scale, y * scale, z * scale);
        }
    }
}
```

Try: [Playground: LOD and Instances Demo](https://playground.babylonjs.com/#14ESWC) - Simple example of using the LOD system with instances.
