Hi Sebastian,

As Robert say in its previous mail, he want to depreciate/remove old shader
composition. This is the bad thing.

Cheers
David

2015-02-16 19:03 GMT+01:00 Sebastian Messerschmidt <
[email protected]>:

>  Hi David,
> I don't see where you see problems. The old ShaderComposition is still
> there, and basically nothing has changed, as the new feature is orthogonal
> to the old one.
> I'm using some adapted version of the ShaderComposition framework, and it
> still works with the current trunk, so could you please provide some
> example what is failing?
>
> Cheers
> Sebastian
>
>   Hi Robert, Hi all
>
>
> I also implement a shader composition framework for a client, based on osg
> shader composition, so remove it will be a big loss.
> My implementation handle OpenGL version, some pragma (optimize and
> debug), generate a main function for vertex and fragment shader based on
> what is found in shaderComponent list. So change from previous shader
> composition to new one will not be  straight forward.
>
>
>
>  some thought about new shader composition
>
> 1)
> OpenGL Shading Language specification
> 3.3 Preprocessor :
> #pragma allows implementation dependent compiler control
>
> so pragma "requires" and "import_defines" should be use by shader
> compiler, replace them by "osg_requires" and "osg_import_defines" could
> be prevent futur pragma collisions. Thought ?
>
>  but pragma is an elegant way to insert information directly in shader
> code. well spot !!!
>
>
>
>
> 2)
>  Define a main function with all possibility and use define to choose the
> ones to enable and the ones to not will make
>  a really complex shader, imagine, you optionally use
>  - instancing
> - bump/deplacement mapping
> - vertex blending
> - material/texture/multi-texture
>  - lighting/shadow
>  - fog
>  - physic
>  - one/multi fragment output
>  You will be quickly crazy. The one that work with SpeedTree Shader knows
> what I am talking about.
>  This is why I prefer your previous approach that inject code found in
> StateAttribute in final program.
>  It is also less intrusive. If i need to insert a new shader component in
> the program, no need to change main
>  shader. More over, I introduce some new ShaderAttribute like "camera" to
> define where fragment shader output have to go,
>  or "drawable" to define which vertex shader input are available,
> "Instance" to optionally use draw instance, ... so don't remove Shader
> Attribute. With modern OpenGL and depreciated data like fog, light, ...
> we need a way to introduce our custom attribute.
>  I create a nodekit osgLighting just to manage different light source. I
> have 5 different light source (sun, car, streetlight, ...) that all use
> shaderAttribute to define data that compose the light and shader that use
> this data. So don't remove shaderAttribute this is really a good idea you
> have here !!!
>
>
>  3)
> On a performance point of view, it will be a good thing to use subroutine
> to enable/disable feature.
>  Many different path in shader composition result in many different
> program. And so many change
>  of program in one frame, perhaps use the program A, then the program B,
> then the program A again...
>  This is the main problem I currently have in my shader composition
> implementation.
>
> 4)
>  I always think that lack of define injection in shader is a drawback in
> osg. With your function and name convention,
>  this will be difficult to add this feature. Replace import_define by
> import_module will fix this.
> Because we talk about shader module, lighting, fog, bump mapping, shadow
> ... all of this could be define as shader module.
>
>
>
>
>  I really think that shader composition is a big piece of software,
> really usefull, and really complex.
>  I think we need a  debate about this with all user that have already try
> to implement a shader composition.
>  Clearly define our needs (have reusable module, keep code in shader
> files, use OpenGL feature to improve performance like subroutine,
> pipeline object, ...), debate about solution, propose implementation...
>
>
>  This problem is really new and so few research has be done an the
> subject. I did my first implementation in octobre 2010
>  I have used my shader composition in many way. Found some cool stuff and
> other bad about my design. I look for existing solution
>  on internet, I found some one like libsh <http://libsh.org/> but not
> easy and clean way to solve it. Recently i found CosMo
> <http://www.vrvis.at/publications/pdfs/PB-VRVis-2014-001.pdf> that did
> the job in many way
>  like my implementation, but more deeply in abstraction of the code. They
> don't think in term of shader but in term of
> pipeline graphics, shader composition will decide which code put in
> vertex/tessellation/geometry/fragment shader. I also do this
>  but it's clearly not a good idea.
>
> You propose a clean and (perhaps too) easy way to do the job. This is
> fresh. This is nice to have a new view on this complex problem.
>  So, Robert, Other, we need to talk about this to create a robust, clean
> and easy way to do shader composition.
>
> Thought ?
>
>  My 2 cents
>  David
>
>
>
> 2015-02-13 19:01 GMT+01:00 Robert Osfield <[email protected]>:
>
>>     Hi All,
>>
>>  Attached is a screenshot of running (clock.osgt is in
>> OpenSceneGraph-Data):
>>
>>    osgshadercomposition clock.osgt
>>
>>  A very simple example that provides a single osg::Program that have five
>> different shader combinations used on the same subgraph to produce
>> different results.  From left to right they are:
>>
>>     1) White unlit box - is the default implementation with no define's
>> supplied from osg::StateSet's so no texturing or lighting
>>
>>     2) White lit box - "GL_LIGHTING" define is provided to the shaders
>> via the stateset->setDefine("GL_LIGHTING");
>>
>>     3) Textured unlit box, "GL_TEXTURE_2D" define is provide to the
>> shader via stateset->setDefine("GL_TEXTURE_2D");
>>
>>    4) Textured lit box, both "GL_LIGHTING"  and "GL_TEXTURE_2D" defines
>> are provide via stateset->setDefine("GL_TEXTURE_2D"); etc.
>>
>>     5) As for 4 but a macro function is passed to the shader via :
>>
>>                stateset->setDefine("VERTEX_FUNC(v)" , "vec4(v.x, v.y, v.z
>> * sin(osg_SimulationTime), v.w)");
>>
>>  In each of these instances the define you provide via
>> StateSet::setDefine(DefineString) is mapped to a set of:
>>
>>     #define DefineString
>>
>>  The is passed to the shader compilation.  When
>> StateSet::setDefine(DefineString, DefineValue) is used it's mapped to:
>>
>>    #define DefineString DefineValue
>>
>>  So for the case 5 the Define's passed to the StateSet map to a set of
>> shader lines that are inserted before the body of the shader thus:
>>
>>     #define GL_LIGHTING
>>     #define GL_TEXTURE_2D
>>     #define VERTEX_FUNC(v) vec4(v.x, v.y, v.z * sin(osg_SimulationTime),
>> v.w)
>>
>>  These #defines are then used by the three shaders attached to the
>> osg::Program in the osgshadercomposition example, the first shader is
>> OpenSceneGraph-Data/shader/osgshadercomposition.vert which looks like:
>>
>>  -- start of osgshadercomposition.vert --
>>
>> #pragma import_defines ( GL_LIGHTING, GL_TEXTURE_2D, VERTEX_FUNC(v) )
>>
>> #ifdef GL_LIGHTING
>> // forward declare lighting computation, provided by lighting.vert shader
>> void directionalLight( int lightNum, vec3 normal, inout vec4 color );
>> #endif
>>
>> #ifdef GL_TEXTURE_2D
>> varying vec2 texcoord;
>> #endif
>>
>> #ifdef VERTEX_FUNC
>> uniform float osg_SimulationTime;
>> #endif
>>
>> varying vec4 basecolor;
>>
>> void main(void)
>> {
>>     basecolor = gl_Color;
>>
>> #ifdef GL_LIGHTING
>>     directionalLight( 0, gl_Normal.xyz, basecolor);
>> #endif
>>
>> #ifdef GL_TEXTURE_2D
>>     // if we want texturing we need to pass on texture coords
>>     texcoord = gl_MultiTexCoord0.xy;
>> #endif
>>
>> #ifdef VERTEX_FUNC
>>     gl_Position   = gl_ModelViewProjectionMatrix * VERTEX_FUNC(gl_Vertex);
>> #else
>>     gl_Position   = gl_ModelViewProjectionMatrix * gl_Vertex;
>> #endif
>>
>> }
>>
>> -- end of osgshadercomposition.vert --
>>
>>  First thing of note is the first line:
>>
>>    #pragma import_defines(GL_LIGHTING, GL_TEXTURE_2D, VERTEX_FUNC(v))
>>
>>  This #pragma is read and used by the OSG to tell it what Define's to
>> look up and apply if they are provided in the parental chain of StateSet's,
>> note the matching is case sensitive and in the case of macro VERTEX_FUNC(v)
>> you must use exactly the same parameters including name as the matching is
>> doing straight std::string match internally.  When using import_defines()
>> the defines are all treated as optional, so if they aren't supplied by the
>> StateSet's then nothing is passed along.  Also if you switch off a define
>> via setDefine("GL_LIGHTING", osg::StateAttribute::OFF); then this value
>> will not be passed on.
>>
>> It is intended that the shaders themselves will use #ifdef blocks to
>> enable/disable various features so that all the various paths make sense.
>> This approach make it possible to implement optional varying and uniform
>> usage as well as operations within the main or functions.  It also ensures
>> that the shader compilation done by the drive just compiles what is
>> required, it doesn't have extra uniform variables that might be constant or
>> varyings and uniforms that might not be used in all code paths.
>>
>> --
>>
>>  The second shader is OpenSceneGraph-Data/shaders/lighting.vert that
>> provides the directionalLight() function that is used by the
>> osgshadercomposition.vert main when GL_LIGHTING is enabled via
>> StateSet::setDefine("GL_LIGHTING").  Since this shader is not required when
>> GL_LIGHTING is not defined it's not appropriate to link the shader to
>> Program, so here we provide a #pragma requres(GL_LIGHTING) as a directive
>> to the OSG so it know when to link it.  The shader looks :
>>
>>  -- start of lighting.vert
>>
>>  #pragma requires(GL_LIGHTING)
>>
>> void directionalLight( int lightNum, vec3 normal, inout vec4 color )
>> {
>>     vec3 n = normalize(gl_NormalMatrix * normal);
>>
>>     float NdotL = dot( n,
>> normalize(gl_LightSource[lightNum].position.xyz) );
>>     NdotL = max( 0.0, NdotL );
>>
>>     float NdotHV = dot( n, gl_LightSource[lightNum].halfVector.xyz );
>>     NdotHV = max( 0.0, NdotHV );
>> #if 1
>>     color *= gl_LightSource[lightNum].ambient +
>>              gl_LightSource[lightNum].diffuse * NdotL;
>> #else
>>     color *= gl_FrontLightModelProduct.sceneColor +
>>              gl_FrontLightProduct[lightNum].ambient +
>>              gl_FrontLightProduct[lightNum].diffuse * NdotL;
>> #endif
>> #if 0
>>     if ( NdotL * NdotHV > 0.0 )
>>         color += gl_FrontLightProduct[lightNum].specular * pow( NdotHV,
>> gl_FrontMaterial.shininess );
>> #endif
>> }
>>
>>  -- end of lighting.vert
>>
>> Since this shader requires GL_LIGHTING it doesn't make any sense to had
>> an optional code paths using this define so the shader doesn't have any.
>> If you did want to add in use of defines as in the
>> osgshadercomposition.vert shader you'd need to specify them with an
>> additional #pragma import_defines(...) line as per the
>> osgshadercomposition.vert shader.
>>
>>  The optional linking facility provided by #pragma requires(..) enables
>> on to optionally pull in whole chunks of the shader, so if you wanted you
>> could optional link in a geometry shader, or disable vertex shaders and
>> fallback to use fixed function pipeline if you so wished.  It also allows
>> you to attach multiple shaders to the main osg::Program and have these
>> shaders provide the same functions but each with a different
>> implementation, but then use different define's to pull in the
>> implementation you want and no link the unneeded ones without any conflicts.
>>
>> --
>>
>>  Finally we have the osgshadercomposition.frag shader that does the
>> optional texture mapping, the shader looks like:
>>
>>  -- start of osgshadercomposition.frag
>>  #pragma import_defines ( GL_TEXTURE_2D )
>>
>> #ifdef GL_TEXTURE_2D
>> uniform sampler2D texture0;
>>
>> varying vec2 texcoord;
>> #endif
>>
>> varying vec4 basecolor;
>>
>> void main(void)
>> {
>> #ifdef GL_TEXTURE_2D
>>     gl_FragColor = texture2D( texture0, texcoord) * basecolor;
>> #else
>>     gl_FragColor = basecolor;
>> #endif
>> }
>>  -- end of osgshadercomposition.frag
>>
>>  Note the #pragma import_defines pulls in the optional GL_TEXTURE_2D,
>> and when it's provided both the uniform sample2D texture0; and the varying
>> texcoords are compiled in, along with the texture2D(..) fetch in the main().
>>
>> --
>>
>>  The use of OSG specific #pragma enables the shaders themselves to be
>> passed as-is to the driver to compile and have these custom #pragma's
>> simply ignored by the driver.  This means one can also use the same shaders
>> in non OSG applications, such as developing the shaders in a 3rd party
>> tool.  In this tool you'd need to manually add in the #define's to test the
>> different path ways out and then comment them out/remove them for the final
>> shaders you pass to the OSG so the StateSet::setDefine() magic can provide
>> all the different paths you need.
>>
>>  This ability to have shaders that are readable and usable as-is without
>> code insertion/mucking about by the application is a real bonus.  When I
>> was modifying the old osgshadercomposition code paths (now placed in
>> examples/osgshadercomposition/oldshadercomposition.cpp) I was struck by how
>> hard is was to work on what on earth was going on with how the C++ code
>> passing strings for code injection during shader composition to the final
>> GLSL.  Basically the old way is complicated and so obfuscated it's now
>> seems an obviously bad approach - a case of hard problems needing complex
>> solutions.
>>
>> My hope is that the new "#pragma(tic) shader composition" approach is
>> simple to understand and use, I've certainly found it fun to start using in
>> - it's now used in the new osgTerrain::DisplacementTechnique to enable
>> toggling between different features.  It's actually so simple and powerful
>> I can't believe I never thought of this approach years ago.  I guess that
>> is the way sometimes with hard problems, you spend too close to a problem
>> that the you can't see through the complexity to find a simple solution,
>> but once the simple and elegant solution is presented to you is like it's
>> so OBVIOUS to hard to fathom why it was overlooked for so long.
>>
>>  Given how much user friendly the new approach is over the previous
>> attempts at shader composition like the old osg::ShaderComposition
>> framework and the VirtualProgram approach I believe it's appropriate to
>> deprecate the ShaderComposition, in fact my preference would be to remove
>> it from the OSG as it's just adding weight and complexity to the OSG that
>> offers less power than the new approach.  I know there are some users out
>> there who've worked/modified osg::ShaderComposition framework to work
>> better, so removing it completely will be an initial loss, but I feel
>> keeping the API simpler is worth that bit of pain.  Porting to #pragm(tic)
>> shader composition should be hopefully be relatively straight forward.  The
>> osgvirtualprogram provides another previous attempt that now feel is
>> eclipsed by the new approach so again I'm keen to simple remove it so user
>> don't got learning the wrong things.
>>
>>  For osgEarth, it has it's own VirtualProgram infrastructure that works
>> across a range of OSG versions, but I don't expect any problems so once
>> OSG-3.4 with the new shader composition functionality both will happily
>> work together.  In fact the #pragma's and StateSet::setDefine(..)
>> functionality should hopefully work out of the box with VirtualProgram and
>> make it more flexible and powerful.  Longer term it could be mean that
>> osgEarth::VirtualProgram could be deprecated and new shaders composition
>> used instead, but I don't see any hurry to do this.
>>
>>  Now I've written this baby, it's over to you community, see what fun
>> things you can dream up to do with it ;-)
>>
>>
>>
>>
>>
>> _______________________________________________
>> osg-users mailing list
>> [email protected]
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>
>>
>
>
> _______________________________________________
> osg-users mailing 
> [email protected]http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to