Hi Phil, There are lots of different ways to tackle billboards.
The osg::Billboard is based on computing a modelview matrix for each billboard leaf geometry and computes this on every frame. You can reuse the leaf geometry but it won't save you much as the biggest bottle-neck is the CPU overhead in culling and dispatching all those modelview matrices. If you have really large amounts of billboard data then it's best to use a custom shaders such as a vertex shader to compute the billboard rotation for you thus avoiding all the CPU overhead and state changes that a normal osg::Billboard entails. Another tweak is to use geometry instancing. Another route is to use a geometry shader to create billboard quads just from points. The later approach makes it very scalable. The osgforest example provides a couple of examples for different approaches. Robert. On 5 March 2013 21:54, Phil Osteen <[email protected]> wrote: > Hi, > > I have seen some discussion on this topic, but I have a specific OGRE based > benchmark that will hopefully allow me to narrow down ways to make my code > more efficient. > > First, the benchmark uses Billboards while I am simply going for Quads, > although Billboards would be ideal. > > In doing a bit of research, I came across the OGRE API and found this: > > >> Billboards have their geometry generated every frame depending on where the >> camera is. It is most beneficial for all billboards in a set to be >> identically sized since Ogre can take advantage of this and save some >> calculations - useful when you have sets of hundreds of billboards as is >> possible with special effects. You can deviate from this if you wish but be >> aware the extra overhead this brings and try to avoid it if you can. > > > Does this apply to OSG as well? I am not sure if I am reading the following > right in thinking the answer is "no" (from the beginners guide) > > >> Unfortunately, it is not clever enough to add the same drawable object to >> osg::Billboard with different positions, which could cause the node to work >> improperly. > > > > In any case, OSG with Quads is performing slower than I had expected, > although I am rendering millions of Quads. > > A snippet of what I am doing (the threshold logic is from the 3dc plugin): > > > > Code: > > geode=osg::ref_ptr<osg::Geode>(new osg::Geode()); > osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry()); > > osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array(4)); > osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array()); > osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array()); > > for (int i=0; i<total_num_quads; i++) { > if (vertices->size()>=num_vertices_thresh) > { > geometry->setUseVertexBufferObjects(true); > geometry->setVertexArray(vertices.get()); > geometry->setNormalArray(normals.get()); > geometry->setColorArray(colors.get()); > geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); > geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); > geometry->addPrimitiveSet(new > osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size())); > > > geode->addDrawable(geometry.get()); > > // allocate a new geometry > geometry = new osg::Geometry(); > vertices = new osg::Vec3Array(); > normals = new osg::Vec3Array(); > colors = new osg::Vec4Array(); > vertices->reserve(num_vertices_thresh); > normals->reserve(num_vertices_thresh); > colors->reserve(num_vertices_thresh); > } > } > > // Create Quads > vertices->push_back (osg::Vec3 (point.x-0.5,point.y,point.z-0.5)); > vertices->push_back (osg::Vec3 (point.x-0.5,point.y,point.z+0.5)); > vertices->push_back (osg::Vec3 (point.x+0.5,point.y,point.z-0.5)); > vertices->push_back (osg::Vec3 (point.x+0.5,point.y,point.z+0.5)); > > normals->push_back(osg::Vec3 (point.normal_x, point.normal_y, > point.normal_z)); > normals->push_back(osg::Vec3 (point.normal_x, point.normal_y, > point.normal_z)); > normals->push_back(osg::Vec3 (point.normal_x, point.normal_y, > point.normal_z)); > normals->push_back(osg::Vec3 (point.normal_x, point.normal_y, > point.normal_z)); > > uint32_t red,green,blue,alpha; > red=point.r; > green=point.g; > blue=point.b; > alpha=point.a; > colors->push_back (osg::Vec4f ((float)red/255.0f, (float)green/255.0f, > (float)blue/255.0f,(float)alpha/255.0f)); > colors->push_back (osg::Vec4f ((float)red/255.0f, (float)green/255.0f, > (float)blue/255.0f,(float)alpha/255.0f)); > colors->push_back (osg::Vec4f ((float)red/255.0f, (float)green/255.0f, > (float)blue/255.0f,(float)alpha/255.0f)); > colors->push_back (osg::Vec4f ((float)red/255.0f, (float)green/255.0f, > (float)blue/255.0f,(float)alpha/255.0f)); > > geometry->setUseVertexBufferObjects(true); > geometry->setVertexArray (vertices.get()); > geometry->setNormalArray (normals.get()); > geometry->setColorArray (colors.get()); > geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); > geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); > > geometry->addPrimitiveSet(new > osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size())); > > geode->addDrawable (geometry.get()); > osg::StateSet* state = geometry->getOrCreateStateSet(); > state->setMode( GL_LIGHTING,osg::StateAttribute::OFF); > > > > > > ... > > Thank you! > > Cheers, > Phil[/code][/url] > > ------------------ > Read this topic online here: > http://forum.openscenegraph.org/viewtopic.php?p=52959#52959 > > > > > > _______________________________________________ > osg-users mailing list > [email protected] > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

