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

