B Tutorial Shader Ghosts and Shaders

Users who are viewing this thread

Tutorial as Word file

Needed data:
Warsword Ghost Pack

Additional readings:

How to add custom shaders to the Warsword Conquest Module:
There are two files in the root mount and blade warband folder called mb_2a.fxo and mb_2b.fxo, these are the main compiled shader files. We must add our own mb_2a.fxo and mb_2b.fxo to the warsword conquest root folder in order to load our version of the shaders. Like this:
NE-lflYRXSR01BCNY_SBjtchcRT9JqDoMYH4AGW6FnlZHPoi5GiFiBSy2b8OU2OJ_LhrM4U-RI2Y5p27mRg5u5ckGGCTDDyz8bX--tOSTbcWlwJpBmsssqw0_tzepXvY1g
To do this you must first compile mb.fx. Extract the ghost pack to a suitable location. In the ghost pack in the shader folder you will find the precompiled shaders
wFl862ibV5E4iSr9RtQnvmOWKOX9qRe5mScI26w0Wo5l_MppDlIA17rYNTCDbTgFcMs3ICDBPE1q93L66ekqdaa7k6WfDC9wXsBnHTHpaX4UhIHMTO6vP_6TKBOlZQZgrw

Mb.fx is the precompiled main shader, it's in text so you can read and edit it. mb_2a.fxo and mb_2b.fxo are compiled as binary making them hard to edit.

Run compile_fx.bat. This will take a little while. If there are no errors it will create mb_2a.fxo and mb_2b.fxo in the shader folder.
u9IJl8sBDRDjnMe7loRGl_D5NxDl1uLMI_vLe6lfFwwqqD-CZbRT053eERB8qkRyCmwotL34raauPj4Dk4hEYJyIMbQjvdRLTRAFCh-sAYo7rdf2yVPqNmpI0MmlCnKM9Q
Copy only mb_2a.fxo and mb_2b.fxo to the warsword conquest root folder. That’s it for custom shaders: now how to use them in openbrf.

How to edit the ghosts to use the new shaders:
Copy the transparent textures from ghost pack to warsword conquest/textures.
(They are semi transparent textures saved as DXT5 (smooth alpha) dds)

(I included zombies.brf in the pack it has all the right settings for reference)

The rest of the setup is done in open brf:

Creating the shader in a brf (zombies.brf makes sense).
Settings for shader:
XWt-u6IbZ_aLa8hdgZWqtj-qEuRBzzWJz_nOaZCesrwQ1isQfEJWOr2n5e0dEpQnrjwyYzL3a821u69l59uVp_FPzM9yFFZvS5YaPUfF5rci8HVOPbgSdaIOMpEqNjyJZw
Requires 4000 makes the ghost shader work only for people running mount and blade on high settings.
Fallback tex_mul_color_alpha is a diffuse shader with alpha enabled.

Setting up the material correctly:
AVQPkGBd4zkXGv1vxFjQWJPa7A-Lh7Bqra7Os6lk3ythe-4sKWiQr_zzkZYOUUhYMH-XznPpopDPWD9YN-U09STQUzKwtccaq44Qssac8etN39KZP2aZxcW_mkkZbBOoag
jt6OsXQ6mrzmtpGG5Vs-gDk2_eNcY9XsHatg3OiMf8Ng5XCgvnHWIKqI6tnN-0oSrRJEuPg-oj2rc0T_CMKaAM94kyukatw3_SpiE-FjrmKAjqH3ye0BNOEG9qdUW1doTg
That's it! hopefully they work in-game!

Making changes to a hlsl shader:
The following is an quick guide on editing the ghost shader. It is additional information for anyone who’s interested.

Open mb.fx from the ghost pack with notepad or a text editor. This wall of text is the precompiled warband shaders.
cM4nY9rEXzcmPH-46FYxUJjVX8zoReEBAJdudqjNyQgbnChJBE6hGjx4LCoIcM2lIXmP1TaYwCJ8dWAZZ65gk3WgXE7QrmWkgGwlpdYTiWf6VYyWdXQnGgrPCa1R4EAwNQ
They are hlsl shaders written for shader model 2. Scroll to the very bottom of the document.
N4FNv7UffRglHU2RRzU5hKc7LfGPFt6xvf3f3kWFvou_JSGYxs4Xc1LGf-7n7JJEv0IUrg-qllHWiFCw86Dr5gc7poQRaNKXCxz3NRH021xvZl4JupxNQbhDatKMEB3P3g
The ghost shader begins at
Code:
///////////////////////////////////////////////////////////////////
//Burspa's Ghost Shader
////////////////
and ends at
Code:
/////////////////////
////Burspa Ghost Shader End
///////////////////////////////////////
The ghost shader is a modified diffuse shader with fresnel applied. A simplified explanation of fresnel is that it finds the edges of an object. A simplified explanation of the shader is that it finds the edges of the ghost mesh, the size of these edges is based on GlowExpon, and combines the color of these edges (based on the texture assigned), with GlowColor.

There are only 2 lines of code that should be changed to alter the ghost shader.
float3 GlowColor = {244.0f, 78.0f, 66.0f};
float GlowExpon = 1.3f;

Glow Color is an rgb float
You can find rgb color values here
So let's say we wanted to make the ghosts green. Change the code from
float3 GlowColor = {244.0f, 78.0f, 66.0f};
to
float3 GlowColor = {70.0f, 247.0f, 64.0f};

Rgb values must have .0f on the end because they are being stored as a float.

GlowExpon is the inverse size of the edges so:
GlowExpon = 0.3f would mean the edges would be huge and almost the entire ghost would be coloured in.
GlowExpon = 6.0f would create small edges and would create a nice rim lighting effect that fresnel is usually known for.

If you make any changes to mb.fx you will need to recompile as per instructions at the beginning.

Thats all there is to changing the ghost shader.

A tip for altering shaders for Mount & Blade:
Copy all the data from the ghost pack /shader folder to mount and warband root folder (make sure you make backups of the files you replace). Make sure the module you’re using does not contain custom shader files. Now make changes to mb.fx directly from the root warband folder. And when you compile now the compiled files will be in the correct location. Now open warband in edit mode. Find the unit you are changing in edit mode. With warband still open, make changes to the mb.fx file save and recompile. Now in warband edit mode, press ctrl + f, and the shaders will be updated in game. This allows you to quickly make alterations to shaders for testing ingame without having to restart warband.

mb.fx file
 
Since the shader doesn't include skinning deformations inside the VS, if it's used on a skeletal mesh it will apply the deformations via CPU which is pretty inefficient.
C-like:
struct VS_OUTPUT_GHOST_SHADER
{
    float4 Pos                    : POSITION;
    float4 Color                : COLOR0;
    float2 Tex0                    : TEXCOORD0;
    float  Fog                    : FOG;
    float3 ViewDir                : TEXCOORD6;
    float3 WorldNormal            : TEXCOORD7;   
};



VS_OUTPUT_GHOST_SHADER vs_ghost(uniform const bool use_skinning, float4 vPosition : POSITION, float4 vNormal : NORMAL, float2 tc : TEXCOORD0, float4 vColor : COLOR0, float4 vLightColor : COLOR1, float4 vBlendWeights : BLENDWEIGHT, float4 vBlendIndices : BLENDINDICES)
{

    INITIALIZE_OUTPUT(VS_OUTPUT_GHOST_SHADER, Out);

    float4 vObjectPos = vPosition;
    float4 vObjectN = vNormal;
    
    if(use_skinning)
    {
        vObjectPos = skinning_deform(vPosition, vBlendWeights, vBlendIndices);
        vObjectN = normalize(skinning_deform(vNormal, vBlendWeights, vBlendIndices));
    }

    Out.Pos = mul(matWorldViewProj, vObjectPos);

    float4 vWorldPos = (float4)mul(matWorld, vObjectPos);
    
    float3 vWorldN = normalize(mul((float3x3)matWorld, vObjectN)); //normal in world space
    float3 P = mul(matWorldView, vObjectPos); //position in view space

    Out.Tex0 = tc;

    float4 diffuse_light = vAmbientColor + vLightColor;
    diffuse_light += saturate(dot(vWorldN, -vSkyLightDir)) * vSkyLightColor;
    diffuse_light += saturate(dot(vWorldN, -vSunDir)) * vSunColor;
    Out.Color = (vMaterialColor * vColor * diffuse_light);

    //apply fog
    float d = length(P);
    Out.ViewDir =normalize(vCameraPos-vWorldPos);
    Out.WorldNormal = vWorldN;   

    Out.Fog = get_fog_amount_new(d, vWorldPos.z);
    return Out;
}

PS_OUTPUT ps_ghost(VS_OUTPUT_GHOST_SHADER In)
{
    PS_OUTPUT Output;

    float3 GlowColor = {66.0f,128.0f,130.0f};
    float GlowExpon = 1.3f;

    float4 tex_col = tex2D(MeshTextureSampler, In.Tex0);
    INPUT_TEX_GAMMA(tex_col.rgb);

    Output.RGBColor =  In.Color * tex_col;

    //add fresnel term
    float fresnel = 1.0-(dot( normalize(In.ViewDir), normalize(In.WorldNormal)));

    fresnel = pow(fresnel,GlowExpon);
    //fresnel = fresnel* GlowColor.rgb;
     float3 result = fresnel * GlowColor.rgb;
    Output.RGBColor.rgb *= result;

    OUTPUT_GAMMA(Output.RGBColor.rgb);
    return Output;
}

technique ghost_shader
{
    pass P0
    {
        VertexShader = compile vs_2_0 vs_ghost(false);
        PixelShader = compile ps_2_0 ps_ghost();
    }
}

technique ghost_shader_skin
{
    pass P0
    {
        VertexShader = compile vs_2_0 vs_ghost(true);
        PixelShader = compile ps_2_0 ps_ghost();
    }
}
 
Back
Top Bottom