Batching again

Started by
1 comment, last by SimmerD 18 years, 9 months ago
In these forums the topic of batching often comes along. However, this one is slightly different. I'm going to play the devil's advocate and state that batching might not be good for general world geometry. Batching is good if you have largish amounts of polygons (in the range of 1000 vertices or up) with the same material properties (shaders, textures, lighting etc). This means that true meshes (players, weapons, creatures, vehicles, props) are prime contenders to be batched. However, if you look around you, the walls of normal buildings are pretty flat. They do often have different textures. In a street, often times the buildings will be the same in building style, but they will have different bricks (color and /or texture), or maybe even some kind of pattern using different kind of bricks in a single house. Geometry like this is not so easy to batch due to the large amount of different materials used for the different polygons. You could try to create a single batch of similar houses, but then you have the chance that a lot of houses in that batch will not be in the viewing frustum. This is again less than ideal. To me it seems that batching is not very interesting for this kind of world geometry, unless one can somehow overcome these differences. One option is to use texture pages/atlases for the different bricks. But you are still limited to the size of texture the GPU supports. What are your thoughts on this?
Advertisement
If there are lots of materials in a scene, then there isn't really much one can do. One solution is to somehow "join" different materials and let the geometrical data decide what to pick out from the material properties, kind of what you mentioned.

A more exotic solution could be to "merge" objects from, say, different nodes from a world tree (ABT, Octree, ubertree or whatnot):

First, make sure the geometry-data in the nodes are "modules", which means that the nodes merely "point" to the geometry data (renderable object) somewhere. Then create a list that is able to hold a large number of renderable objects. Create a material-table that records renderables.
Now, as objects are queued for rendering, record them in the material-table. After a number of frames, investigate the table and see what objects share the same materials. Merge the vertex buffers and save the new information in a new renderable flagged as "merged", _but_ also save the old buffer information in the existing renderables (just delete the geometry data). We can't only merge objects, so some splitting would be nice. When recording objects, the recorder must check merged objects and if it shows one is peeking out the frustum (or similar), investigate its children. When a child has been peeking out for quite some time (deduced from the mat-tab investigation), split its vertex buffer from the merged object and insert that data into the old object. In order not to stall due to all the copying, set a max amount to copy every frame and distribute the work.
Pretty ambitious, but this runtime batching sounds fun :)

Maybe some magic fragment-shader to create brick-like textures? Send some data per vertex about the properties and you got customized bricks for an entire block in one batch...
My feeling on batching, and graphics performance in general, is that for each draw call, make sure you are getting more visual detail or complexity.

So, switching textures is a good thing when it leads to more visual variety in your scene. What is not a good thing is to do

texture a
texture b
texture a
texture b

You are paying more in cpu time than you are getting visually. So, by all means, make your scene complex, but then try to wring out as much coherency as possible.

So instead, do

texture a
texture a
texture b
texture b

or

texture a
texture b
texture c
texture d

What I do in my engine, is to take chunks of world geometry, which are roughly 4000 triangles each, and sort the triangles by material. Then I keep track of a per-material AABox and also a start index and size, so I can cull each geometry section separately ( important for lighting ), and so I can easily pick out just the non-culled parts.

If I am doing a cheap operation, like drawing ambient, I will draw all geometry in the world chunk if the world chunk's aabb is visible, but when lighting or shadowing, I do the culling test on the per-material AABBs.

So, chunks with more materials are potentially slower, but hopefully the various materials make it look that much better.

This topic is closed to new replies.

Advertisement