Hi Aurelien,
> About your comments on state attribute :
>
> As an experienced application developper, I can tell that something really
> important is to let the developper have the control on what is executed. For
> example, all "automatic shader generation" methods must be optionnal :
> developper can disable it if needed. Some use case are specific and cannot be
> covered by any generic / automatic code generation system.
My plan was for the users to be able to toggle on/off shader
composition at a subgraph level, right now it can be done via
osg::State but it's not directly supported by an in scene graph
construct, that's something that would come. The approach I was
aiming for was not only could users toggle on/off shader composition
but individually override the shader components for different state
attributes, including the transitional fixed function style ones, so
one could customize things at a fine grained level.
Right now we have osg::Program that works at very coarse grained level
- it's all or nothing w.r..t user written shaders or fixed function
pipeline, this is due to OpenGL more than the OSG's design, the
concept of shader composition is to bridge the two - provide fixed
function equivalent shaders and user shaders that can be composed to
an program that is passed to OpenGL.
> My approach about StateAttributes and "advanced" OpenGL is minimal : provide
> only the data access to avoid the loss of data, but do not provide the
> functionnality. The main idea behind this is the following : when you develop
> an OpenGL based application, you have to choose an OpenGL version.
Understood, this is a little different for shader composition in that
part of it's aim to make it possible to work across different OpenGL
versions more easily - one of the challeneges developers face right
now is that isn't a good bridge between fixed function and shader.
Full shader composition is hard nut to crack though, so adding a few
more steps along the way is sensible if we can expose the feature in a
way that is headed in the same direction as final shader composition.
> 1/ You choose a version with fixed pipeline support, then you can use it and
> it's very suitable for a lot of application.
>
> 2/ You choose an "advanced" version, because you want or you need it. In this
> case, without fixed pipeline you have to develop your own shaders. This is
> more work but allow to do more advanced rendering, and you was warned when
> you made the choice to work with an "advanced" OpenGL version. This is
> mandatory for specific applications (for example data vizualisation
> application may need a special shading system to display data correctly)
>
> 3/ You want "advanced" OpenGL, but with "simple'n'standard" shading (for
> example, for mobile hardware without fixed pipeline at all). This case could
> be covered by the implementation of a default "simple'n'standard" shader
> system in OSG.
>
> But the developper must be able to disable the "simple'n'standard" shader
> system to get a "naked" pipeline and cover the second use case. For example,
> last year I've worked on an application which display 3d data, but not
> "geometric models" : it displays simulation result (still based on a triangle
> mesh), with annotations and visual helpers. In this application, we have
> written our own shading system, without the use of any light source, without
> the use of any standard material or color, but only "scientific" data which
> were computed in Cuda and send as a texture to OpenGL. The shader then
> translate these values into color using different method (LUT,
> tonemapping...) Even the GUI components where not lighted with a light
> source, but as simple lines, circles and squares.
>
> So I think that the best long-tem strategy is to integrate in OSG two
> functionnality :
>
> - made all the deprecated state attributes accessible from shaders using
> "osg_***" uniforms. Maybe select which uniforms to use with a set of flags
> => this ensure that all data contained in a 3d model file are accessible to
> the render pipeline
>
> - create a "simple'n'standard" shading system, which use the "osg_***"
> uniforms and which can be easily enabled/disabled
> => this ensure fixed pipeline emulation on modern hardware
I believe this is what shader composition would provide plus more.
>
> About your comments on shader composition :
>
> I have worked with osgEarth, and I think their VirtualProgram system is
> really great.
> I would like to have a system based on this idea andon the idea of the shader
> composition, something like a "VirtualShader" state attribute which acts as
> follow :
>
> - multiple VirtualShader attributes can be added to a StateSet
> - every time a VirtualShader is applied, a program is generated based on the
> following :
>
> 1/ make a list of all traversed VirtualShaders, one list for each type
> (vertex/fragment/geometry...)
> 2/ prune every list by shader name and override value : there can be only one
> "foo" vertex VirtualShader, one "bar" fragment VirtualShader etc..
> 3/ compile and link all shaders
> 4/ no automatic code generation/injection
>
> With this system you can write a "generic shader" which is bound on the top
> of the scene graph, something like
>
> Fragment VirtualShader named "main" :
>
> Code:
> out vec4 FragColor; // Shader output
> vec4 getFragColor(); // Declaration of a method which should
> return the fragment color : get from vertex, from texture...
> vec4 computeLighting(vec4 color); // Declaration of a method which should
> compute the lighting of a fragment
>
> main
> {
> vec4 color = getFragColor();
> vec4 lightedColor = computeLighting(color);
> FragColor = color;
> }
>
>
>
>
> Fragment VirtualShader named "getFragColor" :
>
> Code:
> vec4 getFragColor() // implementation of a default frag color
> getter
> {
> return vec4(1.0, 1.0, 1.0, 1.0); // return white
> }
>
>
>
>
> Fragment VirtualShader named "computeLighting" :
>
> Code:
> vec4 computeLighting(in vec4 color) // implementation of a
> default lighting equation
> {
> return doSomePhongStuff; // return the result of a lighting equation
> : Phong, Cook-Torrance, a mesuread BRDF...
> }
>
>
>
>
> And then, on a node which use a texture, simply add this shader :
>
> Fragment VirtualShader named "getFragColor" :
>
> Code:
> in vec2 textureCoords // varying which is an output of the vertex
> shader
>
> vec4 getFragColor() // override the implementation of the default
> frag color getter
> {
> return texture2D(textureCoords); // return the texture color
> }
>
>
>
>
> On a node which should be rendered using another lighting equation :
>
> Fragment VirtualShader named "computeLighting" :
>
> Code:
> vec4 computeLighting(in vec4 color) // override the
> implementation of the default lighting equation
> {
> return doSomeOtherStuff;
> }
>
>
>
>
> and of course, if you need to modify the "main" structure, just add a
> VirtualShader named "main".
>
>
> With this :
>
> - you can separate the main rendering logic (a "main" shader on top of scene
> graph) and the data getter (each node may have a different getFragColor()
> method, with texure sampling or constant value or osg_Material use, or
> anything else....)
> - your code is never modified : what you is code is what is compiled, what is
> linked and what is excuted
> - no code source merging
> - every shader is compiled separately : it's easier to debug, and maybe allow
> to share more resources between nodes (I don't know if a shader instance can
> be linken to diferrent program)
>
> And, last but not least, if you need to render anything else than a standard
> rendering, you just have to create your specific "main" shader which can be
> really different than any classic shader.
>
> => If you need to render only a sub-graph using different equations (separate
> the GUI and the scene for example), you can have a common data access logic
> (a set of "get***()" methods) and different "main" shaders on the top of the
> different branchs of the scene graph.
We have the osgvirtualprogram example, is this same approach as used
in osgEarth. In my review of the VirtualProgram approach I found
problems in it's design and implementation that weren't able to
address all the issues I wanted to achieve with a full blown shader
composition. It solves some of the problems but not enough so I felt
it was a dead end. I have to admit I am cold on the topic and it
being so complicated I can't just dive in and provide all the ins and
outs.
For the problem you are looking at right now I feel that one needs to
look at how osg::StateAttribute subclasses and the OpenGL fixed
function attributes they are associated map to one or more uniforms.
It may be appropriate for osg::StateAttribute base class to have
generic access functions to managing Uniforms. For instance a colour
that we store as an osg::Vec4 right now would map to a osg::Uniform
that contains four floats and with a name that is appropriate. Blocks
of Uniforms would naturally map to a struct. I haven't worked on the
design for so long I can't say exactly how it all be managed, but
essentially you'd need to have osg::State collecting the uniforms from
the StateAttribute that have them and applying them as standard
Uniforms. It might be that we'd want to evolve the current way that
osg::Uniform are assigned to osg::StateSet to keep a scheme consistent
between uniforms in osg::StateAttribute vs attached directly to the
the osg::StateSet.
Robert.
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org