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

