Grouping and combining lots of small objects for performance benefits
Table of Contents
Batching PrinciplesThe engine has a feature to optimize the draw call number for lots of smaller objects. These can be combined, so the engine sees them only as a single object, which improves performance dramatically. For this to work, you must follow a number of simple rules.
Auto BatchingAuto batching groups a number of identical models together. The process is fully automatic, as long as you adhere to these limitations:
- Vertex count must be lower than 33 (see example below)
- no lightmaps nor dynamic lighting
- no skinned meshes (bones, joints)
- original materials (no script override)
- one material priority per batch group (different from the default 127, and also different from one another)
33 Vertices limitationThe most restrictive limitation is the vertex count. It is important to note that 32 vertices in 3DS Max are not automatically 32 vertices in ShiVa.
Statistics from Max:
Polys : 47
Verts : 32
Statistics from the ShiVa Editor:
Polys : 49
Verts : 47
ShiVa calculates the number of vertices as your GPU will process them. The vertex count for a graphics card is a combination of three pieces of information: Position, UV and Normal. 3DS Max only takes one into consideration, namely the position.
The normals at the top are different. We can count 45 normal vertices from the sides. Also, the top mesh UV vertices are not welded to the side ones, which results in 47 UV vertices - the number correctly calculated by the ShiVa Editor.
In order to have 32 vertices in both tools, you have to weld some of the vertices, and also change part of the texture. After modification, we get 32 vertices on both tools.
Runtime object combinerIf your objects are simply too large to meet the Autobatch criteria, you can still try to merge them manually. The merge is computed only one time, so during the game, the CPU will be free to do other things.
This method is very effective but has limitations: The objects you want to merge have to be simple (no children, not a group of groups), and objects must not have controllers (no AIs, no physics, etc).
CodeThe combiner take a group of objects so you have to create the root of the group, a dummy for example:
hGroup = scene.createRuntimeObject ( hScene, "" ) -- then, for each object you want to combine, parent it to the group: object.setParent ( hObject, hGroup, true ) -- now combine everything: hCombined = scene.combineRuntimeObjectsGroup ( hScene, hGroup ) -- you now have a clone of your models, you can remove the original group scene.destroyRuntimeObject ( hScene, hGroup ) -- and set the merged result visible: object.setVisible (hCombined, true )