How to make a shader - Quick documentation

Welcome to our brand new Clickteam Community Hub! We hope you will enjoy using the new features, which we will be further expanding in the coming months.

A few features including Passport are unavailable initially whilst we monitor stability of the new platform, we hope to bring these online very soon. Small issues will crop up following the import from our old system, including some message formatting, translation accuracy and other things.

Thank you for your patience whilst we've worked on this and we look forward to more exciting community developments soon!

Clickteam.
  • 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

    Code
    struct PS_INPUT
    {
        float4 Position   : POSITION;
        float2 Texture    : TEXCOORD0;
    };

    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).

    Code
    struct PS_OUTPUT
    {
        float4 Color   : COLOR0;
    };


    This structure defines the output value of the pixel shader function. It's a simple RGBA value.


    Variables

    Code
    sampler2D img;

    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 :

    Code
    int var1;
    float var2;
    float4 var3;

    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 :

    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.

    Code
    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 :

    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).

  • Nice tutorial and a great reference to look up the XML elements. :D

    Anyway, I have a question.
    Why do you use PS_OUTPUT and PS_INPUT?

    The ps_main() example function could be done like this as well.

    Please login to see this link.

  • You're correct, no need to use the input / output structures. Initially I took a shader example from the DX SDK, and I didn't want to modify it. I also thought vertex shaders would work, but that was not possible - that will be possible probably in MMF3.

    So yes one can use your syntax too. :)

  • I'm having difficulties with making a shader. I've been trying to make one that scales the object. This is the code:

    The FX file:

    And the XML file:

    It's supposed to grow/shrink the object. However, it doesn't work. The shader does absolutely nothing (unless the value is below 1.0, in which case, it makes the object disappear altogether). Can anybody help me out here?

    My Please login to see this link. (which I actually use), my Please login to see this link. (which I mostly don't use), and my Please login to see this link. (which I don't use anymore pretty much at all really). If there are awards for "'highest number of long forum posts", then I'd have probably won at least 1 by now. XD

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!