For some time now, I’ve been exploring how to establish the most efficient method for rendering meshes on the screen. Instead of solely relying on mesh density, I’m aiming to determine the draw distance using a more scientific approach, considering the mesh’s size on the screen.
Level of Detail (LOD) is a crucial technique for optimizing graphics performance. It involves replacing a more expensive mesh with a cheaper one as the distance from the camera increases. Ideally, you want to see a high-resolution mesh up close, but as an asset becomes smaller on the screen, optimizing the mesh becomes more important. When executed correctly, you won’t notice any visual difference, and it’s also more cost-effective to render, creating a win-win situation.
Would it be practical to create an infinite number of LODs? Not really.
They require additional storage space on disc, which can be a concern. Additionally, loading them into memory puts more strain on the CPU and GPU. It’s a delicate balance to keep in mind. Furthermore, at a certain point, the mesh becomes too small to be rendered on screen effectively, so it’s best to set the maximum asset draw distance at that threshold.
There are several methods to determine the maximum LOD distance. One method calculates the distance in units like centimeters or meters. The other option is based on screen size, which is more adaptable as it considers platform and render resolution. For instance, rendering for HD versus 4K displays depends on render resolution for detail visibility, while physical distance remains constant.
This approach ignores any mesh-related costs, such as pre-optimized triangles with maximum area triangulation or the initial mesh cost.
However, this method is not foolproof. Factors like mesh silhouette changes and unmatched normals per level of detail (LOD) can noticeably affect lighting between meshes.
The method outlined here is based on unit distance measured in meters and can be implemented in your Engine’s API or in Maya. I begin with the highest visual mesh level of detail (LOD), which is L0, and calculate the diagonal of the asset to provide a rough estimate of its size, although there are exceptions, such as more rectangular assets, where this method may not be entirely accurate. Nevertheless, I do this because the draw distance needs to be effective from various visible angles.
To determine the maximum draw distance, we input the diagonal and the target size on screen (in percentage). For the L0, I set the display size to 90%; you could say 100%, but that would trigger the L1 if the asset is visible from top to bottom of your screen, which is extremely close. The 90% provides some breathing room.
The L0 is always set at 0 meters since it’s the closest to the camera. However, we want to switch to the L1 mesh at a specific distance, and that’s where the ‘maximum draw distance value’ comes into play. This value determines the distance at which we transition to a lower LOD. We continue this process until we reach the lowest LOD in the set.

Using trigonometry, I can calculate the distance of the asset to the camera at a given percentage by utilizing the diameter.
pseudo code diagonal = ∛(0.075² + 0.157² + 0.167²) = 0.387m CalculateDistance(inSize=diagonal, inScreenSpacePercentage=100, inFovDegrees=45.0, inVerticalResolution=1080): ratio = inVerticalResolution / 1080 # compensate for 4k or FullHD screens # distance to see the asset, top to bottom distance_to_object = (inSize * 0.5) / (tan(inFovDegrees * 0.5)) distance_by_screensize = distance_to_object * 100 / inScreenSpacePercentage max_distance = distance_by_screensize * ratio return max_distance
What about the other LODs, you might ask?
With appropriate reductions, I aim for a 50% triangle reduction with each LOD step. Therefore, if I multiply the calculated distance times two, it mostly works. However, there are always odd cases when the poly count is already too low, which can break the silhouette or the normals, and this approach won’t hold up completely.
You might be wondering why you should bother learning how to calculate it yourself when Simplygon or Unreal can do it for you?
In my opinion, you should be aware of the following points:
- Understanding the underlying principles allows you to troubleshoot issues when automated tools don’t produce the desired results.
- By knowing how to calculate it yourself, you can tailor the process to fit specific project requirements, which might not be fully supported by generic tools.
- Relying on your own skills ensures you’re not limited by the availability, cost, or licensing of specific tools like Simplygon.
To estimate the draw distance based on the cost of the GPU, you can calculate the distance using the shortest edge lengths of the asset. This means you collect all the edge lengths of the LOD mesh, calculate the average length, and then adjust the distance based on the target platform’s requirements. For instance, if the average length of an asset at a 5-meter distance is 1 centimeter, the mesh is likely too dense, and you’d need to reduce the distance to avoid it becoming a bottleneck.
Are there any flaws? I’m sure there are. But please feel free to comment and discuss or provide your feedback.