shiny  0.4
a shader and material management library for OGRE
Defining materials and shaders

Your first material

Create a file called "myFirstMaterial.mat" and place it in the path you have used in your initialisation code (see Getting started). Paste the following:

material my_first_material
{
diffuse 1.0 1.0 1.0 1.0
specular 0.4 0.4 0.4 32
ambient 1.0 1.0 1.0
emissive 0.0 0.0 0.0
diffuseMap black.png
pass
{
diffuse $diffuse
specular $specular
ambient $ambient
emissive $emissive
texture_unit diffuseMap
{
texture $diffuseMap
create_in_ffp true // use this texture unit for fixed function pipeline
}
}
}
material material1
{
parent my_first_material
diffuseMap texture1.png
}
material material2
{
parent my_first_material
diffuseMap texture2.png
}

The first shader

Change the 'pass' section to include some shaders:

pass
{
vertex_program my_first_shader_vertex
fragment_program my_first_shader_fragment
...
}
Note
This does not refer to a single shader with a fixed source code, but in fact will automatically create a new instance of this shader (if necessary), which can have its own uniform variables, compile-time macros and much more!

Next, we're going to define our shaders. Paste this in a new file called 'myfirstshader.shaderset'

shader_set my_first_shader_vertex
{
source example.shader
type vertex
profiles_cg vs_2_0 arbvp1
profiles_hlsl vs_2_0
}
shader_set my_first_shader_fragment
{
source example.shader
type fragment
profiles_cg ps_2_x ps_2_0 ps arbfp1
profiles_hlsl ps_2_0
}

Some notes:

Now, let's get into writing our shader! As you can guess from above, the filename should be 'example.shader'. Make sure to also copy the 'core.h' file to the same location. It is included in shiny's source tree under 'Extra/'.

Important: a newline at the end of the file is required. Many editors do this automatically or can be configured to do so. If there is no newline at the end of the file, and the last line is '#endif', you will get the rather cryptic error message " ill formed preprocessor directive: #endif" from boost::wave.

#include "core.h"
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
shVertexInput(float2, uv0)
shOutput(float2, UV)
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
UV = uv0;
}
#else
SH_BEGIN_PROGRAM
// NOTE: It is important that the sampler name here (diffuseMap) matches
// the name of the texture unit in the material. This is necessary because the system
// skips texture units that are never "referenced" in the shader. This can be the case
// when your base material has optional assets (for example a normal map) that are not
// used by some derived materials.
shSampler2D(diffuseMap)
shInput(float2, UV)
SH_START_PROGRAM
{
shOutputColour(0) = shSample(diffuseMap, UV);
}
#endif

There you have it! This shader will compile in several languages thanks to the porting defines in "core.h". If you need more defines, feel free to add them and don't forget to send them to me!

For a full list of macros available when writing your shaders, refer to the page Shader Macros

In the future, some more in-depth shader examples might follow.