The documentation below is very basic, it explains the global structure and how it interfaces with MMF2, it doesn't explain how shaders work. For more info about shaders look at the DirectX documentation.
A DirectX effect is contained in a .fx file. A .fx file is a source code file that usually contains :
- the definition of input / output data structures
- the global variables used by the shader
- the shader function(s)
This documentation only explains the structure of a .fx file.
In MMF2 the .fx file is associated with a .XML file that contains info about the shader : name, parameters, author, etc.
If you have never made a pixel shader, I suggest that you look at the source code of the Horizontal Flip effect of MMF2 (Please login to see this link. files in the MMF2 Effects directory) while you are reading this documentation.
FX file
Input / output parameters
This structure defines the input parameters passed to the pixel shader function. The Texture variable contains the X and Y coordinates of the pixel in the texture being processed. Those coordinates are UV coordinates, between 0 (left/top) and 1 (right/bottom).
This structure defines the output value of the pixel shader function. It's a simple RGBA value.
Variables
This is the minimum global variable to define in a shader, it contains a 2D sampler associated with the texture passed to the shader (the object's image).
If your shader needs to access the background, add the following sampler2D for the background texture :
sampler2D bkd : register(s1);
You will need to specify <BackgroundTexture>1</BackgroundTexture> in your XML file, see below.
If your shader accesses other images, add one sampler2D per image :
sampler2D image1 : register(s1);
sampler2D image2 : register(s2);
etc.
Start from register(s2) if you also use a background image sampler. And you will need to add these images as parameters in your XML file.
Other variables :
Optional, defines global variables that you can use in your shader function. You have to add a <parameter> section in the XML file for each variable you need to retrieve/change from the MMF events and properties. 3 data types are supported in the MMF2 events and properties :
int = integer value
float = floating point value
float4 = set of 4 floating point values between 0 and 1 that correspond in MMF to a RGBA color (each component between 0 and 255 in MMF is converted to a floating point value between 0 and 1). In the XML file this type of variable must be used in conjunction with the int_float4 property type.
Predefined variables
- declare the fPixelWidth and fPixelHeight values if you need to know the width and height of a pixel (equal to 1/texture_width and 1/texture_height) :
float fPixelWidth;
float fPixelHeight;
Shader function
The shader function is called for each pixel in your object's image. It gets as input parameter the coordinates of the pixel in the texture and must return the color of the pixel.
Example of pixel shader function :
PS_OUTPUT ps_main( in PS_INPUT In )
{
PS_OUTPUT Out;
float2 coord;
coord.x = 1.0-In.Texture.x;
coord.y = In.Texture.y;
Out.Color = tex2D(img, coord);
return Out;
}
Display More
As explained above in the "input / ouput parameters" section, In.Texture contains the pixel coordinates (between 0 and 1), and the function returns the color of the pixel.
tex2D(img, xy) is a HLSL function that returns the color of the pixel at the xy coordinates in the img sampler.
The routine above just flips the image horizontally.
technique tech_main
{
pass P0
{
// shaders
VertexShader = NULL;
PixelShader = compile ps_1_4 ps_main();
}
}
This section allows to specify the shader function (ps_main) and the minimum shader version number it requires, here 1.4. You can also set render states.
More info about shaders in the HLSL documentation on MSDN :
Please login to see this link.
Some tutorials found via Google :
Please login to see this link.
Please login to see this link.
Please login to see this link.
Please login to see this link.
Please login to see this link.
There are others. And take a look at the source code of the MMF2 shaders made by Sphax, Looki, etc, they probably contain examples for everything you want to do.
XML file
Contains info about the shader and its (optional) parameters :
<effect>
<name>Put here the effect name</name>
<description>Put here a description of the effect, displayed in the Effects dialog box</description>
<author>Your name here</author>
<company>Your company here</company>
<copyright>Copyright @ 2009 Your Company</copyright>
<website>www.your_web_site.com</website>
<email>someone@somewhere.com</email>
<dx8>yes or no, depends if your shader works wirh DirectX 8 (usually no unless your shader is in asm)</dx8>
<parameter>
<name>Name of parameter 1, displayed in the properties</name>
<variable>Variable name in the .FX file (and used in the event editor)</variable>
<description>This variable does this...</description>
<type>variable type : either INT, FLOAT, INT_FLOAT4, IMAGE</type>
<property>Property type : EDIT, SPIN, SLIDER, CHECKBOX, COLOR, IMAGE</property>
<value>initial value</value>
<min>minimum value</min>
<max>maximum value</max>
<delta>step value, for FLOAT + SPIN only</delta>
<preview_value>value used for the preview in the Effects dialog box</preview_value>
</parameter>
<parameter>
<name>Name of parameter 2</name>
etc...
</parameter>
etc...
</effect>
Display More
All the fields are optional, except for the name of the shader and the parameters if any.
The content of the "value" line depends on the variable type :
- INT : integer value
- FLOAT : floating point value
- INT_FLOAT4 : integer value that contains 4 values between 0 and 255, used for RGBA color values. These values are transformed to a float4 variable, that contains 4 floating point values between 0 and 1 (1 corresponds to 255). This parameter type is generally used with the COLOR property type.
- IMAGE : the value is the name of a graphic file in the Effects directory. This file is loaded when the user sets up the shader in the properties, and then the image is stored in the MFA file, the user can modify it with the MMF picture editor. The IMGE property type can be used only with the IMAGE type (and reciprocally).