Tuning Source Engine LOD: From QC Blocks to Real‑Time Performance
Learn how to set up and verify model level‑of‑detail (LOD) in the Source Engine, understand its impact on frame rates, and avoid visual popping. A step‑by‑step guide with a QC example, trade‑offs, and practical checks for the game developer.
14 May 2026, 10:34 UTC

Why LOD Matters in Source Engine Games
When a map contains dozens of props or NPCs, the GPU can become saturated with draw calls and shader executions. The Source Engine mitigates this by letting you define multiple model variants that the engine swaps automatically based on camera distance. This is called level‑of‑detail (LOD). When a model is far away, the engine can render a simplified mesh, reducing vertex count and texture memory usage. The trade‑off is the risk of noticeable pop‑in if the thresholds are too aggressive or the low‑poly mesh looks too different.
Defining LOD in a QC File
LOD is configured inside the model’s QC file, which is processed by studiomdl to produce the .mdl binary. Each $lod block specifies a distance threshold and the geometry to use. Optionally, you can switch bones with $switchbone to keep animations working on the simplified mesh.
$modelname "props\myprop.mdl"
// High‑detail LOD (0‑200 units)
$lod 0 {
$body "body" "myprop_ref.smd"
}
// Low‑detail LOD (200+ units)
$lod 200 {
$body "body" "myprop_low.smd"
$switchbone "spine" "spine_low"
}
Key points:
$lod 0is the base level that the engine always loads.- Distances are in world units; 200 means the low‑poly version appears when the camera is farther than 200 units.
$switchbonemaps bone names from the high‑poly mesh to bone names in the low‑poly mesh, preserving animation transforms.- All bodies, textures, and materials referenced inside a
$lodblock must exist in the model’s resource folder.
Compiling and Enabling LOD in the Game
After editing the QC file, run studiomdl -includepath "path\to\source\game" -outpath "path\to\output\folder" "props\myprop.qc" (replace paths with your environment). This rebuilds the .mdl file with the new LOD data. The game executable must have r_lod enabled – it is on by default in most Source builds, but you can verify with the console command r_lod 1.
Verifying LOD Switching at Runtime
- Load a map that contains the model.
- Open the developer console and type
r_lod 1. The engine will draw colored outlines around each LOD level, helping you see the distance thresholds. - Walk toward the model and back. When the outline changes colour, the engine has swapped LOD.
- Use
modelinfowhile pointing the cross‑hair at the entity to confirm the current LOD level and bone state. The output will showLOD level: 0/1and any activeswitchbonemappings. - Run
showbudgetbefore and after enabling LOD to see the reduction in vertex count and draw calls. A noticeable drop indicates a performance gain.
Common Pitfalls and How to Avoid Them
- Popping: If the low‑poly mesh differs significantly in shape, players may notice a sudden change. Keep the silhouette similar or use a gradual LOD threshold (e.g., 250, 500).
- Bone Mismatch: Without
$switchbone, animations may break on the low‑poly mesh. Always map bones that change between LODs. - Texture Size: The low‑poly mesh can still reference high‑resolution textures, negating the performance benefit. Use lower‑resolution textures or a
$textureblock to override. - Missing LODs: If you forget to compile after editing QC, the game will still use the old .mdl. Always re‑run
studiomdland verify withmodelinfo.
When LOD Is Not Worth It
For small, static props (e.g., a single crate) the overhead of managing multiple LODs may outweigh the performance gain. Similarly, if a model is rarely visible or always within a few units of the camera, LOD can be omitted. Use profiling to decide: if showbudget shows negligible vertex count for the model, skip LOD.
Actionable Checklist
- Write QC with at least two
$lodblocks and$switchbonewhere necessary. - Re‑compile the model with
studiomdl. - Enable
r_lodin the game and user_lod 1to visualize. - Test in the target map, watch for popping, and adjust thresholds.
- Measure performance with
showbudgetand confirm a reduction in draw calls. - Document the LOD configuration in the model’s README for future maintainers.
By following these steps, you can harness the Source Engine’s LOD system to keep your maps running smoothly while maintaining visual fidelity.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.