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
> 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

Reply via email to