Idea to try: one region = one mesh.
Current system:
- a level is made of different regions connected by portals
- a portal is a convex polygon
- a region is a collection of meshes
- a mesh is a collection of “subsets”. Each mesh has a single PRS transform and is a single object in 3DS MAX.
- a subset is a collection of triangles sharing the same render states (same material).
Currently, things are exported as-is from 3DS MAX, and each region contains several meshes, depending on whatever is in the MAX scene. Visible objects are batched, and sorted to minimize the number of render state changes. However this may not be necessary: we could use the “static batching” that happens for each individual mesh instead, the one creating subsets. We just have to merge all the meshes of a given region together, ending up with a single mesh per region.
If the regions are quite small, i.e. if it is possible to see “all” meshes of a region from a particular viewpoint, this looks like a good idea (following the “optimize your worst case” strategy). We save memory by reducing the number of “meshes” in the system, we save CPU time on culling, batching, etc.
If the engine creates one physics mesh for each render mesh, it might also have some benefits. It certainly saves memory, minimizing the cost associated with each “object” within the physics engine. It also reduces the stress on the broad phase. However it puts it on the midphase (basically OPCODE), since the whole region is now a huge AABB-tree. The old “RAPID vs OPCODE” tests showed that AABB-trees are not too great when a small object is fully contained within a big scene, but on the other hand temporal caches helped a lot for this case, so it might be ok in the end.
Now the only issue with this is probably when you have a room with several open doors, each of them being a portal connected to a different region. If you stand in the middle of the room looking at those doors, you end up rendering all the regions even though a small part of them is visible, whereas before only the first meshes of each region would have been rendered. So you made your worst case worse, in a way.
——–
Not merging meshes at all and keeping the same organization and the same number of objects as in MAX does work, but it puts the burden on the artists, and on the batcher. But even if the batcher does a perfect job, you still waste memory associated with individual meshes. In ICE, sizeof(Mesh) is something like 500 bytes or more, which I know is too much, but that’s how it is now, and a lot of professional engines have worse than this. With ~1000 meshes in a single region,that’s ~500 Kb lost per region: not good. Plus, the batcher is never “perfect” anyway, i.e. it has a runtime cost.
Merging meshes by material regardless of spatial considerations doesn’t work. It makes things easier for the batcher but it kills the physics.
A good alternative is just to cover the region with a fixed-size grid, assign triangles to grid cell (regardless of their original mesh), and create one mesh per cell. It keeps the number of meshes under control, it’s physics-friendly, and also culling-friendly. The main drawback is when the physics does a convex decomposition and relies on it to have good collision response. You can end up with a perfectly flat plane cut to N different, unconnected physics meshes - and bad collision response when an object slides from one part of the mesh to the other.
You can always completely decouple the physics & graphics representations, but it’s a pain to manage. Probably the best option though.
July 1st, 2008 at 8:50 am
I’m by no means an expert on this, but maybe something in the middle would work better? I.E. not merge the whole room into a mesh, but smaller parts of it. Each wall, for example, could be turned into a big mesh. Or maybe two walls. Or a subset of a wall to a subset of a wall.
On another tangent, could a tool be written to go through all the possible moves and camera angles of the level (or more realistically travel and rotate in steps) and keep statistics of the rendered frames, so you can have some data of how the meshing and the portals affect the engine?