Lesson 9.3Lesson 9.3 · Optimization & Performance
LODs, Draw Calls & Culling
The classic levers - instance, merge, cull and stream - that claw a heavy building back to frame rate
The GPU can draw a hundred million triangles. It struggles with ten thousand separate objects. Optimization is mostly the second problem.
Newcomers assume performance is about triangles. In an archviz scene it is far more often about draw calls - the number of separate objects the CPU has to describe to the GPU each frame. A model imported piece by piece from Revit can be thousands of individual actors, and every one is a phone call from CPU to GPU.
This lesson is the toolbox for the bottleneck the last lesson taught you to diagnose. LODs shed detail with distance, instancing and merging collapse draw calls, culling skips what you cannot see, and texture streaming tames memory. None are exotic - they are the classic levers every real-time artist reaches for, and knowing which one your profile is asking for is the whole craft.
Draw calls first (instance + merge), then cull the unseen, then LOD the far, then stream textures. Always re-measure after ONE change.
Draw calls: the number that usually hurts
A draw call is one instruction from the CPU to the GPU: 'draw this mesh, with this material, at this position.' Each one has fixed overhead on the CPU draw thread regardless of how many triangles it carries. So a scene of ten thousand tiny, individually placed objects can drown the CPU in draw calls while the GPU sits half-idle - the classic CPU-bound-on-Draw signature from stat unit. Reducing draw calls is the highest-value optimization in most archviz scenes.
The first lever is instancing. When the same mesh appears many times - 500 identical chairs, a facade of repeated mullions, a car park of bollards - an Instanced Static Mesh (or Hierarchical Instanced Static Mesh, which adds culling and LODs) lets the CPU describe the mesh once and hand the GPU a list of positions. Five hundred draw calls become one. The pixels on screen are identical; the CPU just stops repeating itself. Unreal will auto-instance identical static meshes in many cases, and the Foliage tool instances by design.
The second lever is merging. Different meshes that will never move - a cluster of fixed props, an architectural assembly - can be combined with Merge Actors into a single mesh with a shared material, turning many draw calls into few. The trade is flexibility: merged geometry moves and culls as one unit, so you merge things that genuinely belong together. A third quiet lever is shared materials - each unique material on a mesh is typically its own draw call, so a mesh with eight materials costs more than one with two. Consolidating materials and using texture atlases pulls the count down. Reach for stat rhi after each of these moves and watch the draw-call number fall - it turns an abstract technique into a figure you can see dropping, which is the fastest way to build an instinct for what each lever is worth.
Draw call = one CPU->GPU instruction. 500 chairs placed by hand = 500 calls. One instanced mesh = 1 call. Same pixels.
Culling: do not draw what you cannot see
The cheapest object to render is the one you never draw. Culling is the family of tricks that skips geometry the camera cannot actually see, and Unreal does several kinds automatically - your job is to help them work well.
Frustum culling drops anything outside the camera's field of view - the view frustum, the pyramid of what the lens can see. Look north and the building behind you is not drawn. This is automatic and nearly free. Occlusion culling drops what is inside the frustum but hidden behind something else - the furniture in the next room, blocked by a wall. Unreal computes occlusion each frame, and it works best when big solid occluders (walls, floors, slabs) genuinely block the view; a scene modelled as a hollow shell with gaps lets the engine see - and draw - everything behind it. Distance culling (via a Cull Distance Volume or per-object max-draw-distance) simply stops drawing objects past a set distance, ideal for small clutter that is invisible from far away - you will never see the drawer handles from across the plot, so stop drawing them at thirty metres.
The practical craft: model solid occluders rather than paper-thin hollow shells so occlusion culling has something to work with; set sensible cull distances on small props; and remember that in a wide-open scene with long sightlines, culling helps less, so you lean harder on LODs and instancing. Culling and drawing are two sides of the same budget - every object culled is time handed back to the frame.
Frustum: off-screen. Occlusion: hidden behind. Distance: too far/small. All three = drawing less to draw faster.
LODs: shedding detail the distance hides
For every mesh that is not a Nanite mesh - foliage, translucent surfaces, animated geometry, or anything on the classic path - Levels of Detail remain the workhorse. An LOD chain is a set of progressively simpler versions of a mesh; the engine swaps to a lower one as the object shrinks on screen, because a chair fifty metres away does not need its full triangle count to look right. Unreal can auto-generate LODs from a source mesh, or you can import your own.
The controls that matter are the screen sizes (how small the object must appear before each LOD kicks in) and managing the LOD pop - the visible snap when one level swaps to the next. Set switch distances too aggressively and viewers see geometry visibly simplify; set them too generously and you carry detail you are paying for and cannot see. Dithered transitions soften the pop. For whole clusters of buildings or props, Hierarchical LOD (HLOD) goes further: it merges distant groups of actors into a single low-detail proxy mesh, cutting both triangles and draw calls for far-off parts of a large scene at once.
Getting LODs right is a small craft of its own. Unreal's auto-LOD generation is a fine starting point - you set a number of levels and reduction percentages and let it decimate - but for hero foliage or a signature piece you may import hand-made levels that hold silhouette better. Watch the triangle percentage each level keeps and the screen size at which it activates, and always test by flying the camera the way a viewer actually will: a level that looks fine in a static shot can pop distractingly during a smooth walkthrough. Dithered or temporal transitions blend the swap so the eye never catches it.
Remember the division of labour from earlier in this module: Nanite gives you continuous, automatic LOD for opaque static geometry, so you do not author LOD chains for it. LODs and HLOD are for everything Nanite does not cover, plus for platforms or projects where you are not using Nanite. Knowing which mesh belongs in which system is exactly the judgement this module is building, and it is the difference between an artist who blanket-applies one recipe and one who reaches for the right system per mesh.
LODs = simpler mesh with distance, for non-Nanite geometry. Watch the pop. HLOD merges distant groups (fewer tris AND calls).
Texture streaming and putting the levers together
Geometry is not the only budget. Texture streaming manages video memory (VRAM) by keeping high-resolution textures on disk and loading only the mip level - the resolution - a surface needs at its current on-screen size. A 4K wood texture on a distant floor is streamed in at a low mip; walk up to it and the high mip loads. This keeps VRAM from overflowing, which matters enormously in texture-heavy interiors and doubly in VR, where memory is tight. When you see textures visibly 'pop' from blurry to sharp, or the console warns of a streaming pool over budget, you are watching the streamer work - raise the pool size (r.Streaming.PoolSize) if you have VRAM to spare, or reduce texture resolutions if you do not.
Now put it together as a routine, driven by the profile rather than by habit. If stat unit says CPU-bound on Draw, attack draw calls first: instance the repeated meshes, merge the fixed clusters, consolidate materials, and let HLOD collapse distant groups. If GPU-bound, lean on culling (solid occluders, cull distances), LODs (tighter screen sizes), lighter shadows and translucency, and texture streaming for VRAM. Always change one lever at a time and re-measure with stat unit and stat rhi, watching the draw-call and triangle counts fall. This measured loop - diagnose, apply the matching lever, verify - is how a heavy building that crawled becomes a smooth, walkable experience, and it is the same loop VR will demand at double the intensity in the next lesson.
Texture streaming = load only the mip you need; protects VRAM (critical in VR). Match the lever to the profile; re-measure each change.
Instanced Static Mesh
Drawing many copies of one mesh in a single draw call
Describe the mesh once, hand the GPU a list of transforms; the Hierarchical variant adds per-instance culling and LODs. Huge draw-call savings for repeated geometry.
Merge Actors
Combining multiple static meshes into one with a shared material
Turns many draw calls into few for geometry that never moves; trade-off is the merged result moves and culls as a single unit.
Occlusion & frustum culling
Skipping geometry the camera cannot see
Frustum drops off-screen objects, occlusion drops hidden ones; occlusion needs solid occluders (real walls) to work, not hollow shells.
Texture streaming
Loading only the texture resolution a surface currently needs
Keeps VRAM in budget by streaming mip levels; critical in texture-heavy interiors and in VR. Watch the streaming pool warnings.
Workshop - cut the draw calls on a heavy scene
You will take a draw-call-heavy scene, read the baseline with stat rhi, then apply instancing, merging and culling one lever at a time - re-measuring after each - so you see exactly how much each move is worth. This is the profile-driven optimization loop made concrete.
Unreal Engine 5, a draw-call-heavy scene, and the console (backtick) for stat unit and stat rhi. Instancing, Merge Actors and Cull Distance Volumes are all built in.
Goal: measurably reduce draw calls with matched levers Inputs: Unreal Engine 5 and a scene with many repeated/separate objects (a populated archviz level or your own piece-by-piece import) Time: ~40 minutes
- 1Baseline: type stat unit and stat rhi. Record Frame/Game/Draw/GPU and the draw-call and triangle counts. Confirm from stat unit that you are CPU-bound on Draw (if you are GPU-bound instead, note it - your levers will shift to culling and LODs).
- 2Find a mesh repeated many times (chairs, mullions, bollards). Replace the individual placements with an Instanced Static Mesh (or use the Foliage tool). Re-run stat rhi and record how far the draw-call count dropped.
- 3Select a cluster of fixed, never-moving meshes and use Merge Actors to combine them, consolidating materials where you can. Re-measure and record the further draw-call reduction.
- 4Add a Cull Distance Volume (or set per-object max draw distance) for small clutter, and confirm your big walls are solid occluders so occlusion culling works. Fly the camera and watch stat rhi drop as objects leave view.
- 5Compare final stat unit and stat rhi to the baseline. Write down which lever gave the biggest win and why the profile predicted it.
You’ll walk away with
A before/after table of stat rhi draw-call and triangle counts and stat unit ms at each step (baseline, after instancing, after merging, after culling), plus a sentence on which lever was most valuable for this scene and how the profile told you so.
Three altitudes on the same idea
Read the band that fits you — or all three.
Your biggest performance win usually costs you no visual quality at all: instancing and merging a piece-by-piece BIM import. A Revit model arrives as thousands of separate actors, and collapsing the repeated and fixed elements into instances and merged meshes can slash draw calls without changing a single pixel. Model solid walls and slabs rather than hollow shells, too - occlusion culling can only skip the next room if a real wall is blocking it.
Interiors are draw-call and texture heavy - repeated decor, many materials, high-res finishes - so instancing and texture streaming are your friends. Instance the repeated chairs, books and tiles; consolidate materials where finishes are shared; and let texture streaming keep your 4K fabrics from swamping VRAM. Set cull distances on small clutter the client will never see from across the room, and you reclaim frame rate the eye never misses.
These four levers - LODs, instancing/merging, culling, streaming - are the vocabulary of every real-time performance conversation, so learning them makes you fluent. The skill that impresses is not knowing they exist but matching the right one to a profiling read: draw-call problems get instancing and merging, GPU problems get culling and LODs. Practise reading stat unit and reaching for the matching lever, and you will optimize with intent instead of trial and error.
“Optimizing a real-time scene is mostly about reducing the polygon count.”
Do it yourself
Match each lever to the problem it solves - that is the exam this module sets.
- 1What is a draw call, and why can ten thousand tiny objects hurt more than one huge mesh?
- 2When would you instance a mesh versus merge actors, and what does each cost you in flexibility?
- 3Name the three kinds of culling and, for occlusion, what your model must provide for it to work.
- 4For which meshes do you still author LOD chains now that Nanite exists, and what is HLOD for?
- 5What does texture streaming protect, and why does it matter even more in VR?
The one line to carry out
Peer-reviewed journals & authoritative standards
- 01Level of detail (computer graphics) — Wikipedia, 2026.
- 02Back-face culling — Wikipedia, 2026.
- 03Texture mapping — Wikipedia, 2026.
- 04Unreal Engine 5 Documentation — Epic Games Developer Documentation, 2026.
You now have the levers to make a heavy scene run on a desktop. VR raises the bar sharply - two eyes, a higher frame rate, a shorter budget - and it also demands specific hardware. Next we face VR performance and the machine head-on.
The author
Amogh N P
Architect, interior designer, and creative polymath. Studio Matrx began in his notebooks — his vision of design made honest, useful, and open to everyone. Its Academy is written and taught in his memory, and free, forever.
More about Amogh →