User Tools

Site Tools



This is an old revision of the document!

Level Design - Indoor Level Performance


This tutorial will show some steps on how to optimize an indoor level to get better performance.


Measuring performance can be hard. The main target is 60 FPS on a high end computer running at 1080p and 30 FPS on a low end computer running at 720p with low quality settings.

There are other things that are much easier to measure. Here is a list of goals for different parameters (in 1080p):

  • Total Memory Usage: ~700 mb (max 1024 mb)
  • Vertex Memory Usage: ~64 mb (max 128mb)
  • Draw Calls: ~400 (max 500)
  • Rendered Triangles: 1.0 million (max 1.5million)
  • Queries: ~50 (max 100)

Occlusion Culling

The only way to get good performance on an indoor level is to design it to make use of occlusion culling. Occlusion culling reduces the number of objects that needs to be rendered.

Occlusion culling is a way for the graphics engine to calculate which objects are visible from a certain position in the level. This is a complicated problem and the engine will not be able to solve this perfectly on its own. There are a few things that can be done to increase the efficiency of the culling.


An occluder is an object that is used to block the vision of the engine. All static objects are automatically set to be occluders, but dynamic objects are not. Some type of dynamic entities should be set as occluder to help the game. The most important ones are doors or objects that act as blockades. You should not set to many dynamic objects as occluders since it increases the draw call and queries. But it is better with to many than to few.

In order to see where the occlusion culling fails you can use the Debug Menu (F1) in Depth and select Render Only Occluders. This will show you what the engine sees when determining what is visible.


The image to the left shows what the player sees. It looks like only a single room is rendered. On the right you can see what the engine sees when calculating what is visible.


On the left you can see everything that is rendered when the door is not set to be an occluder, which is pretty much the whole level. On the right the door is set to be an occluder and most of the objects are removed. But it is still not perfect.

IsOccluder setting can be found under the Apperance tab for dynamic entities.

Room Positioning

Another way of making sure that the occlusion culling is effective is to try to separate rooms and corridors as much as possible.


Adding some space between rooms can help the occlusion culling determining which objects belong to which part of the level. The space does not need to be as big as in the image. The important part here is that the bounding volumes of the objects in one room should not intersect with the other room. This is very important for shadow casting lights.


In this image the two rooms are connected with a corridor without doors. If the player stands in one room he would be able to see the other room. The best solution here would be to add doors or other occluders. If that is not possible you can change the look of the corridor so that the player does not have direct vision between the rooms. Using a diagonal corridor would work as good as a zigzag one.



Directional light with sky and ground color should make up the base of the outdoor lighting.

Most outdoor levels also require the use of directional light shadows. This is a very expensive operation. To lower the impact of shadow rendering you will have to uncheck the “Cast shadows” checkbox for some types of objects.

Here is a list of object that should not cast shadows:

  • Small objects
  • Objects that are almost hidden in undergrowth
  • Objects that are only used as a silhouette
  • Objects that will always be far away
  • Big objects that the player can never reach

The objects selected in this picture are located above the player and can not be reached because of invisible walls. Shadow casting can be disabled for them without affecting the quality of the scene.

hpl3/tutorials/level_design_-_indoor_level_performance.1360581020.txt.gz · Last modified: 2013/02/11 11:10 by nebej