Monday, September 15, 2008

Dirty Meshes

For years there has been much talking about automatic level of detail (or LOD) for geometry in games.
The idea is to automatically build lower detail meshes. Thus, giving modelers greater artistic freedom and have a conversion system deal with reducing complexity to a manageable level for real-time applications. This also adds the ability to target different platforms with different hardware capabilities without any additional work from the artists/designers.
However it's not all about decimating polygons. Along with complex meshes come "dirty" meshes: flipped normals, duplicated materials and uneven distribution of geometry.

Recently I've been working with some geometry and textures meant for off-line rendering. I'm at a good point with textures (see earlier post). Geometry however it's a bit trickier. The irregular distribution of data (when compared to a bitmap) makes it harder to resample geometry, but it's certainly possible and recently a coworker came out with a pretty solid edge collapsing mesh reduction implementation.

The next issue however is dealing with plain careless modeling. For example I found a geometry file that has literally thousands of meshes. Each of these meshes is made of one quad (4 vertices) which is used for billboard-vegetation.
The overhead from having to create thousands of vertex buffers in DX10 and consequent draw calls is pretty heavy. DX10 and current generation hardware surely wasn't meant to deal with this volume of vertex buffers.
Of course one could ask to an artist to merge those polygons together in the same mesh, etc etc. But it's always preferable to solve issues programmatically, instead of having to bother the less technically inclined.
It's also important for me to build a system that will at least warn of broken or inefficient data.
For one thing I've already built a function that will compare all meshes loaded and find duplicated meshes that can be eliminated. This kind of operation is better suited for pre-processing, and it will be moved there, however it's easier to try this at run-time and eventually port the process to the build phase (I see the rendering and building phases as tightly connected and the amount of work shifting depending on the necessities of the application and hardware: what kind of data you "bake" depends on your target).

For the "one mesh per billboard" case, first of all I think I can safely make those meshes index-less. There is really no point in allocating an index-buffer of 6 items (1 quad = 2 triangles = 6 indices) when I can draw a triangle strip with the 4 vertices as they are.
But on a second stage, I should really merge those vertices together in a common vertex buffer.. or even merge all/multiple meshes into one.. provided that those meshes aren't going to be addressed individually in some animation !

In conclusion, there is really a lot more than meets the eye when dealing with real-time graphics. Going by the book will only get you so far. When the data gets complex, that's the time when doing real-time 3D becomes interesting (at least for me !)



  1. Well I think in a case like that, artists can at least give a hint to the engine that the geometry is used for vegetation by means of some material parameter.

    Then the engine will know how to treat it.

    In Dx10 you could maybe store a vertex per billboard and generate the rest in the geometry shader?

  2. I don't really want to worry about special cases to the point of having to use Direct3D's geometry shaders 8)

    Anyhow, I guess it all depends on how much dynamic the scene has to be.
    I've been wanting to make some sort of pictures explaining different levels of dynamism for graphics rendering.

    Recently I had a chance to talk to some famous figure of game/engine dev.
    It was some sort of presentation with questions.. I asked him if he thought that Microsoft Talisman had any future.
    The question was somewhat rhetorical.. my point being that one should think of a more generic way of tackling real-time 3D.
    "Baking" should be a core part of an engine.. which would span from best offline rendering quality to 2D sprites.. by different levels of baking.

  3. Hhmm, generic solutions only take you so far. A good example of this that keeps coming up are UI systems. In my experience I've seen many attempts by enthusiastic programmers to create a fully generic UI system (on a console). And it always ends up being an overcomplicated disaster.

  4. ...true, however what I mean is that I'd rather find a compromise where those thousands of quads are not dealt with in a very special manner. It's a bit like compression, where one applies fairly generic algorithms to deal with large quantities of data.. sure one could always find a more specific formula to synthesize something.. but if it doesn't have to be too interactive, then the less I know about it the better 8)

  5. eehhhh, are you saying knowledge is bad? =)

  6. 8P I'm saying that time is scarce and I prefer to compromise on performance rather than working a an adhoc solution for a few seconds worth of playback.
    I prefer generic solutions... if they don't get too complicated 8)