Mewa Film User's Guide/Extending Mewa Film with MFX files

From Wikibooks, open books for an open world
< Mewa Film User's Guide
Jump to: navigation, search

Introduction[edit]

This chapter explains how to extend the out-of-the-box feature set of Mewa Film with MFX files. MFX files encapsulate node behavior, they can be used to create specific image processing algorithms, to create 3D effects, and much more. Once a MFX file is imported it become accessible to the node graph using the nodes toolbar, like any other node.

To create a MFX file you must have knowledge on GLSL programming and understand XML.

MFX files use GLSL shaders to apply effects over images or a 3D scene. For those who don't know, GLSL is a high level shading language to create effects that run on graphics hardware, and so, using MFX files you can create your own effects very quickly and achieve a degree of performance only offered by accelerated hardware.

Because MFX files are dependent on the graphics hardware, older graphics hardware might not support all MFX files.

What is a MFX file?[edit]

An MFX file is called MFX because it's file name ends with .mfx. An MFX file holds the GLSL source code and a description of the GUI controls that manipulate the effect.

For artists and developers of real-time graphics, this format provides cross-platform compatibility of an effect with behaviour and GUI descriptions embedded in one file.

GLSL developers can describe a complete rendering effect in a .mfx file. Although individual MFX programs may contain the core rendering algorithms necessary for an effect, only when combined with this additional environmental information does the shader become complete and self contained. The addition of artist-friendly GUI descriptions and fallbacks enables MFX files to integrate well with the production workflow used by artists and programmers.

To better understand how to create MFX files lets analyse the underwater effect applied over a image.

Underwater effect

Below is a brief explanation of the underwater MFX file for better understand the idea behind MFX files.

MFX file source explained

How to use a MFX file?[edit]

All MFX files are located inside the 'effects' folder in Mewa Film installation directory. To use a new MFX file just copy your .mfx files to the folder effects in Mewa Film installation directory. An easy way to create your own MFX files is by modifying an existing MFX files (underwater.mfx and over.mfx).


MFX files contain GLSL code that needs to be compiled. The MFX file is compiled when added as node, from the nodes tool bar, to the node graph. If the MFX file does not compile it will become disabled from the nodes tool bar and the only way to enable it back is by restarting the application.

Remember that the MFX file is compiled on your graphics hardware, and so more elaborated MFX files might not work on older graphics hardware.


To help you create your own MFX files the MFX files info window was introduced.

MFX file info dialog

To open the MFX Files Info window choose the menu Help >> MFX Files Info. All the MFX files found inside effects folder are shown in the MFX file info list. To check your MFX file for any error, choose your MFX file from the shown list and press Refresh File. The status column prints Success if the MFX file build without errors and is ready to be used, otherwise the error is printed.


Summarizing, you can edit the MFX file with your favourite text editor, save your changes, check if it compiles on the 'MFX files info' dialog, and once compiled verify its behaviour using it in the node graph.

MFX file format overview[edit]

A .mfx file starts with the element MewaFilmNode and has the following obligatory attributes:

  • Name
  • and Output
<MewaFilmNode Name="MyEffect" Output="Image">
  ...
</MewaFilmNode>

The Output element can be set to one of two options:

  • Image
  • Scene3D

Mewa Film node graph has two kinds of nodes, image processing nodes and 3D scene nodes. The kind of node is defined by the node output. If the output of a node is an image then the node is a image processing node and will be added to the image processing tools, if the output is Scene3D the node is a 3D node and will be added to 3D tools.

Other optional attributes can be set to MewaFilmNode element, those are the output node tool tip, and a help address.

<MewaFilmNode Name="MyEffect" Output="Image" ToolTip="Magnific effect">

Node inputs[edit]

Node inputs are calculated by reading order of Sampler2DRect in the vertex shader. e.g. a vertex shader that starts with the following text,

...
uniform sampler2DRect backImage;
uniform sampler2DRect frontImage;
...

backImage will be attached to TEXTURE0 and frontImage will be attached to TEXTURE1. These sampler2DRect are input nodes and added from left to right of the node. You can add sampler2DRect to a maximum of 6.

The PortTooltip is the tool tip shown when the mouse is over a node port.

<Input Tooltip=""></Input>
<Input Tooltip="Input image"></Input>

Note that doesnt matter what kind of inputs, Image and Scene3D, tool tips are set by order of appearance.

UI parameters[edit]

Inside a MewaFilmNode element goes the GUI controls, to manipulate node's parameters, and the shaders source.

The UI controls are used to update shader's uniform variables. The GLSL data types that are available to use with UI controls are:

  • float
  • vec2
  • vec3
  • vec4


The UISpinner is a spinner wheel control used to control values from -\infty to +\infty. The UISpinner has the following attributes,

  • Name defines the name
  • Step defines the step value for each tick, also know as precision
  • Default defines the default value


UISlider is a slider control, usefull to manipulate values inside a range. The UISlider has the following properties,

Slider control
  • Name defines the name
  • Step defines the step value for each tick, also know as precision
  • Default defines the default value
  • Min defines the slider minimum value
  • Max defines the slider maximum value


UIColor is a color selection widget where the user can choose a color using RGB sliders or from a color dialog. Colors are represented by 3 float values that can range between 0 and 1. The UIColor has the following properties,

Color control
  • Name defines the name
  • DefaultRed default red color
  • DefaultGreen
  • DefaultBlue

The UIColor widget can be only be used to modify vec3 or vec4 GLSL data types.

If you want to use a vec4 as a color,

<UniformVariable Type="vec4" Name="color">
    <UIColor Name="Background"  DefaultRed="0.0" DefaultGreen="0.0" DefaultBlue="0.0"></UIColor>
    <UISlider Step="0.01" Name="Alpha"  Min="0.0" Max="1.0" Default="1.0"></UISlider>
</UniformVariable>


Parameters are inside tabs.

<Tab Title="Position">
  <UniformVariable Type="float" Name="test">
    <UISpinner Step="0.01" Name="Scale" Default="0.3"></UISpinner>
  </UniformVariable>
</Tab>


Because the vec4 variable type contains 4 values we need 4 UI widgets to manipulate each of the value.

<UniformVariable Type="vec4" Name="test">
  <UISlider Min="0.0" Max="10.0" Step="0.01" Name="X" Default="0.3"></UISlider>
  <UISlider Min="0.0" Max="10.0" Step="0.01" Name="Y" Default="0.2"></UISlider>
  <UISlider Min="0.0" Max="10.0" Step="0.01" Name="Z" Default="0.0"></UISlider>
  <UISlider Min="0.0" Max="10.0" Step="0.01" Name="A" Default="0.1"></UISlider>
</UniformVariable>

You can group all the UI widgets from a uniform variable inside a groupBox by adding the XML attribute UIName="GroupName",

<UniformVariable Type="vec4" Name="test" UIName="Test Variable">
  ...
</UniformVariable>

Shader source[edit]

The most important information in a MFX file is the GLSL source, it defines what the effect will do. The GLSL source is divided in two shaders, VertexShader and FragmentShader.

The vertex shader source comes between <VertexShader> and <VertexShader>. Below is a example of a vertex shader inside a MFX file.

...
<VertexShader>
  uniform sampler2D displacementMap;
  void main(void)
  {
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
  }
</VertexShader>
...

The fragment shader is added to the MFX file in the same way, but comes between <FragmentShader> and </FragmentShader>.

The shader source needs to written in GLSL ES. For GLSL programmers this means that the precision keyword cannot be used.

Examples[edit]

To use the examples, open a text-only (plain text) editor. Usualy notepad on windows, vi or emacs on linux. Copy and paste the example to the opened file and save it with a name followed by .mfx. Now just move the MFX file to <MewaFilm_directory>/effects.

Image processing node example[edit]

<MewaFilmNode Name="RedDivide" Output="Image" ToolTip="Simple effect">

<Input ToolTip="input image"></Input>

<Tab Title="Position">
  <UniformVariable Type="float" Name="split">
    <UISpinner Name="Scale" Step="1.0" Default="40.0"></UISpinner>
  </UniformVariable>
</Tab>


<VertexShader>
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
</VertexShader>

<FragmentShader>
uniform sampler2DRect colorMap;
uniform float split;
                                                 
void main(void)
{
  vec4 sum = vec4(0.0);

  if(gl_TexCoord[0].s &lt; split)
  {
    sum = texture2DRect(colorMap, gl_TexCoord[0].st );
  }
  else
  {
    sum = vec4(1.0, 0.0, 0.0, 0.5);
  }

  gl_FragColor = sum;
}
</FragmentShader>

</MewaFilmNode>

3D node example[edit]

The example below is a color effect.

<MewaFilmNode Name="ColorsEffect" Output="Scene3D">

<VertexShader>
varying float xpos;
varying float ypos;
varying float zpos;
void main(void)
{
        gl_Position = ftransform();
        xpos = clamp(gl_Vertex.x,0.0,1.0);
        ypos = clamp(gl_Vertex.y,0.0,1.0);
        zpos = clamp(gl_Vertex.z,0.0,1.0);
}
</VertexShader>

<FragmentShader>
varying float xpos;
varying float ypos;
varying float zpos;
void main (void)
{
        gl_FragColor = vec4 (xpos, ypos, zpos, 1.0);
}
</FragmentShader>

</MewaFilmNode>

Considerations to take when writing MFX files[edit]

Texture coordinates[edit]

Shders in MFX files must use Sampler2DRect, not Sampler2D. With Sampler2DRect you access image pixels using non-normalized coordinates, this means, pixels coordinates vary from 0 to image width and image height, e.g. to get the pixel 12,12 you do

vec4 pixel = texture2DRect(image, vec2(12,12) );

The pixel at position (0,0) is at the bottom left corner of the image. The xx axis increases to the right side and the yy axis increases up.

Image size in shaders[edit]

It's possible to get information about the size of the input Sampler2DRect inside shaders. Just declare the uniform variable mfx_image<Width|Height><Sampler>, like shown below.

uniform int mfx_imageWidth0;
uniform int mfx_imageHeight0;

The zero at the end of the variable name represents Sampler2DRect number. Sampler2DRect's are numbered by reading order, this means, the first declared Sampler2DRect is 0, the second is 1, and so on.

XML reserved symbols[edit]

Because .mfx files use xml syntax, the following symbols are "reserved" and may not be used in an instance document's data.

     <  >  &  "  '

Instead, the "escaped" version, at the table below, must be used.

Symbol "escaped" version
< &lt;
> &gt;
& &amp;
" &quot;
' &apos;


However, you don't need to "escape" the symbols >, ", or ' you do need to escape >, ", and '.