DX9 effects files in Fusion consist of 2 files:
.xml => effect definition
.fx => DX9 effect file
In Fusion 2.5+ you can also use DirectX11 shaders, this adds 2 or 3 files:
.hlsl -> dx11 HLSL file
.fxc -> DX11 compiled shader (compiled with the fxc.exe from the Microsft SDK)
.premultiplied.fxc -> optional, DX11 compiled shader that will be used in "premultiplied" mode
How to create a .hlsl file from a .fx file
Both files are very similar. What to change:
1. Pixel shader output / input
Replace COLOR0 by SV_TARGET either in the PS_OUTPUT structure if you use one, or in the main shader function otherwise, like this:
float4 Color : SV_TARGET;
float4 ps_main(in float2 In : TEXCOORD0) : SV_TARGET
- Input: you should use the following input structure:
So in the end your main shader function should look like:
float4 Tint : COLOR0;
float2 texCoord : TEXCOORD0;
PS_OUTPUT ps_main( in PS_INPUT In )
float4 ps_main( in PS_INPUT In ) : SV_TARGET
Replace the main texture:
Do this for additional textures too, use the same register index as the one in the .fx (or 0 for the object's texture). For example if you use a background texture:
Texture2D<float4> Tex0 : register(t0);
sampler Tex0Sampler : register(s0);
Texture2D<float4> bg : register(t1);
sampler bgSampler : register(s1);
In the HLSL code, replace tex2D(Tex0, xy) by Tex0.Sample(Tex0Sampler, xy);
Move all the parameters parameters in a cbuffer structure (the parameters that are defined in the shader XML file):
cbuffer PS_VARIABLES : register(b0)
// IMPORTANT: the parameters must be in the same order as in your XML file
4. If the shader uses fPixelWidth and fPixelHeight, add this:
5. Multiply the texture color by In.Tint (= RGBA coefficient in the object properties) when you read from the texture:
cbuffer PS_PIXELSIZE : register(b1)
(adjust to your code)
float4 color = Tex0.Sample(Tex0Sampler, xy) * In.Tint;
6. Finally delete the technique section, you don't need it.
How to build the .hlsl file to .fxc file
Use the tool fxc.exe included in recent versions of the Microsoft SDK (for example a SDK that is installed with VS2017) to compile your shader to a .fxc file, this is the file used by Fusion.
You can use this batch file that was taken and modified a bit from MS DirectXTK to build your shader. Make sure the local pathname of fxc.exe is correct in the batch file (in the case it can't be automatically determined) and replace ShaderTest by the name of your shader. The line that compiles your shader is:
This line compiles your shader with ps_main as entry point.
call :CompileShaderHLSL "ShaderTest" ps ps_main
Replace CompileShaderHLSL CompileShaderHLSL4 if needed (like register limits etc). And replace ps_main if you use another name.
The second CompileShaderHLSL line compiles the ps_main_pm function to a .premultiplied.fxc file. See below. Comment it out if you have no premultiplied version.
Unlike .fx file, you cannot define sampler states in the DirectX 11 .hlsl files used by Fusion. If you need specific sampler states in DirectX 11 mode, you can define the in the XML file of your effect (requires build 292.6 or above). Just add sampler sections like this:
<index>register index of the sampler</index>
<filter>Filtering method, can be point or linear (don't specify a filter member if you want to keep Fusion's mode)</filter>
<addressU>U address mode, can be clamp, wrap, mirror, border (default = clamp)</addressU>
<addressV>V address mode, can be clamp, wrap, mirror, border (default = clamp)</addressV>
<bordercolor>border color (RGBA integer value, high order byte = alpha, low order byte = red)</bordercolor>
2.5+ has a new premultiplied option. When this option is selected, the RGB values of the images (and various surfaces) are multiplied with their alpha value. Some shaders work the same with or without this option, others don't. If your shader needs a premultiplied version, compile this version as .premultiplied.fxc file. When Fusion builds an application that has the Premultiplied option, it first tries to find a .premultiplied.fxc file instead of a .fxc file. If it can't find it, it takes the .fxc file.
As you can see in the already converted effects, some of them have both a ps_main and a ps_main_pm functions. The second one is the premultiplied version, this is the one that is built to a .premultiplied.fxc file by the batch file above.
The simplest way to convert a shader to premultiplied is to (1) demultiply the source color (divide the rgb by the alpha), (2) apply the normal shader, (3) multiply the output rgb by its alpha. It's what most converted shaders do for the moment.
Hopefully this quick guide is not too obscure and has no mistake (I'm sure it has)...