[osg-users] Multi-view Performance Issue with Statesets

2010-03-12 Thread Drolet, Frederic
Hi everyone,

 

I've seen a lot of threads on performance issues in the mailing list but none 
of them seemed to address my particular problem precisely, either because the 
problem description was vague or the replies were covering a matter far too 
vast to include everything in a single message. So I've decided to expose my 
problem and share my observations and potential solution. My goal here is to 
understand why it does what it does and maybe help some other users with 
similar problems.

 

Here's my system configuration: Dell XPS, Intel Core2 Quad Q9300 @ 2.5 Ghz, 4 
GB RAM, NVidia GeForce GTX 280. The application uses MFC classes (extended from 
the OSGViewerMFC exemple) and is run under Windows Vista 32-bit.

 

So, I have this multi-view application with textured terrains generated  from 
osgGIS. I eliminated all LODs to eliminate this factor in my performance 
comparison. On those terrains, we add road segments with a stateset:

 

mGeometrie = new osg::Geometry;

mGeometrie-setVertexArray(lListe);

mGeometrie-addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,1));

mGeometrie-addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,1));

((osg::DrawArrays*)mGeometrie-getPrimitiveSet(0))-setCount(lListe-size());

((osg::DrawArrays*)mGeometrie-getPrimitiveSet(1))-setCount(lListe-size());

 

osg::ref_ptrosg::StateSet lStateSet = mGeometrie-getOrCreateStateSet();

lStateSet-setMode(GL_LIGHTING, osg::StateAttribute::OFF);

 

osg::ref_ptrosg::Vec4Array lCouleur = new osg::Vec4Array;

lCouleur-push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));

mGeometrie-setColorArray(lCouleur);

mGeometrie-setColorBinding(osg::Geometry::BIND_OVERALL);

 

We also add a larger invisible road segment above to make things easier for the 
user to select a segment (the collision is detected in a visitor):

 

osg::ref_ptrosg::Geometry lGeometrieSelection = new osg::Geometry;

lGeometrieSelection-setVertexArray(lListeSelection);

lGeometrieSelection-addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,1));

lGeometrieSelection-addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,1));


((osg::DrawArrays*)lGeometrieSelection-getPrimitiveSet(0))-setCount(lListeSelection-size());


((osg::DrawArrays*)lGeometrieSelection-getPrimitiveSet(1))-setCount(lListeSelection-size());

 

osg::ref_ptrosg::StateSet lStateset = 
lGeometrieSelection-getOrCreateStateSet();

osg::ref_ptrosg::Material lMateriel = 
dynamic_castosg::Material*(lStateset-getAttribute(osg::StateAttribute::MATERIAL));

if (!lMateriel) lMateriel = new osg::Material;

lMateriel-setTransparency(osg::Material::FRONT_AND_BACK, 1.0f);

lStateset-setAttributeAndModes( lMateriel, 
osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);

lStateset-setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

 

osg::ref_ptrosg::Vec4Array lCouleurSelection = new osg::Vec4Array;

lCouleurSelection-push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 0.0f));

lGeometrieSelection-setColorArray(lCouleurSelection);

lGeometrieSelection-setColorBinding(osg::Geometry::BIND_OVERALL);

 

Now, I noticed a lot of things while doing my performance experiments:

 

-  First of all: Statesets seem to affect performance drastically and 
the code above generates a lot of them. I have 4 views sharing a scene 
containing 4 terrain with 15 segments each. Without the road segments, I reach  
56 FPS with 237 statesets, 512K vertices and 970K primitives. When I add the 
road segments, I drop to 24 FPS with 781 statesets, 544K vertices and +1M 
primitives.

-  Primitives and vertices count also affect performance but the effect 
is less significant. Indeed, I can put 5 terrains without the road segments and 
I'm still at 55 FPS with only 257 statesets, 625K vertices and +1.2M 
primitives. I drop to 30 FPS with 514 statesets, 1.2M vertices and 2.4M 
primitives (10 terrains with no road segments).

-  With a single view, the stateset effect is far less significant. 
Maybe my multi-view is not set properly?

-  The FOV (set in the camera's projection matrix) also seem to affect 
performance negatively and worsen the stateset effect. For now, I set it to 170 
degrees (to be able to cull everything for CAVE rendering) but I think I will 
need to optimize this value with tracker coordinates.

 

I remember Robert saying that we should avoid independent statesets. This 
raises a lot of questions since I don't fully understand this functionality 
yet... For instance, what is the typical amount of statesets in a commercial 
application? How can we combine statesets for multiple objects potentially in 
different states from each others?

 

Finally, do you have any idea how I could solve my particular selection problem 
without having to add more statesets for the invisible but larger 

Re: [osg-users] Multi-view Performance Issue with Statesets

2010-03-12 Thread Thrall, Bryan
Drolet, Frederic wrote on 2010-03-12: 
 osg::ref_ptrosg::StateSet lStateSet = mGeometrie-
 getOrCreateStateSet();
 
 lStateSet-setMode(GL_LIGHTING, osg::StateAttribute::OFF);

OpenGL performance is very sensitive to state changes, so it is a good idea to 
minimize them as much as possible. OSG groups Drawables with the same state as 
part of this (the exception is transparent drawables that require a certain 
ordering to render correctly, so they can't be grouped), but it just compares 
the StateSet pointers rather than a (much more expensive) comparison of what 
OpenGL state the StateSet pointers represent.

Therefore, if you have a bunch of StateSets that are identical, like you seem 
to have, it is a really good idea to just use the same StateSet object 
everywhere you need it, rather than create a new instance every time.

HTH,
--
Bryan Thrall
FlightSafety International
bryan.thr...@flightsafety.com
  


___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Multi-view Performance Issue with Statesets

2010-03-12 Thread Drolet, Frederic
Let's say I want to change the color of my road segment (when selected for 
instance). We're currently doing this modification that way:

osg::Vec4Array* lCouleur = 
(osg::Vec4Array*)(mGeometrie-getColorArray());
*(lCouleur-begin()) = pCouleur;
mGeometrie-dirtyDisplayList(); 

From what you're saying, I guess we should create a different stateset for 
every color instead of a stateset for every segment? Maybe I should ask first 
if the color is indeed part of the stateset anyway! If not, we could reduce 
the stateset count even more!

Thanks!

Frederic Drolet, M. Sc.
Computing Solutions and Experimentations | Solutions informatiques et 
expérimentations
Systems of Systems | Systèmes de systèmes
DRDC Valcartier | RDDC Valcartier
2459, boul. Pie-XI North
Quebec, Quebec
G3J 1X5 CANADA
Phone | Téléphone: (418) 844-4000 ext : 4820
Fax | Télécopieur: (418) 844-4538
E-mail | Courriel: frederic.dro...@drdc-rddc.gc.ca
Web : www.valcartier.drdc-rddc.gc.ca
-Original Message-
From: osg-users-boun...@lists.openscenegraph.org 
[mailto:osg-users-boun...@lists.openscenegraph.org] On Behalf Of Thrall, Bryan
Sent: Friday, March 12, 2010 10:39 AM
To: OpenSceneGraph Users
Subject: Re: [osg-users] Multi-view Performance Issue with Statesets

Drolet, Frederic wrote on 2010-03-12: 
 osg::ref_ptrosg::StateSet lStateSet = mGeometrie-
 getOrCreateStateSet();
 
 lStateSet-setMode(GL_LIGHTING, osg::StateAttribute::OFF);

OpenGL performance is very sensitive to state changes, so it is a good idea to 
minimize them as much as possible. OSG groups Drawables with the same state as 
part of this (the exception is transparent drawables that require a certain 
ordering to render correctly, so they can't be grouped), but it just compares 
the StateSet pointers rather than a (much more expensive) comparison of what 
OpenGL state the StateSet pointers represent.

Therefore, if you have a bunch of StateSets that are identical, like you seem 
to have, it is a really good idea to just use the same StateSet object 
everywhere you need it, rather than create a new instance every time.

HTH,
--
Bryan Thrall
FlightSafety International
bryan.thr...@flightsafety.com
  


___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Multi-view Performance Issue with Statesets

2010-03-12 Thread Thrall, Bryan
Drolet, Frederic wrote on 2010-03-12: 
 Let's say I want to change the color of my road segment (when selected
 for instance). We're currently doing this modification that way:
 
   osg::Vec4Array* lCouleur = (osg::Vec4Array*)(mGeometrie-
 getColorArray());
   *(lCouleur-begin()) = pCouleur;mGeometrie-dirtyDisplayList();
 
 From what you're saying, I guess we should create a different stateset
 for every color instead of a stateset for every segment? Maybe I should
 ask first if the color is indeed part of the stateset anyway! If not,
 we could reduce the stateset count even more!

The color array is independent from the StateSet.

It appears you are only using the StateSet to turn lighting off; if that is 
true, you could just create a single StateSet that turns lighting off and put 
it near the top of your scene graph.

The color arrays and modifying them should not affect performance as much as 
the OpenGL state changes that come from many StateSets.

 -Original Message- From:
 osg-users-boun...@lists.openscenegraph.org [mailto:osg-users-
 boun...@lists.openscenegraph.org] On Behalf Of Thrall, Bryan Sent:
 Friday, March 12, 2010 10:39 AM To: OpenSceneGraph Users Subject: Re:
 [osg-users] Multi-view Performance Issue with Statesets
 
 Drolet, Frederic wrote on 2010-03-12:
 osg::ref_ptrosg::StateSet lStateSet = mGeometrie-
 getOrCreateStateSet();
 
 lStateSet-setMode(GL_LIGHTING, osg::StateAttribute::OFF);
 
 OpenGL performance is very sensitive to state changes, so it is a good
 idea to minimize them as much as possible. OSG groups Drawables with
 the same state as part of this (the exception is transparent drawables
 that require a certain ordering to render correctly, so they can't be
 grouped), but it just compares the StateSet pointers rather than a
 (much more expensive) comparison of what OpenGL state the StateSet
 pointers represent.
 
 Therefore, if you have a bunch of StateSets that are identical, like
 you seem to have, it is a really good idea to just use the same
 StateSet object everywhere you need it, rather than create a new
 instance every time.
 
 HTH,


--
Bryan Thrall
FlightSafety International
bryan.thr...@flightsafety.com
  


___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org