- Naive version: measure distance from the camera. This works fine if your field of view is constant, but our cameras were all over the place. In particular the TV replay cameras used a very narrow field of view (which is the same thing as a telephoto lens) so distant bikes would appear large on the screen.
- Better version: project the extents of each object into screen pixels. Anything higher than 80 pixels might get high detail, while between 20 and 80 pixels is medium, and we use the low detail model for objects smaller than 20 pixels.
Math note: the screen size of a 3D object is proportional to (1 / DistanceFromCamera / tan(FieldOfView / 2)).
This provides consistent visual quality (you never see a low detail model drawn large enough to look ugly), but not consistent performance. If a TV camera with a telephoto lens looks down a straight section of track, all 20 bikes could end up a similar size on screen, but the framerate would plummet if we drew them all at high detail!
- MotoGP version: sort objects by distance from camera, then allocate LOD on a first come, first served basis. The closest 4 track sectors get high detail, the next 6 get medium, and the remainder get low detail.
This provides consistent performance (we never draw more high detail models than we can afford) but not consistent visual quality. When the TV camera sees all the bikes coming down that straight, the ones at the back end up with low detail models drawn so big that you can see all the flaws. But hey. Framerate was higher priority, so this was a good tradeoff for us.
Note that when all the bikes are far away, this algorithm chooses high detail for some even though medium could suffice. We didn't care about that, because the goal was to improve worst case performance in order to maintain a steady 60 fps. There are no prizes for going faster than 60, so no point optimizing scenarios that are already the best case.
LOD selection is a classic case where hysteresis is useful to avoid popping, but I can't remember whether we implemented that in MotoGP.