Hi Michael,

How would I set it up for instanced drawing?

My guess is that I would need to write a node-visitor that collects all
of the geometry ->  drawables and sets them up to use the instanced call
overload instead of the default. I have tried doing this, but my
implementation has gotten pretty complex, and I want to make sure there
isn't a more simple way I have overlooked.

You've got the right idea for the general way to apply instanced rendering for complex objects. But you can simplify usage by making your model simpler.

Draw instanced will work really well if your model consists of a single primitiveset. So ideally you'll have your modeler create the tree in a single geometry with a single primitiveset. They can make a texture atlas so that the same texture file applies to the whole geometry, and then merge all the geometry into a single one.

If this is not possible, you can try using the osgUtil::Optimizer to do this for you as a pre-process. Using the artist's model as input, you would apply the SHARE_DUPLICATE_STATE, FLATTEN_STATIC_TRANSFORMS, MERGE_GEODES, MERGE_GEOMETRY, VERTEX_PRETRANSFORM, VERTEX_POSTTRANSFORM, INDEX_MESH and possibly TEXTURE_ATLAS_BUILDER optimizers on it. I use this combination on all models by the way, in combination with a few custom visitors it does wonders to cull and draw times. What these will do:

TEXTURE_ATLAS_BUILDER: Will merge many small textures into a single larger one, adjusting texture coordinates, which can then be shared by all those nodes. An artist-created texture atlas is better though, I've seen cases where the texture atlas builder in OSG will create a really large texture and use less than half the space in it, and other such inefficiencies. A human will also be better equipped to judge of the qualitative criteria in making some textures smaller thus fitting more textures into a single atlas.

SHARE_DUPLICATE_STATE: Make sure identical state is shared (uses the same pointer to the same object) instead of having multiple state attributes with the same value throughout your model. You might have to write a small visitor to help this optimizer a bit, essentially normalizing all state that your modeling tool might set differently from what you expect, but which has no effect on the final output. For example you could force all geometry to single sided, etc. The idea is to make sure the next steps will be able to merge as much as possible.

FLATTEN_STATIC_TRANSFORMS: Remove any transforms that are marked as static data variance. You might have to make a small visitor that will change the data variance to static on any transforms that you don't really need. Modeling programs have a tendency to put lots of transforms all over the place (in Maya for example, there are no groups, everything is a transform, even graph leaves are a transform plus a geometry...). Again this will make the next steps work more efficiently, because things that are separated by a transform can't be merged together. You might want to write another simple visitor that would remove unnecessary Group nodes. Once again things that are separated by a Group can't be merged together.

MERGE_GEODES, MERGE_GEOMETRY: Merge as many scene graph leaves together as possible. Again this will make the next steps work more efficiently. Note that the MERGE_GEODES optimizer in OSG has a pretty serious "design flaw", it will only merge Geodes whose direct parent is a Group, and not any Group subclass. Sure, merging the children of an LOD node or Switch node is bad, but there are plenty of other subclass es of Group where it makes no difference. So I just subclassed the MergeGeodesVisitor so it checks the actual type of the parent, doesn't merge if it's certain types of Group subclasses (like LOD or Switch) but merges in all other cases.

VERTEX_PRETRANSFORM, VERTEX_POSTTRANSFORM, INDEX_MESH: This is a powerful trio of optimizers that will turn DrawArrays into DrawElements optimized for the GPU's cache, and merge all primitivesets under a Geometry together. After this, you might want to run the MERGE_GEODES and MERGE_GEOMETRY optimizers again, as they will be able to merge even more things together.

So anyways, I described why you would want to use the various optimizers for general models, but for your trees the goal is to end up with a single Geometry which has a single primitiveset. Then your job of doing instanced drawing of this tree becomes much easier. And again, if you can get your artist / modeler to make the model with this in mind, all the better. In general, if you can massage the data in order to make the code simpler, it's normally a win in the long run.

Hope this helps,

J-S
--
______________________________________________________
Jean-Sebastien Guay    jean-sebastien.g...@cm-labs.com
                               http://www.cm-labs.com/
                    http://whitestar02.dyndns-web.com/
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to