RT Shader System Component (RTSS)
Posted: Thu Aug 27, 2009 12:29 pm
Hi –
In the last few weeks I've been working on a runtime shader system component. (RTShader System).
The need for such a system comes from the demand to reduce the amount of work needed by writing many shader programs for each material in my system.
Another issue I had to tackle is that some components in my application generate materials during the runtime, so the actual shader code of these materials is not predictable and therefore I can't write an appropriate shader programs in advance.
The main goals for this system are –
1.Be able to take an existing Technique and create an equivalent technique that goes thru shader rendering pipeline.
I.E – In case you're application base content composed of many materials that rendered only with the FFP and you want them all to be rendered with shader programs, the RTShader System will allow you doing so without writing single line of shading code.
2.Be able to extend the system beyond the core implementation of the fixed function pipeline.
I.E adds per pixel lighting support for all the material in the system, or basically any shader based effect.
Possible future uses of this component are:
1.Seamlessly support shader based render system such as D3D10 and OpenGL ES 2.0.
2.Implement visual shader editor that will enable to artist with zero knowledge in shading languages to create shader based materials.
The RT Shader System component composed of the following interface:
1.ShaderGenerator – this is a singleton class that enables the creation of shader based technique for a given material.
2.RenderState – this class use to define a complete set of rendering states from which one can create a set of shader programs.
3.SubRenderState – this class is abstract interface for detailed sub part of render state. Each sub state of render state should derive from it and implement the pure methods it declares. The RTShader System contains sub class implementation for all Fixed Function Pipeline sub components: FFPTransform, FFPLighting, FFPTexturing, FFPColour and FFPFog.
4.ProgramWriter – singleton class that perform the actual conversion from a CPU shader program classes to
GPU programs.
In order to create shader based technique for specific material one should call the ShaderGenerator::createShaderBasedTechnique and pass to it the name of the material, name of the source technique scheme and name of the destination technique scheme name.
In case of success, a new technique will be created in this material and it will be using shader programs that will emulate the exact behavior of the source technique as if rendered using the fixed pipeline.
In order to use the new technique, one can simply change to material scheme name of the viewport(s) he uses and then the internal mechanism of Ogre will automatically choose the appropriate technique to use during the rendering process.
In order to use shader based effect one should be familiar with the concept of RenderState and SubRenderState classes, then implement the desired effect by creating new sub class of SubRenderState and finally apply this custom render state either to the whole scheme or just for specific material.
The basic concept that stands beyond the shader code generation is to use a set of predefined shader functions and link them together by need at runtime by the render state definition.
The RT Shader System comes with set of shader libraries that contains implementation of the Fixed Function Pipeline:
FFPLib_Common.cg , FFPLib_Transform.cg, FFPLib_Lighting.cg , FFPLib_TextureStage.cg, FFPLib_Fog.cg.
Currently the system supports only CG as target shader language.
In order to support other languages we'll have to port these libraries to the desired shading language. This can be useful for situations where CG shader code is not enough.
In order to compile and use the RT Shader System one should define the OGRE_BUILD_COMPONENT_RTSHADERSYSTEM option as TRUE in the CMakeLists.txt file under the root folder of the source code.
I personally use the CMake GUI application to do that.
Then the OgreRTShaderSystem project is added to the Ogre solution and basic demonstration code is added to the basic demo's framework.
On each sample that uses this framework pressing the F3 Key will cause to every material in the scene to be rendered using a shader based technique and pressing the F2 key will switch back to default material behavior.
Future work Steps –
1.Add common shading effects implementation to the system - per pixel lighting, bump map, etc.
2.Integrate to D3D10 render system.
The RTShader System is not aware of the vertex declaration while it generates the shader code and therefore it may result in creating functions prototype that doesn’t fit the incoming vertex streams.
In order to integrate with D3D10 render system a bridge layer should be implemented to overcome the strict demand of 1 to 1 matching between vertex declaration and shader entry point prototype. This layer will simply add adapter entry function that matches the vertex declaration and it will call the original function with the appropriate parameters adjustments.
BTW – During the integration with the samples I found a crash in the OgreMain module caused by using NULL pointer, it is in the OgreMovableObject.cpp in MORecvShadVisitor::visit method that reference a Renderable object technique without checking its value.
The RTSahder System patch can be found here
https://sourceforge.net/tracker/?func=d ... tid=302997
The MovableObject crash fix patch can be found here
https://sourceforge.net/tracker/?func=d ... tid=302997
I'll keep updating my progress later on…
In the last few weeks I've been working on a runtime shader system component. (RTShader System).
The need for such a system comes from the demand to reduce the amount of work needed by writing many shader programs for each material in my system.
Another issue I had to tackle is that some components in my application generate materials during the runtime, so the actual shader code of these materials is not predictable and therefore I can't write an appropriate shader programs in advance.
The main goals for this system are –
1.Be able to take an existing Technique and create an equivalent technique that goes thru shader rendering pipeline.
I.E – In case you're application base content composed of many materials that rendered only with the FFP and you want them all to be rendered with shader programs, the RTShader System will allow you doing so without writing single line of shading code.
2.Be able to extend the system beyond the core implementation of the fixed function pipeline.
I.E adds per pixel lighting support for all the material in the system, or basically any shader based effect.
Possible future uses of this component are:
1.Seamlessly support shader based render system such as D3D10 and OpenGL ES 2.0.
2.Implement visual shader editor that will enable to artist with zero knowledge in shading languages to create shader based materials.
The RT Shader System component composed of the following interface:
1.ShaderGenerator – this is a singleton class that enables the creation of shader based technique for a given material.
2.RenderState – this class use to define a complete set of rendering states from which one can create a set of shader programs.
3.SubRenderState – this class is abstract interface for detailed sub part of render state. Each sub state of render state should derive from it and implement the pure methods it declares. The RTShader System contains sub class implementation for all Fixed Function Pipeline sub components: FFPTransform, FFPLighting, FFPTexturing, FFPColour and FFPFog.
4.ProgramWriter – singleton class that perform the actual conversion from a CPU shader program classes to
GPU programs.
In order to create shader based technique for specific material one should call the ShaderGenerator::createShaderBasedTechnique and pass to it the name of the material, name of the source technique scheme and name of the destination technique scheme name.
In case of success, a new technique will be created in this material and it will be using shader programs that will emulate the exact behavior of the source technique as if rendered using the fixed pipeline.
In order to use the new technique, one can simply change to material scheme name of the viewport(s) he uses and then the internal mechanism of Ogre will automatically choose the appropriate technique to use during the rendering process.
In order to use shader based effect one should be familiar with the concept of RenderState and SubRenderState classes, then implement the desired effect by creating new sub class of SubRenderState and finally apply this custom render state either to the whole scheme or just for specific material.
The basic concept that stands beyond the shader code generation is to use a set of predefined shader functions and link them together by need at runtime by the render state definition.
The RT Shader System comes with set of shader libraries that contains implementation of the Fixed Function Pipeline:
FFPLib_Common.cg , FFPLib_Transform.cg, FFPLib_Lighting.cg , FFPLib_TextureStage.cg, FFPLib_Fog.cg.
Currently the system supports only CG as target shader language.
In order to support other languages we'll have to port these libraries to the desired shading language. This can be useful for situations where CG shader code is not enough.
In order to compile and use the RT Shader System one should define the OGRE_BUILD_COMPONENT_RTSHADERSYSTEM option as TRUE in the CMakeLists.txt file under the root folder of the source code.
I personally use the CMake GUI application to do that.
Then the OgreRTShaderSystem project is added to the Ogre solution and basic demonstration code is added to the basic demo's framework.
On each sample that uses this framework pressing the F3 Key will cause to every material in the scene to be rendered using a shader based technique and pressing the F2 key will switch back to default material behavior.
Future work Steps –
1.Add common shading effects implementation to the system - per pixel lighting, bump map, etc.
2.Integrate to D3D10 render system.
The RTShader System is not aware of the vertex declaration while it generates the shader code and therefore it may result in creating functions prototype that doesn’t fit the incoming vertex streams.
In order to integrate with D3D10 render system a bridge layer should be implemented to overcome the strict demand of 1 to 1 matching between vertex declaration and shader entry point prototype. This layer will simply add adapter entry function that matches the vertex declaration and it will call the original function with the appropriate parameters adjustments.
BTW – During the integration with the samples I found a crash in the OgreMain module caused by using NULL pointer, it is in the OgreMovableObject.cpp in MORecvShadVisitor::visit method that reference a Renderable object technique without checking its value.
The RTSahder System patch can be found here
https://sourceforge.net/tracker/?func=d ... tid=302997
The MovableObject crash fix patch can be found here
https://sourceforge.net/tracker/?func=d ... tid=302997
I'll keep updating my progress later on…