Hi,

Sounding great so far. A lot to digest! I have a couple of questions.

One thing I am not clear on is how the rules for injecting a Shader into a 
ShaderMain would work. This is an area I have had difficulty with in my own 
shader assembly approach. For example, how will it be possible to change the 
order in which shaders are applied? As a contrived example, I might want to use 
the material color of a fragment as the input to my lighting shader, and then 
blend my textures with the result. Alternatively, I might want to first blend 
all my textures, then use this color as the input to the lighting shader. How 
would I specify these kind of rules?

Another area I am not clear on is how (if at all) we will be able to avoid 
doing the same calculations many times for a single vertex or fragment. Say, 
for example, we need the ec position of a vertex as an input to several of our 
vertex Shaders. Would each shader have to recalculate this value independently? 
This shouldn't be a major hit to performance in most cases but it is obviously 
less efficient than just doing the calculation once. Then again, maybe the 
compiler can figure this out for us.

Cheers,

Brad

-----Original Message-----
From: [email protected] 
[mailto:[email protected]] On Behalf Of Robert Osfield
Sent: Thursday, 1 July 2010 4:30 PM
To: OpenSceneGraph Users
Subject: Re: [osg-users] Shader composition, OpenGL modes and custom modes

Hi All,

I've been thinking about the various classes and relationships that
we'll need to support both the front end API for shader composition,
and the backend implementation of it, and my current thoughts are:

1) The ShaderSet I've been discussing over my last few post should be renamed,
    my current preferred name is ShaderComponent.

2) Rather than ShaderComponent (was ShaderSet) have the details of how to
    inject code into the shader main for each of the vertex, geometry
and fragment
    mains, I now feel it would be more managable to move injection support into
   osg::Shader.

   This would mean that ShaderComponent would then just have a list of
one or more
   osg::Shader.  These Shaders would then be grouped into ones that affect the
   vertex, geometry and fragment programs.

   The osg::Shader class would have some new API for setting up the inject code,
   this could be empty/inactive in a default constructed osg::Shader,
so wouldn't
   affect how we use osg::Shader/osg::Program right now.  It's only when shader
   composition comes into play will these extra fields be queried.

3) StateAttribute would "have a" ShaderComponent that implements the
   shader functionality, this ShaderComponent would typically be shared between
   the same type of StateAttribute.  The StateAttribute attribute
would also provide
   osg::Uniform that pass in the values to the associated ShaderComponent, these
   osg::Unfirom will be applied by the existing
StateAttribute::apply(..) method.

   This is approach I've been discussing before (save for the ShaderSet rename.)

4) osg::State will maintain a current list of enabled ShaderComponent's, this
    list of pointers will form a key to search for the appropriate osg::Program
    to apply to achieve that functionality.  The way that the osg::Program will
    be wrapped up and cached is within a ShaderAssembly.   osg::State
    would internally manage the creation of ShaderAssembly, and cache of these
    and apply the osg::Program they contain.

    Lazy state updating in osg::State will seek to minimize the times that
    the state is changed between ShaderAssembly.  When the set/list of enabled
    ShaderComponent's changes a the appropriate ShaderAssumbly for this set
    of ShaderComponent is then lookup in the ShaderAssembly cache.  If
    non apporpriate ShaderAssembly is found then the ShaderComposer is
    invoked to create a new ShaderAssembly which is then cached and made
    current.

 5) A ShaderAssembly is an internal implementation class so not something
     a user would normally worry about, only the ShaderComposer or
     subclasses from it would need to know about it.

     A ShaderAssembly has the final osg::Program that is applied to OpenGL,
     this osg::Program is composed on the osg::Shader's provided by the
     osg::ShaderComponent, and also an automatically created osg::Shader
     main for each of the vertex, geometry and fragment parts osg::Program.

     The automatically generated shader mains are wrapped up in a ShaderMain
     class that has a list of osg::Shader that contribute to it, these
osg::Shader
     are pulled in from the ShaderComponent's that are associated with the
     ShaderAssembly.  The individual osg::Shader that assigned to a ShaderMain
     provide the code injection details that enable the ShaderComposer to create
     the final main() code that gets placed in the ShaderMain's automatically
     generated osg::Shader.

     The ShaderAssembly contains a ShaderMain for each of the vertex, geometry
     and fragment programs.  Pulling all the Shaders, both provided by the
     ShaderComponent and the automatically generated ones in the three
     ShaderMain to create the final osg::Program.

     It will be possible to share ShaderMain between multiple ShaderAssemly, and
     this will be desirable as often we will just enable/disable a
mode that affects
     only the vertex shaders parts, or just the fragment shader parts,
so if we are
     able to share then we only need create a new ShaderMain for the part that
     changes, the rest can be reused from a cache of ShaderMain (that will be
     provided by osg::ShaderComposer).

     Like ShaderAssembly the ShaderMain is an implementation detail that most
     end users need not use directly or worry about.  It's only osg::State and
     osg::ShaderComposer (or subclasses from it) that will directly
deal with them.

 6) ShaderComposer will manage a cache of ShaderAssembly, and access to
     this cache and the automatic creation of new ShaderAssembly when a
     new combination of enabled ShaderComponent is requested.  When a
     a new ShaderAssembly is created the ShaderComposer querries the
     ShaderComponent to work out what ShaderMain it needs to create, and where
     possible to pull these in from a cache of ShaderMain.

     osg::State "has a" ShaderComposer, and will defer most of the shader
     composition functionality to it.  Users will be able to subclass from
     ShaderComposer to provide their own custom schemes for creating and
     managing the required osg::Program.  Such as subclass could even
     roll their own ShaderMain/ShaderAssembly classes as we might well
     be able to hide these implementation details entirely within the
ShaderComposer
     base class.

 7) In terms of ease of design and management it would be easiest for use to
     by able to assume that ShaderComponent and the osg::Shader they contain
     are all constant.  If a user want to change the shaders they they create a
     new osg::Shader and a new ShaderComponent for them rather than reuse
     an existing one and tweak it.

     We could possible enforce that const behaviour by having a toggle in
     ShaderComponent and osg::Shader that once switched on will make these
     classes ignore changes to them, or at least warn of the change might
     break the ShaderAssembly cache.

     The alternative being able to make the const assumption would be for us
     to implement a dirty count in Shader and ShaderComponent such that
     any associated ShaderAssembly would have to be recreated.  Perhaps
     this might not be too complicated to implement, but wouldn't be without
     a CPU overhead in checking for shader components.

  8) ShaderComponent would provide guidance on what traditional fixed
      function gglEnable/glDisable GLenum's that take over the role of,
      these GLenums we set right now via osg::StateSet::setMode(..).  The
      guidance provided by ShaderComponent will enable osg::State to know
      which modes to redirect to enabling the associated ShaderComponent
      and which should be ingored or still passed on to OpenGL via
      glEnable/glDisable.


OK. That's my current thoughts...  I'm getting reasonably comfortable
with the different parts, not everything is settled but I'm probably
far enough along now to start doing
some coding up which hopefully get a chance to start tackling over the
next couple of days.  It's school holidays right now though so I'm
looking after my brood for most of today, so don't expect too many
check-in's right away.

Let me know your thoughts/suggestions.

Robert.
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org



DISCLAIMER:---------------------------------------------------------------------------
This e-mail transmission and any documents, files and previous e-mail messages
attached to it are private and confidential. They may contain proprietary or 
copyright
material or information that is subject to legal professional privilege. They 
are for
the use of the intended recipient only.  Any unauthorised viewing, use, 
disclosure,
copying, alteration, storage or distribution of, or reliance on, this message is
strictly prohibited. No part may be reproduced, adapted or transmitted without 
the
written permission of the owner. If you have received this transmission in 
error, or
are not an authorised recipient, please immediately notify the sender by return 
email,
delete this message and all copies from your e-mail system, and destroy any 
printed
copies. Receipt by anyone other than the intended recipient should not be 
deemed a
waiver of any privilege or protection. Thales Australia does not warrant or 
represent
that this e-mail or any documents, files and previous e-mail messages attached 
are
error or virus free.
--------------------------------------------------------------------------------------

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to