Using effect files

WME allows you to apply so-called "effect files" to 3D objects. Effect files (files with the .fx extension) are standard DirectX text files, describing advanced materials. You are probably familiar with applying textures to 3D objects. Effect works similarly, to certain degree, but instead of just textures, they define rendering instructions for a specific 3D object. Those include vertex and pixel shaders to be used, as well as various render states. Additionally, one effect file can contain multiple "techniques", i.e. multiple ways of achieving the effect, depending on available hardware capabilities. The most appropriate technique is then selected at runtime. Each technique can define one or more rendering passes (i.e. you may need to render the 3D object multiple times, with various shaders applied, to achieve various effects).

The effect files are a complex topic, which requires some knowledge about 3D graphics programming and about the HLSL shader language. Please refer to Microsoft DirectX documentation for details on effect files and HLSL.

Note: Effect files are only available in the Direct3D 9 version of Wintermute Engine. All functions related to effects are ignored in the Direct3D 8 version.

 

Applying effects to 3D actors in WME

In WME, you can apply effects to individual sub-meshes of your 3D model. The sub-meshes are defined by material, i.e. if your actor model uses three different textures, three sub-meshes are created. Each sub-mesh is named after its original texture (as assigned in 3D modeling software). For example, if the head of your actor model uses texture called "textures\joe_head.png", the sub-mesh is internally called "joe_head". This is important to remember, because you use sub-mesh name while working with effects.

There are two ways of assigning effect to sub-meshes. Either you specify effect file(s) directly in actor definition file, or you can assign or remove effect using script commands.

To assign effect file to a sub-mesh in actor definition file, the file would contain something like this:

  EFFECT
  {
    MATERIAL = "chrome_buckle"
    EFFECT_FILE = "effects\shine.fx"
  }

This tells the engine, you want to apply the effect file "effects\shine.fx" to a sub-mesh called "chrome_buckle". You can of course add several such sections to your actor definition file, for each sub-mesh/material you want to assign effect to. Please note that effect assignment must be placed AFTER the "MODEL =" lines in the definition file, because the engine needs to be aware of the existing sub-meshes before applying effects.

Assigning effects from scripts is similar. There are two methods available, actor.SetEffect() and actor.RemoveEffect():

  actor.SetEffect("chrome_buckle", "effects\shine.fx");
  actor.RemoveEffect("chrome_buckle");

The first line applies the effect file called "effects\shine.fx" to a sub-mesh called "chrome_buckle". The second line removes any effect from the sub-mesh. The actor.SetEffect() method returns true or false, depending on whether the effect file has been successfully compiled and applied. If the compilation fails, you can find the list of errors in wme.log file in your project directory, or in the debugging console.

 

Setting effect parameters from a script

Sometimes it can be useful to set effect parameters dynamically. WME provides the following script methods for setting effect parameters.

actor.SetEffectParam() - This method allows you to set a parameter of types string, logical, integer number and floating point number. For example, to change the "BorderWidth" parameter of the sample effect "outer_glow.fx", you would call something like this from a script:

actor.SetEffectParam("chrome_buckle", "BorderWidth", ToFloat(20));

Just like in the above examples, "chrome_buckle" is the name of the submesh, whose effect you are working with. "BorderWidth" is the name of the parameter you are setting. The third parameter is the value to be assigned.

actor.SetEffectParamVector() - This method works similarly to SetEffectParam(), but it allows you to assign a 4D vector to a parameter. For example, to change the "BorderColor" parameter of the sample effect "outer_glow.fx", you would call something like this:

actor.SetEffectParamVector("chrome_buckle", "BorderColor", ToFloat(1), ToFloat(0), ToFloat(0), ToFloat(1));

Notice that you are sending 4 floating point numbers, the 4 components of the 4D vector (1, 0, 0, 1).

actor.SetEffectParamColor() - This method is a simplified version of SetEffectParamVector(), specifically designed for passing color values, created using the MakeRGBA() function. The usage is:

var ColorRed = MakeRGBA(255, 0, 0);
actor.SetEffectParamColor("chrome_buckle", "BorderColor", ColorRed);

Internally this method extracts the R, G, B and alpha components of the color, converts them to a 4D vector and passes them to the effect.

In addition to these script methods, WME can fill some parameters automatically, if they are marked with known semantics. It's described in the next chapter.

 

Supported semantics

As you can learn from the effect file documentation, global parameters can be augmented with so-called semantics, which define the meaning of the parameter. The engine then uses these semantics to automatically fill some shader parameters. For example, if you define a parameter like this:

float4x4 worldViewProjMatrix : WorldViewProjection;

you are defining a matrix variable called "worldViewProjMatrix" (you can use any name), with semantics "WorldViewProjection". The engine will detect that you are using known semantics, and it will automatically fill the variable with current world-view-projection matrix before rendering the mesh.

The following table contains all semantics currently supported by WME:

SemanticsType Description
Worldfloat4x4World matrix
Viewfloat4x4View matrix
Projectionfloat4x4Projection matrix
WorldTransposefloat4x4Transposed world matrix
ViewTransposefloat4x4Transposed view matrix
ProjectionTransposefloat4x4Transposed projection matrix
WorldViewfloat4x4World-view matrix
WorldViewProjectionfloat4x4World-view-projection matrix
WorldInversefloat4x4Inverse world matrix
ViewInversefloat4x4Inverse view matrix
ProjectionInversefloat4x4Inverse projection matrix
WorldInverseTransposefloat4x4Transposed inverse world matrix
ViewInverseTransposefloat4x4Transposed inverse view matrix
ProjectionInverseTransposefloat4x4Transposed inverse projection matrix
WorldViewInversefloat4x4Inverse world-view matrix
WorldViewTransposefloat4x4Transposed world-view matrix
WorldViewInverseTransposefloat4x4Transposed inverse world-view matrix
WorldViewProjectionInversefloat4x4Inverse world-view-projection matrix
WorldViewProjectionTransposefloat4x4Transposed world-view-projection matrix
WorldViewProjectionInverseTransposefloat4x4Transposed inverse world-view-projection matrix
ViewProjectionfloat4x4View-projection matrix
ViewProjectionTransposefloat4x4Transposed view-projection matrix
ViewProjectionInversefloat4x4Inverse view-projection matrix
ViewProjectionInverseTransposefloat4x4Transposed inverse view-projection matrix
ViewPositionfloat4Camera position
ViewDirectionfloat4Camera direction
DiffuseMaptextureCurrent mesh texture
Ambientfloat4Material ambient color
Diffusefloat4Material diffuse color
Specularfloat4Material specular color
Emissivefloat4Material emissive color
PowerfloatMaterial specular power
TimefloatCurrent time (in seconds)
ElapsedTimefloatTime elapsed since last frame (in seconds)
ActorLightPosfloat4Position of actor's shadow light
LightPosX (where X is 0..7)float4Light position
LightDirX (where X is 0..7)float4Light direction
LightDiffuseX (where X is 0..7)float4Light diffuse color
LightAmbientX (where X is 0..7)float4Light ambient color
LightSpecularX (where X is 0..7)float4Light specular color

 

Supported annotations

In addition to semantics, global parameters and effect passes can be augmented by annotations. Annotations specify additional processing of effect file elements. WME supports the following annotations:

Texture definition

Texture annotations can contain path to image file to be loaded into a texture, using the ResourceName annotation:

texture SomeTexture
<
    string ResourceName = "path\\filename.png";
>;

Please note that you can reference the texture currently assigned to the model using the DiffuseMap semantic, like this:

texture ModelTexture : DiffuseMap;
 

Render target definition

WME allows you to define render color targets and render depth targets using the following annotations:

texture RT_Tex : RenderColorTarget
<
    float2 Dimensions = { 1024, 1024 };
    string Format = "D3DFMT_A8R8G8B8";
    float  ClearDepth = 1.000000;
    int    ClearColor = 0x00000000;
    int    MipLevels = 1;
>;

texture RT_Depth : RenderDepthStencilTarget
<
    float2 Dimensions = { 1024, 1024 };
    string Format = "D3DFMT_D24S8";
    float  ClearDepth = 1.000000;
>;

Pass scripting

WME supports simple scripting of render passes. Pass scripts allow you to switch render targets and to render a screen-aligned quad. The annotation syntax is:

pass P0
<
    string Script = "RenderColorTarget0 = RT_Tex;"
                    "RenderDepthStencilTarget = RT_Depth;"
                    "Draw=Buffer;"
                    "Draw=Geometry;"
                    ;
>
{
    // pass code here
}

Supported script commands are:

If no Draw command is specified, the mesh is rendered.

WME only support pass scripts, not technique scripts.

 

Shader prototyping tools

There are tools allowing you designing and prototyping shaders. The most common tools are:

While these tools are useful for quick prototyping and previewing of shader effects, you shouldn't expect the effect files generated by these tools to be directly usable by game engines.

 

Shader preview tool

There is a simple shader preview tool included with WME Development Kit. It's a WME project and you will find it in the projects\wme_effects\ directory. To use the tool, place your .fx files into the "effects" subdirectory of the project directory. Run the project from ProjectMan. It displays a teapot model and lets you choose / reload / remove an effect file. You can also change background image (those are loaded from scenes\Room directory, you can add custom .png files there).