OGRE 14.3
Object-Oriented Graphics Rendering Engine
|
When targeting multiple graphics APIs, one typically needs to provide separate shaders for each API. This results in lots of duplicated code gets out of hand quickly.
To support using the same shader code for multiple APIs, Ogre provides the following mechanisms.
#include
directives are universally supported - even with GLSL, so you can rely on them to organised your shaders.The following defines are available:
OGRE_GLSL=120
, OGRE_HLSL=3
OGRE_VERTEX_SHADER
, OGRE_FRAGMENT_SHADER
OGRE_REVERSED_Z
OGRE_NATIVE_GLSL_VERSION_DIRECTIVE
which expands to e.g. #version 300 es
for GLSL programs and nothing on other rendersystems.Additionally, the OgreUnifiedShader.h
provides macros to map GLSL to HLSL and (to some extent) Metal.
As everything is handled by standard macros, the conversion can be performed by simply running the standard c preprocessor (cpp
) on them - even without running Ogre.
In general, you have to do the following changes compared to regular GLSL:
#include <OgreUnifiedShader.h>
directive at the top of the fileMAIN_PARAMETERS
and MAIN_DECLARATION
directives instead of void main()
IN
/ OUT
macros to specify non-uniform parameters that are passed to the main function.OGRE_UNIFORMS
macroSAMPLER2D/3D/CUBE/..
macros instead of sampler2D/3D/Cube/..
mtxFromRows
/ mtxFromCols
to construct matrices from vectorsmul
instead of *
to multiply matricesvec2_splat(1.0)
instead of the vec2(1.0)
single component constructor.Let's take a look at how to use the OgreUnifiedShader.h
macros by starting with a simple GLSL shader:
to make it cross-platform, we need to modify it as:
HLSL_SM4Support.hlsl
providing the SAMPLER*
macros for mapping HLSL9/ Cg and HLSL SM4 (D3D11)GLSL_GL3Support.glsl
providing the IN
/ OUT
macros and texture
aliases for mapping GLSL <= 120 and GLSL >= 130To toggle features on and off use a shader skeleton like this:
then in the material file, you can instantiate 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.