3D Design
Jun 2023
Inna Cherkashina

Optimizing Your Game: How to Process 3D Models

When creating a 3D model for a video game, modelers usually take into account various hardware and software limitations of the target platforms that will be running the game. When models are too complex, they can slow down processes on the device and ruin the player’s experience with delays and artifacts. In this case, 3D artists need to optimize the resources to boost the performance.

In this article, we’re going to cover such techniques as batching and LOD to help you produce a well-tuned 3D model

Key factors of optimization

Optimization is the process of reducing a 3D model’s file size to ensure a higher frame rate. An optimized game works at the same frame rate across a wide range of hardware – including low-end configurations – and provides a better gameplay experience.

Every model in a game consists of polygons that are converted into triangles during the rendering process. A higher number of polygons means that the assets are more realistic and detailed, but their rendering requires many more resources.

Inexperienced modelers often try to reduce the number of triangles in order to optimize the 3D model representation. Although the lower number of polygons per mesh can improve the performance, optimization is not always about squashing everything into 5,000 triangles.

Check statistics in the engine to find out the frame rate

Check statistics in the engine to find out the frame rate

You should always bear in mind that the most important factor here is the time spent rendering a frame. This critical background process can be evaluated by:

  • Frame Rate: Rate at which consecutive images (frames) are captured or displayed. It is expressed in frames per second (fps).
  • Frame Time: Time required to deliver one frame.
  • Draw Calls: Graphical commands which tell the GPU what and how to render (draw).
Frame Debugger (Unity) decomposes a frame and evaluates the number of required draw calls

Frame Debugger (Unity) decomposes a frame and evaluates the number of required draw calls

The number of draw calls is a very comprehensive parameter that shows the complexity of the frame. The more draw calls rendering has to push, the more time it takes to deliver one frame.

You should always focus on the number of draw calls you can have per frame based on your hardware and software requirements. Check this target value before you start decomposing the rendering process into separate commands.

The average number of draw calls per frame is as follows:

  • Mobile projects: About 100 on medium or high settings (advanced devices may deliver more)
  • PC and console games: from 500 to 5,000

For example, Battlefield and the third Witcher game push about 1,000-2,000 draw calls, while the same value for PUBG varies from a reasonable amount of 5,000 up to an enormous one of 50,000.

These figures may not be relevant now, as technical capabilities of modern devices change very quickly. However, you should always target a certain number of draw calls for your game because it can easily become a bottleneck.

How to reduce the rendering time

You can handle optimization in different ways depending on a particular render pipeline in your project.

Render pipeline is a model that describes what steps a graphics system needs to perform to render a 3D scene to a 2D screen. For example, Unity provides three pre-built render pipelines with different capabilities and performance characteristics, and you can also create your own system.

All pipelines are unique, complex systems, and each of them embraces optimization in its own way. However, you can use RenderDoc, Nvidia Nsight, or Intel Graphic Performance Analysis to check out frame rendering in a random PC game.

Generally, you can reduce the rendering time by:

  • Batching
  • Applying the Level of Detail
  • Avoiding Alpha Overdraw

What is batching

Batching means combining multiple objects into batches for simultaneous processing.

Look at the picture below: there are ten boxes and one tree in a frame. All boxes have the same shader, material, and number of polygons. One can assume that we will have eleven draw calls because there are eleven objects in the frame. In fact, this frame requires only three draw calls.

The system sees that we have ten identical boxes in the frame and puts them together into one mesh. When we play the game, the GPU commands our video memory to draw this mesh as ten separate boxes on the screen.

Depending on the situation, you can use either dynamic or static batching.

Dynamic batching works with dynamic objects. It is a built-in automatic process that analyses the geometry and groups small details such as small fragments separated from the wall.

Dynamic batching reduces the number of draw calls but requires more CPU resources as each frame is processed separately.

Most render pipelines in Unity provide dynamic batching for dynamic geometry, so you can use it if you need to draw a lot of small, similar objects. For example, thousands of fish in a frame in Abzu are actually particles, with their geometry additionally animated by a vertex animation shader.

Note that dynamic batching has very strict limits, and you can’t use it for heavy geometry with more than 900 vertices.

Static batching works with static objects and is usually performed manually. You need to specify that this object is static, so that it will never be changed or shifted.

Static batching doesn’t reduce the number of draw calls per frame. Instead, it reduces the number of render state changes between them as it transforms the static objects into world space—that’s why you can’t destroy a wall or move a chair in a vast amount of games.

💡 Batching is a very effective technique in terms of optimizing your game performance, but it has some drawbacks. For example, when you apply batching, you can’t use Occlusion Culling that allows you to skip drawing objects that are not visible to the camera, such as a box blocked by another larger box.

If you don’t want to use batching, you can always manually merge your geometry for a specific scene and render the entire location in a single mesh.

How to prepare objects for batching

Both dynamic and static batching require the objects to have the same shader, the material on this shader (see “Materials” in Unreal Engine), texture, and the lightmap location.

You need to combine individual textures into a single texture atlas; otherwise, the objects will be batched separately. Texture atlasing also helps to save on the time you would spend on uploading and downloading each texture.

The same thing happens with lighting because two identical boxes will be divided into two batches if they use different lightmaps.

In addition, you need to consider where the final material will be stored.

What is Level of Detail

Level of Detail (LOD) allows you to reduce the number of triangles rendered for an object as its distance from camera increases.

Although all LODs are produced automatically, each of them requires some space in memory, so it’s better to set a limit. Usually, four LODs are used:

  • LOD0: the original model that has the highest number of triangles
  • LOD1–2: used when the object is farther away
  • LOD3: a long-range model

You can also add LOD4 that will be a simple 2D sprite, and sometimes you need to make an extremely full-detail model for cut scenes that will have more polygons than LOD0. For example, a mug in one of the starting scenes of Dead Space 2 has a high number of polygons to avoid being displayed as a square, while similar objects in the game don’t have this level of detail.

LOD can split objects into different batches, so it doesn’t reduce the number of Draw Calls.

What is alpha overdraw and how to avoid it

Overdraw refers to the system’s drawing a pixel on the screen multiple times in a single frame of rendering.

A certain type of overdraw comes from transparent objects in the frame. The larger the transparency area in the frame, and the more transparent objects are stacked, the longer the render pipeline draws the final pixel because it has to redraw it every time. As the transparency information is stored in the alpha channel, the resulting overdraw is called Alpha Overdraw.

Alpha overdraw can significantly affect the rendering time, and you may need to add extra triangles to replace the transparent area, and to speed up the rendering process.

Optimization guidelines

Whenever you decide to optimize your model, you need to take into account lots of details before you choose a specific tool:

  1. Check technical requirements of the target platform because modern devices can provide better CPU and GPU performance and process larger amount of triangles.
  2. Focus on what the model is used for and how the player sees it in the game.
  3. Consider the technique in each specific context instead of reducing the number of polygons just in case.

You should always follow these three steps if you don’t want to waste several hours on optimization that doesn’t work.

No items found.
No items found.

You might also like

Join our social networks

Stay in the loop with all the latest happenings in the game development world?

Subscribe to our newsletter

Receive fresh news and useful articles about game dev directly to your inbox! Stay up-to-date with the latest trends and events in the industry, and receive exclusive tips

Wrong e-mail adress
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Subscribe to our newsletter

Receive fresh news and useful articles about game dev directly to your inbox! Stay up-to-date with the latest trends and events in the industry, and receive exclusive tips

Wrong e-mail adress
One more thing

Follow us on Instagram and we will send you invite to the course

Follow Instagram

Gift for registering a person a list of 10 tips for those who want to change their profession.

Oops! Something went wrong while submitting the form.