OGRE
1.12.13
Object-Oriented Graphics Rendering Engine
|
Writing shading programs is a common task when developing 3D based application. Most of the visual effects used by 3D based applications involve shader programs. Additionally with D3D11/ GL3, support for fixed pipeline functionality was removed. Meaning you can only render objects using shaders.
While GPU Program Scripts offer you maximal control and flexibility over how your objects are rendered, writing and maintaining them is also a very time consuming task.
Instead Ogre can also automatically generate shaders on the fly, based on object material properties, scene setup and other user definitions. While the resulting shaders are less optimized, they offer the following advantages:
The system is implemented as a component, so you can enable/ disable it at compile time.
#ifdefs
that make it increasingly difficult to add new functionality. Instead, it manages a set of opaque isolated components (SubRenderStates) where each implements a specific effect. These "effects" notably include full Fixed Function emulation. At the core these components are plain shader files providing a set of functions. The shaders are based on properties defined in Material Scripts.In case, you are not conviced and want to go with your hand-rolled uber shader, here are some tips:
#include
directives universally - even with GLSL, so use them to split up your shader.OgreUnifiedShader.h
header provides macros to map GLSL to HLSL and (to some extent) Metal. This allows you to write shader code once and use it for multiple rendersystems.HLSL_SM4Support.hlsl
helper allows mapping HLSL9/ Cg to HLSL SM4 (D3D11), if you only target D3D.Then you can have a shader skeleton like this:
then in the material file, you can instanciate it as:
and reference it with your materials.
Incidentally, this is very similar to what the RTSS is doing internally. Except, you do not need the preprocessor_defines
part, as it can derive automatically from the material what needs to be done.
When the early graphic cards came into the market they contained a fixed but large set of functions with which you could influence how 3D object were rendered. These included influencing object positions using matrices, calculating the effect of textures on a pixel, calculating the effect of lights on vertices and so on. These set of functions and their implementation in hardware became later known as the graphic card fixed pipeline (or Fixed Function Pipeline).
As graphic cards became more powerful and graphic application became more complex, a need for new ways to manipulate the rendering of 3D models became apparent. This need saw the introduction of shaders.
Shaders are small custom made programs that run directly on the graphics card. Using these programs, one could replace the calculations that were made by the fixed pipeline and add new functionality. However there was a catch: If shaders are used on an object, the object can no longer use any of the functionality of the fixed pipeline. Any calculation that was used in the fixed pipeline needed to be recreated in the shaders. With early graphics applications this was not problematic. Shaders were simple and their numbers were kept low. However as applications grew in complexity this meant that the need for shaders grew as well. As a programmer you were left with 2 choices, both bad. Either create an exuberant amount of small shaders that soon became too many to effectively maintain. Or create an uber shader, a huge complex shader, that soon became too complex to effectively maintain as well.
The RTSS seeks to fix those problems by automatically generating shaders based on the operations previously required from the fixed pipeline and new capabilities required by the user.
With the introduction of the version 11 of Direct3D, a new reason for having an RTSS like system became apparent. With D3D11 support for fixed pipeline functionality was removed. Meaning, you can only render objects using shaders. The RTSS is an excellent tool for this purpose.