Log inGet started
Package

meshLod.package

Newest version

This package holds more than this page lists. See all of its files in its world.

readme.md

meshLod

A mesh costs the same to draw at 200 m as it does at 2 m. This package picks a cheaper mesh once the subject stops covering enough of the frame for the difference to be visible.

What decides the level

The fraction of the viewport's height the subject's own bounds span:

fraction = radius / (distance * tan(fovY / 2))

radius is half the diagonal of the entity's world-space box, so it holds for any proportions, and it already includes the entity's scale. Selecting on this rather than on distance means a boulder and a pebble drop to their cheaper meshes at the ranges their sizes earn, and a scene that changes field of view re-selects without any threshold being re-authored.

Authoring

Add MeshLod beside a Model. The mesh the Model already carries is level 0.

entity.find("rock").component.add("MeshLod", {
    lod1 = "@builtin::meshes.rock_mid", screen1 = 0.25,
    lod2 = "@builtin::meshes.rock_far", screen2 = 0.08,
})

screenN is the fraction below which that level takes over. A gap ends the chain — setting lod3 while leaving lod2 empty stops at level 1, rather than silently skipping the level that was meant to draw.

hysteresis (default 0.15) is the extra span required to climb back to a richer level, as a fraction of the threshold that was crossed. Leaving a level happens at the threshold; returning to it takes 1 + hysteresis times that.

Reading the state

@builtin::systems.meshLod.meshLod owns the selection, so it can be measured without a camera:

local MeshLod = require("@builtin::systems.meshLod.meshLod")

MeshLod.screenFraction(1.5, 40, 60)         -- what a subject spans
MeshLod.selectLevel(0.08, {0.25, 0.10}, 1, 0.15)  -- which level that earns
MeshLod.levelOf(id)                          -- what an entity draws now
MeshLod.stats()                              -- every tracked entity at once

Removing the component restores the mesh the Model started with.