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

Reply via email to