Image generated with AI
Game-ready assets: polygons, LODs and draw calls
Diego Cortés
Author
To optimize a 3D model for games is not about stripping polygons until the mesh looks ugly: it is about managing four costs that are measured separately and can be audited before you touch a single face. Here is the budget, how to measure it, and the reductions that actually change your frame rate.
What optimizing a 3D model for games actually means
When an asset enters a real-time engine it starts paying four different bills, and each one is fixed with another tool. The first is geometry: triangles and vertices the camera sees in that frame. The second is draw calls: unique meshes by distinct materials, and every combination is one more order the CPU sends to the GPU. The third is texture memory, which depends on the size of each map, not on mesh density. The fourth is per-pixel cost: instructions and transparent layers piling up on every shaded fragment.
One mental rule organises the rest: the engine does not draw your model, it draws what the camera sees at that instant. Anything outside the frustum or hidden behind another object costs nothing, and that is where occlusion comes from. A game-ready asset is therefore not the one with the fewest polygons in the abstract, but the one that fits the budget of a specific project on specific hardware.
The budget: how much fits in one view (Epic's numbers)
Epic publishes reference figures for mobile: roughly 700 draw calls per view and 500,000 triangles per view for the whole scene. That half million was set as the ceiling for holding 30 fps on an iPad 4 and an iPad Air, and on weaker hardware the recommendation drops below 500 draw calls. In HMI projects the target is 100 and fewer than 50 is preferable.
Both numbers are read from the console: Stat RHI gives draw calls, and Stat D3D11RHI or Stat OpenGLRHI gives triangles per view. And a limit almost nobody remembers: mobile materials have 5 texture samplers, and using all five is expensive.
Careful: those are Epic's numbers for mobile. On PC and console the margin is different and depends on device, resolution and project; the method does not change. Universal budgets do not exist.
Step 1: measure before you touch anything
The temptation is to open the decimate modifier and drop the number.
In Blender
Turn on Statistics in the viewport overlays: it shows how many objects and how much real geometry the scene holds, with face and triangle counts. The same panel forces a useful question: how many materials does the asset carry, and how many texture sets? If a single piece carries nine materials, polygons are not your problem.
In Unreal
Stat RHI counts draw calls; Stat GPU, Stat Unit and Stat UnitGraph show milliseconds per thread and GPU, including the spikes that ruin a frame even when the average looks fine; Stat TextureGroup and ListTextures show where memory goes; Primitive Stats gives triangles and memory per primitive; and Memreport -full leaves the full report.
The view that exposes per-pixel cost
Shader Complexity (Alt+8) colours the screen by shading cost: green is cheap, bright red expensive, white or pink very expensive. That is where you see the overdraw of transparencies, which according to Epic can double or more GPU time without the triangle counter moving. Field detail: in Development builds the device console opens by tapping the screen with four fingers; in Shipping it does not exist.
Step 2: triangles and LODs without destroying the silhouette
Decimating in Blender
The Decimate modifier reduces vertices and faces with minimal shape change and shows the remaining faces. Collapse works with a ratio: 1.0 leaves the mesh intact, 0.5 keeps half the faces, 0.0 removes them all; the internal calculation runs on triangles, so a quad mesh keeps more faces than expected. Un-Subdivide undoes subdivision levels with an iteration count, where 2 equals one subdivision. Planar collapses by angle and lets you delimit by normal, material, seam, sharp edge or UV. If the mesh comes from sculpting or subdivision surface, retopology comes first (Blender, Maya): decimating a badly built mesh only spreads the damage.
LODs: the trigger is screen size
A LOD is not the same model, uglier: it is a mesh swap triggered by how much of the screen the object covers. In Unreal, Auto Compute LOD Distances calculates the thresholds, LOD Settings tunes them, and LOD Picker > Custom shows every level at once so you can compare silhouettes; the Static Mesh Editor viewport shows the Current Screen Size of each one. With Add Override for Mobile the transition happens earlier on mobile without touching the PC setup. And Nanite, which is virtualised geometry, does not remove the need for LODs: there are platforms without support and incompatible materials (see the Unreal Engine 5 guide for 3D artists).
Step 3: fewer materials, fewer draw calls
Epic uses a clear example: a well optimised car can be five or six separate meshes with one material each. What matters is the relationship, because draw calls depend on unique meshes per unique material. Ten objects sharing a material are still ten draw calls if they are not combined; one object with five materials is five draw calls.
The first reduction is the cheapest: merge objects in the DCC before importing, in Blender, Maya or 3ds Max. The second is unifying the texture set: bake several material IDs into one texture from Substance Painter and use instances, or separate zones with masks and vertex colour, cheaper than a texture mask and independent of resolution. The third is trim sheets and atlases: many UDIM tiles in real time mean many resources. Material instruction counts live in the Stats window of the Material Editor: fewer nodes mean lower per-pixel cost.
Step 4: textures at the right size (no more, no less)
Picking resolution by eye is the most common source of wasted memory. Epic proposes a method that removes the guesswork: lock camera and FOV at the real gameplay position, put a debug texture with a different colour per mip into the Emissive channel of an unlit material, and look at the asset from the real distance. The highest mip visible on screen is the native size your normal and AO maps need; anything above that is donated memory.
Rules that almost always hold: square textures in power-of-two sizes (256, 512, 1024) because they waste less, and verification with ListTextures and Stat TextureGroup. On compression, real-time formats compress blocks of pixels at a fixed lossy rate and the GPU decompresses on the fly: S3TC, ETC, ASTC and PVRTC are the same idea. Mipmaps are a precalculated chain of half-resolution images that speeds up rendering and reduces aliasing, in exchange for roughly 33% more memory.
The counterexample I use most in class: on mobile, an uncompressed 16-bit normal map takes eight times the space of a normal one and costs more per pixel than a slightly denser mesh.
Step 5: per-pixel cost (where you die without noticing)
Opaque materials are the cheapest thing that exists. Masked and translucent materials are another story: every layer gets shaded and overdraw accumulates. Epic recommends using them only where they cover little screen space, such as glass or car lights, and solving the rest with painted texture.
For weaker hardware there are two scaling tools that do not require duplicating assets: Quality Switch inside the material and r.MaterialQualityLevel, with values 0 Low, 1 High, 2 Medium and 3 Epic. Yes, 1 is High and 2 is Medium: worth memorising before writing a launch script.
Checklist before you call it done
In Blender: triangles with Statistics, materials and texture sets counted, no overlapping UVs, correct origin and scale. In Unreal: draw calls with Stat RHI in the heaviest view, LODs with their screen size reviewed, simplified collision, UV and tangent precision only when artefacts appear, and texture memory with Stat TextureGroup. Measure in the heaviest view of the game, not the most comfortable one in the editor.
What to watch on the platform
The curated collection has a family of videos that follows these steps: Profiling with Purpose and Workflows for Optimizing Live Games on Mobile for profiling; Mastering Sub-D and Low Poly 3D Modeling and Polygon Runway's Blender Game Assets for face counts; UVs and Bakes for baking.
Conclusion
Optimising is learned by measuring. The artist who can read a Stat RHI and say "the problem is draw calls, not triangles" is worth far more than the one who guesses by lowering numbers until the stutter stops. The project gives you the budget, the engine gives you the measurement, and the four reductions -geometry, materials, textures and pixels- are applied in that order.
I invite you to go through the video tutorials on the platform with this framework in mind: next time you watch someone optimise in real time, you will recognise which bill they are working on.