Hi Roland, On Tue, Jun 29, 2010 at 10:22 PM, Roland Smeenk <roland.sme...@tno.nl> wrote: >> 1) Provide a way of encapsulating all the details required to >> contribute a single chunk of functionality that will be combined with other >> active ShaderSet to provide final composed osg::Program. > > Isn't this what I solved with the ShaderMode class?
I believe ShaderMode and ShaderSet are pretty close in concept, the fit a similar role and functionality granularity. Implementation and usage wise they differ, but they have lots of similarity, i.e. they are both big cats, but ones a tiger and ones a lion. > Or is it that you are trying to separate the shader mode associated with a > StateAttribute from the part that is responsible for adding of the piece of > shader functionality. My currently thought is that the various StateAttribute subclasses would provide a standard ShaderSet instance that implements their functionality, but also make it possible to override this standard ShaderSet with custom ones. For instance we might have a standard implementation of osg::Light, but we also want to enable users to have their own implementation, by just providing their own MyCustomPerPixelLightShaderSet. There might also be cases where a osg::StateAttribute subclass might dynamically decide which ShaderSet to use depending upon how it's configured - this would be if we wanted to reduce the number of uniforms by having more pre-configured shaders. > In my contribution I implemented a single ShaderMode that implements all > fixed function lighting possibilities. For new types of lighting it seems > more logical to indeed make a more fine grained breakup of ShaderModes. > > However there's a (minor) advantage to this "one size fits all" lighting code > currently. To enable or disable lighting you simply can override a single > mode. In the case where there are multiple lighting modes (directional, spot > etc.) overall disabling of lighting needs to be done per lighting type. It > might be needed that multiple ShaderSets implementing the same aspect/feature > can be switched on or off all together with a single override. This will also > be needed for instance in shadow map creation where in the first pass you > would like to render geometry into a shadowmap as cheaply as possible and > therefore without lighting. > Perhaps multiple ShaderSets implement a the same aspect/feature in the final > program that need to be disabled or enabled collectively. Again in the case > of shadowmap creation you would like to only render geometry, no texturing, > no lighting, no fog, but you do want to take into account skinned mesh > deformation, wind deflection etc. I don't yet have any concrete plan on how to manage the case where multiple GL enums control particular features. It might be that it'll be best to map some of the controls to uniforms that enable one to toggle features on/off such as lighting, but it might also be that we it could be best to just pass the all modes on the StateAttribute when asking for the appropriate ShaderSet to use and let it decide what to use. This type of issue I expect to fall out of experience with implementing various fixed function functionality such as Lighting. >> 3) The ShaderSet would contain list osg::Shader objects, these osg::Shader >> objects would target which ever part of the overall program that the >> ShaderSet effects - be in multiple osg::Shader for vertex programs, one of >> vertex program one for fragment, or any combination. >> > > I guess you are more targeting shader linking instead of the code generation > that I implemented. Yes, I believe preferring Shader linking over Shader code generation will lead to better performance, more reusability and easier management. One of my plans will be to come up with a ShaderSet file format that will be a subset of use the osgDB serializers to provide .osgt/.osgb/.osg support. This file format would contain the existing serialization for osg::Shader objects, and add the small part of code injection that we'll need. I also want to be able to map this ShaderSet configuration to a C++ source file as well so we can prepare our ShaderSet just be editing a configuration file and do quick runtime testing, then when we're happy with the shaders setup we'd encode this ShaderSet into a .cpp which then provides the default implementation for a particular StateAttribute subclass. I took this approach with the shaders in osgVolume, being able to edit a file and then re-run the application we really effective at cutting the time it took to perfect the shaders. >> The individual osg::Shader objects could also be shared by multiple >> ShaderSet where appropriate. > > It could, but is this likely to happen? We'll find out once we start implementing the fixed function pipeline mapping, but since sharing osg::Shader is already supported in osg::Program providing this capability will effectively be free ;-) >> 5) It might well be that some StateAttribute have unifoms but no ShaderSet, > > I see no logical use case for this. What need is a uniform if there's no > ShaderSet using it? I am thinking of cases where you might want to have a global setting that is used in the shader mains, or a global setting that various separate ShaderSet utilize. >> it might also be appropriate for some StateAttribute to have no uniforms >> and a ShaderSet. >> > > Like the normalize in the fixed function pipeline? Yes, I believe this is a good example. > > Some other notes: > > Like I discussed before I still would like to emphasize the need to be able > to tune performance by balancing between shader program size and number of > program switches. There is no optimal solution before knowing the actual > usage scenario and therefore a user or internal OSG balancing system should > be able to adapt this balance to improve rendering performance. I think this tuning of performance should be possible with the approach I've discussing in this thread, however I don't want to get bogged down too much by optimization right now as the task is complex enough as it is. Once we have an implementation that is working, and has the flexibility for us to customize things at runtime and enables state sorting and lazy state updating then we will have a solution that is reasonably efficient to start with be leave the door open to later optimization. I believe optimization will have to be lead by performance testing across database types, hardware types and drivers. I don't want to make assumption early on about what will and won't be an issue. We need an base implementation before can start doing any testing so this will be my focus for now. > A thing not solved in my ShaderModes based implementation is support for CPU > side calculations needed by the simulation or renderer. This includes > intersection testing and bounding box calculation. When implementing a new > piece of shader functionality (for instance wind deflection) is typically is > not hard to implement the same on the CPU side. If there exists a mechanism > to make the intersection visitor walk through the same ShaderMode tree (or > linked ShaderSets) it could made be possible to actually intersect a tree > swaying in the wind. Ooo I hadn't thought about providing a mechanism for computing vertex positions on the CPU, but this would be very very useful for the quandary of using shaders to modify the vertex positions dynamically. The mechanism would need to know the uniform state and the ShaderSet that are relevant, so the StateAttribute might be the place to couple this. Or perhaps the IntersectionVisitor etc. could accumulate StateSet's and pick out the StateAttribute that effect the vertex position. > To clearify the aspect/feature override part mentioned above here's a > different use case I have in mind. In a scene where it is raining you > typically would want to show all material as being wet. This can be > implemented at several levels of realism. For a quick start I would increase > specular reflection and maybe darken diffuse in the top level StateSet. The > darkening of materials could be made different for several materials in the > scene simply by setting a different uniform darkening value. Some objects in > the scene might implement wetness with a specular cubemap. In case of a road > it might even contain puddles and use a planar reflection of the scene. All > these shader pieces implement the aspect "wetness" in different ways, where > higher fidelity implementations lower in the scene tree override the default > implementation in the top level stateset. And in case you want to disable > "wetness" for the whole scene it should be possible to do so at the top level > stateset similar > to how we are used to disable texturing, lighting etc. This will be an interesting usage case. Once we have an basic implementation in place we could start testing just how capable it is by testing harder usage cases such as the above. I've talked a lot and don't even have anything that can run yet, so I'll have to just keep my sights set for doing simple stuff like lighting and texturing first. Robert. _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org