Hello, I'm working on an application that can potentially create thousands of ModelNodes in one fell swoop and show them on a map. Creating even just 600 ModelNodes is quite slow, about 12 seconds. Profiling revealed that the bottleneck is in Registry::shaderGenerator().run(). Sure enough, after I disabled shader generation via OSGEARTH_NO_GLSL=1, execution time of that code dropped to about 2 seconds. From what I've read, the performance of ShaderGenerator can be greatly improved by having it use a StateSetCache, but I'm having trouble setting it up. The code I'm using is below; is there anything I'm missing or doing wrong? My models are all loaded from files, and there's only about 80 unique model files, so caching should be very beneficial.
osg::ref_ptr<StateSetCache> cache = new StateSetCache();
[ osg 3.4.0, osgEarth 2.8.0, Intel HD Graphics 530 ]
Are these models all different? If you know that the shader program is going to be the same for all your models, you can tell ModelNode not to generate shaders at all -- by calling setShaderPolicy(SHADERPOLICY_DISABLE) -- and then either supply your own shaders or run the shadergenerator on the whole thing once it's loaded.
The Registry contains a StateSetCache by default; you don't need to create and set one. The cache does not necessarily speed up shader generation anyway. Instead it helps to speed up rendering times by trying to minimize GL state changes.
For the large number of model nodes you are using you might consider a custom approach. ModelNode is kind of a convenience type, and not really designed for scalability.
Hi Glenn, thanks for the advice. The models are all different, though there's only about 80 unique model files, which I read into Nodes and clone as needed. I looked into disabling shading like you suggested, but the old version I'm stuck using (2.8) doesn't seem to have setShaderPolicy(). Using your idea about a custom class for the model nodes turned out to work great. The init() method in this custom class is exactly the same as ModelNode::init() except that I've commented out the block that calls Registry::shaderGenerator().run(). Performance is much better now, about 2 seconds, which is acceptable. The funny thing is that the models are still rendered with shading. This is a pleasant surprise, but any idea what's going on? I'm guessing that there could be a shader in the root node or something like that.