Hi Roland,

On Wed, Jun 23, 2010 at 11:20 PM, Roland Smeenk <[email protected]> wrote:
> I have to dig up the thoughts I had during the period I implemented the 
> shader composition that you reviewed. The goals you mention where also the 
> ones I tried to achieve.

There are lots of parallels with what thoughts I kicked off in this
thread and your submission, I've been toying with the idea of using
modes for the past six months so when I got your submission it was
great to see how you'd gone in a similar direction.  Implementation
wise is a bit different than what I was thinking, but it spookily
close.  A good sign as clearly we've both working on the same goals.

>
>
> robertosfield wrote:
>>
>> The absolute minimum code changes required in end user apps is none at
>> all, might this be possible?  If that is to be achieved then we need
>> to be able to use the osg::StateSet::setMode(GLenum,...) and all the
>> osg::StateSet::setAttribute(..) and all StateAttributes subclasses
>> that we are familiar with.
> As you probably saw in my submission this can be done for StateAttributes 
> that are set and modes that are automatically applied by a StateAttribute. 
> For explicitly setting GL modes I used a lookup map, which did not really 
> feel like an ideal solution.

To provide the mapping of the fixed function pipeline to shader we'll
have to use maps to catch the appropriate modes.  I do wonder if we
might be able to do some of this internally in osg::StateSet when
setting up modes, this would avoid some of the runtime overhead in
sorting out which modes to path through to glEnable/glDisable and
which ones to pass through to the shader composition.  For a first
pass push this map into osg::State feels reasonable, and perhaps long
term it'll remain the best approach.

I was hoping to avoid the need for ShaderMode and it's subclasses.  I
don't know yet whether this is doable or in the end desirable.   I am
toying with the idea that we might be able to push the implementation
of the shaders to use and the hints/rules on how to compose the
shaders into the final main into osg::StateAttribute, perhaps even
right into the base class.

> robertosfield wrote:
>>
>> Now some parts of OpenGL state are common
>> between the fixed function pipeline and the shader pipeline and live
>> on right from GL1 to GL4 and GLES2, these parts needn't change one bit
>> which is good news.
>
>
> By this you mean the parts of the pipeline that are not (yet) programmable?

I mean modes like enabling and disabling depth test, stencil test,
colour buffers, depth write etc.


> An example of a such a mode is GL_NORMALIZE. It is a mode that doesn't have 
> any additional parameters controlling it and therefore did not need a 
> StateAttribute.
> I tried to solve this with the lookup map I mentioned above. It is the 
> _GLModeShaderModeMap in the osg::State class. It maps modes that are directly 
> set to corresponding ShaderModes.

This is a good point to bring up, if we don't have a separate
ShaderMode scheme like yours how to cope with parts of that have modes
that are enabled/disbable but not actual uniform data associated with
them.   Perhaps a StateAttribute that is non op when running in fixed
function mode, but when still able to provide the Shader/the shader
composition hints/rules.

> Side note:
> In case of shader generation glEnable/glDisable can be implemented in  two 
> ways. We have either the choice to leave out the code of disabled modes and 
> generate a new shader program or disable a piece of shader code in an already 
> existing shader program by wrapping it in an if statement. Both choices 
> should be possible to be able to select the best possible shader program 
> granularity to use at runtime. (big shader program with lot of uniforms for 
> static branching vs. lots of smaller shader programs that are switched during 
> rendering)

I'm inclined to compose only the main() function and leave the bulk of
functionality in shader functions provided by separate osg::Shader
objects.  This main would be composed of all what is required for that
particular mode combination, no if statements, and no uniforms
dictating branches.  This approach makes the assumption that we want
to make the job of drivers GLSL compiler as simple as possible, and
give it the least amount of room to mess up and generate inefficient
code.

>> The second half of this approach would be for the 
>> osg::StateAttrirbute::apply(..) methods to use uniforms to pass in the state 
>> to the shaders rather than their use glFunctionCalls.  Again this is 
>> something that should be possible to hide from the set of those 
>> StateAttribute subclasses and osg::State. I *think* it should be possible to 
>> get something working along these lines.  Implementation will tell us 
>> whether it's possible though.
>
>
> Do you mean that it should be possible to leave for example TexEnv::apply() 
> unmodified?

No, I'm thinking that TexEnv::apply() etc. would all need to modified
to have the old fixed function glFunctionCalls in them and the code
for setting the required Uniforms for the associated shaders.  For the
case of pure GL3/GL4 and GLES2 where no fixed functions exist we'd
just have an #if #else #endif block to make sure that only the uniform
code path is compiled, and the opposite for GLES1.x - only have the
fixed function code path compiled.

> As you probably saw I modified the implementation of TexEnv::apply() to set 
> the needed uniforms needed by the particular piece of shader code 
> implementing TexEnv in shader code.

It's my expectation we'd need to something like your done in
TexEnv::apply(), we may be able to move some of the uniform setting
into the TexEnv::set*() methods, but we will need code to pass these
uniforms on to osg::State.  The later isn't something your approach
does, I'll need to dig back into the code to see how this is done.

It might be that we can formalise the way that osg::State gets the
active uniforms for the osg::StateAttribute rather than have
osg::StateAttribute apply them, right now my gut instinct is the
StateAttribute should push it's active uniforms to osg::State as this
approach would give the most flexibility to StateAttributes about how
they update and apply uniforms.

>
> robertosfield wrote:
> This is exactly the holy grail to achieve. Often the actual compositing is 
> done by letting the users draw the shader graph with a tool or in some other 
> way describing the possible graph layouts. In my implementation I try to 
> dynamically connect shader modes. This is currently done in a limited way as 
> it only involves string based input and output parameter matching. This is a 
> part that needs further attention.

This is part of your design/implementation I need to dive deeper into.
 Right now the OSG's fixed function pipeline set up has both GLenum
telling OpenGL what to do and osg::StateAttribute::Type telling
osg::State/osg::StateSet which attributes are associated with each
other.  I have been wondering about whether a 1 to 1 mapping between
GLenum to the StateAttribute might be better as then we could do away
with the StateAttribute::Type, but as things standard right now we
have attributes like TexGen that can have multiple modes associated
with them.  Breaking this existing mapping up might be advantageous,
but it would break the existing API and OSG application that use it.

With such a major change in functionality as providing shader
composition it well be that we just have to accept that some things
have to be re-factored and that parts of the existing API and usage
will have to be changed.  For now I'll try and look for paths that
gives us all the power whilst minimizing changes to the API and usage.

I'm very conscious of the fact that we have to carry the community
with us through this part of the journey - if we make too many changes
then it will take many years for the community to transition from
OSG-2.x to OSG-3.x, and the longer the transition the fewer testers
and debuggers we'll have to hand and slower the new code will bed in.
Even now you do occasionally see users using OSG-0.9.x and OSG-1.x
reluctant to port to OSG-2.x, this is painful for them and painful for
the rest of the community to support.  If we can just drop OSG-3.x
into a OSG-2.x based app with little changes then we'll put us in a
strong position for pulling the majority of the community with us.


>
> robertosfield wrote:
> Would be great if this could be achieved. This reminds me of one of the 
> additional goals I had in mind:
> Being able to add new pieces of shader code (ShaderModes) at runtime. This 
> would allow loading of complete shader programs created in anyones favourite 
> shader code tool  and create shader modes by splitting it up into pieces 
> based on special comments. This would allow us to prototype shaders in a 
> separate tool and mix it with OSG engine features like shadow mapping or 
> skinned mesh animations (once these are implemented as shader modes).

Being able to swap in shaders at runtime will be very valuable, it
even opens the door to editing shaders and their composition at
runtime which would be very cool :-)

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

Reply via email to