Hi Robert and David,
The Switch node:
==============
I looked at the Switch node but came to a conclusion that I should not use it.
Using it would work if I do a cull-callback on it and set the switch position
during cull-traverse. The switch position need to be changed according to which
camera that is active. The overhead on each switch is higher that my suggestion.
My suggestion need one bitvise and operation, and one array lookup.
The switch node will need an additional callback call, a bitvise and operation
(to figure out what position the switch need to be in), a call to
Switch::setValue() which does and if, an array indexed write, and dirtyBound
(which I do not know how much penalty you get from, I guess bounding-sphere
will need to be re-calculated). And, in addition, the traverse itself runs a
loop to figure out which one to call accept onto.
The camera itself should not do the switching. It would need an own traversal
to do so, and that is too much overhead to do runtime.
Solving the problem by only using node-masks:
====================================
This works fine.
But, there is a penalty.
In this solution I have to specify a Group node that has one child per StateSet
that I want to switch between.
Each child will hold its own node-mask so that cull-mask can be used to switch
between them.
Each child points to the same node(s) as their child(ren).
The penalty I get from this is that any traverse that has multiple bits turned
on will go through for example all of the nodes with unique mask bits set. This
in turn means that their children (which all of them share) will be traversed
one time for each of the nodes with unique node masks.
Any such traverse will thus cost much more.
A switch that is high up in the tree will thus cause a large tree to be
traversed many times more than neccessary.
Any traverse that force node masks on will also cause the same problem as above
(even if I turn off the node masks on the special nodes).
I have tried this solution.
I saw that initialization process for OSG took much longer time with this kind
of node setup. So I think OSG at some point does a scene traverse without a
node visitor. Seems like it happens when for example I switch threading mode.
Layer solution:
============
Sounds interesting.
Will the Layer node use the traverse function to actively chose which child to
traverse?
One way would be to have each child in an array and somehow ensure that only it
gets called when you call Group::traverse(). How would you do that?
Viggo
> Date: Wed, 19 Nov 2008 13:44:49 +0000> From: [EMAIL PROTECTED]> To:
> [email protected]> Subject: Re: [osg-users]
> StateSetSwitchNode suggestion.> > Hi Viggo,> > One thing I have considered in
> the path is to have an osg::Layer node> which is a group that has a StateSet
> per child, this does sound kinda> similar to what you are after. You can
> implement this without any> custom nodes just be arranging Group/Switch and
> StateSet's as required> - its just a bit more wordy w.r.t lines of code.> >
> Robert.> > On Wed, Nov 19, 2008 at 1:32 PM, Viggo Løvli <[EMAIL PROTECTED]>
> wrote:> > Solution suggestion: StateSetSwitchNode> >> > Motivation:> > - I
> need to render with different shader-programs and state-sets, on the> > same
> geometry, during one tick.> > - Example of when I need this is explained in
> the EXAMPLE section below.> >> > I hope from this e-mail to get feedback:> >
> - Is this solution ok?> > - Can it be improved?> > - Can I submit it to OSG?
> And supported in the .ive file format?> >> > Solution:> > ==========> > I use
> Group instances to hold the StateSets.> > Need to store Group pointers in an
> array:> >> > class StateSetSwitchNode : public Group> > {> > ...> > private:>
> > std::vector<Group*> _nodeArray;> > };> >> > Need to override the accept
> function:> >> > void StateSetSwitchNode::accept( osg::NodeVisitor& nv )> > {>
> > if( nv.validNodeMask( *this ))> > {> > if( osg::Group* group = _nodeArray[
> INDEX ] )> > {> > // Apply the Group holding the StateSet instead of 'this'>
> > pointer> > nv.pushOntoNodePath( group );> > nv.apply( *group );> >
> nv.popFromNodePath();> > }> > }> > }> >> > I will explain the INDEX and array
> size later in this e-mail.> >> > Each Group pointer in the _nodeArray:> > -
> must be set up with the same children as the StateSetSwitchNode> > instance
> has.> > - will not have any parents (unless the element point to the> >
> StateSetSwithNode instance).> > - will by default point to the
> StateSetSwitchNode instance.> >> > The StateSetSwitchNode's own StateSet is
> the default StateSet.> >> > I am conserned about how smart it is to have
> nodes that is not tied to a> > parent, but that links to multiple children in
> the node-tree. It will not> > affect performance when traversing children,
> but any parent traversal will> > go into all of the extra nodes stored in the
> _nodeArray. They do not have> > parents, so it is not a large performance
> penalty.> > The class will also need function overrides for
> adding/removing/replacing> > children as we would need to ensure that each
> element in the array point to> > the same children as the
> StateSetSwitchNode.> >> > We do not need to do any code changes to OSG
> (except for supporting the> > class in file formats, and to add the class to
> OSG).> > Cull-traveresal does not suffer a performance-hit, unless you
> actually use> > the StateSetSwitchNode.> > Using the StateSetSwitchNode comes
> with a minimal performance-hit for> > StateSet switching (bitvise and
> operation + an array lookup).> >> >> > INDEX (and the array size):> >
> ============================> > We need some way to select what array index
> we want to use. My need is to> > have multiple camera's render the scene in
> different ways (by using> > different state-sets and shader-programs).> > I
> decided to do it in a way that need no new code, except for the indexing> >
> inside my new class. So I use the traversal-mask which automatically makes> >
> it possible for my camera's to decide what StateSets to render the scene> >
> with. I allocate some of the least significant bits in the node-mask to be> >
> StateSet selectors. So if I use 4 bits for this, then I get a total of 16> >
> different StateSet possibilities in each StateSetSwitchNode.> > We do not
> want to check array size during cull-traverse, the size of the> > array
> should be in the power of two so that we can bitvise and the index> > before
> we read the array. All elements in the array thus need to point to an> >
> instance.> > Any not used elements will point to the default instance (which
> is the> > StateSetSwitchNode instance itself). This must be enforced in the>
> > StateSetSwitchNode constructor.> >> > INDEX (in the above code) is thus
> replaced by this:> > (nv.getTraversalMask() & (_arraySize-1))> >> >> >
> EXAMPLE:> > =========> > Currently we render our scene three times each
> tick:> > - One pre-render camera that render the scene and generate a
> water-surface> > reflection image.> > - One pre-render camera that render the
> scene and generate a sub-sea> > refraction image.> > - One camera that render
> the scene and use the two textures above to> > display a good looking sea
> surface.> >> > The pre-render cameras renders only parts of the scene (those
> nodes that> > actually need to be in the reflective image and those that is
> underneath> > water).> >> > Our terrain use four different shaders:> > - High
> detail shader on the lod's that are close to camera.> > - Low detail shader
> on distant lods.> > - Lower detail shader on the reflection surface both for
> close and distant> > lods.> > - Special fog shader and lower detail both for
> close and distant lods when> > under water.> >> > The same goes for
> vegetation and buildings (which has different shaders than> > then terrain).>
> >> > We can optionally switch to even simpler shaders when the water-surface>
> > start to have higher waves. So dynamically we will be able to speed up> >
> reflection and underwater rendering based on wave-height. This would be a> >
> matter of changing the cull-mask on the pre-render cameras and writing even>
> > simpler shaders.> >> > We use the StateSetSwitchNode to select which
> shaders to render with, and> > this is controlled by setting the lower bits
> in the camera's cull-mask.> > We use bit 0,1 and 2 to select shader.> > We
> use bit 3,4 and 5 to select scene (normal, reflection and underwater).> >
> Doing this has proven to be a performance boost for our scene. We can write>
> > as simple as possible shaders to use at need. The reflection and
> underwater> > does not need high detail. In the future we will also use this
> to render the> > shadow-caster scene with super-simple shaders too.> >> >
> Regards,> > Viggo> >> >> > ________________________________> > Windows Live
> SkyDrive. På tide å glemme minnepinnen.> >
> _______________________________________________> > 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
_________________________________________________________________
Mest sett denne måneden på MSN Video.
http://video.msn.com/?mkt=nb-no&from=HMTAG_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org