Sunnetci_Dede said:
I am not really familiar with custom shaders, and how to create them. I would be grateful if someone would help me in this regard.
I need a shader with Specular Highlights (like "specular_shader_skin_bump_high") with which I can use green-normalmaps.
I sure there are tutorials around, but basically, you need to:
1) write your new shader program, in HLSL programming language
(High Level Shading Language, a part of Direct3D).
HLSL is compiled. You have a source (a file called mb.fx), which is compliled before running the game.
The compilation produces a complied version (a file called mb.fxo, where the warband exe is).
The game loads the complied version. Warband is shipped with it, but without the source.
So, to write your new shader, you need grab the source, modify it by adding your new shader, recompile it to get your modified version of mb.fxo, and overwrite the original mb.fxo.
(this leads to a problem: that the mb.fxo file needed by your mod needs to be not in the folder of that mod, but in the game folder. The application
Iron Launcher by [Swyter] can do the overwriting for you and for the users of your mod, so that this is made a lot more seamless for your users).
You won't find the source code of the shader in your Warband directory, but you can grab it from here, thanks to Armagan & team:
http://download2.taleworlds.com/mb_warband_shaders.zip
Naturally this is not the place about how to write shaders in HLSL. You'll find tons of tutorials around.
But the bit which is relevant here is that a the source file is a collection of alternative "techniques" -- just like a program in, say, C, Pascal or Java, is divided in several "functions" (aka procedures, "subroutines"...). Each technique is identified by its own name (nothing strange: also C functions have their own names).
In HLSL, a technique is usually the union of a Vertex program (what happens to each vertex you send to the card when that technique is active) and a Pixel program (aka fragment shader: what happens for each pixel that is drawn on the screen when that technique is active).
Now, if you want to add a new shader, you need to add a technique to the set of techniques originally present, for example by means of copying and existing one, renaming it, and modifying it.
2) After you changed the shader source code, you need to compile it. This requires to have a directX SDK, so be prepared to install it. Now you have the mb.fxo file.
3) Next step, you need to have a "shader" object in a brf file. This is similar to what happens with textures. As you know, a texture is dds file outside the brf. A BRF file contains a "texture" object, but that is merely a link to the external file (togheter with a few extra info like flags). Similarly, in the BRF file a "shader" object is merely a link to a technique which has to be found in mb.fxo (again, plus a few extra bits like flags -- in this case, the meaning of the flags are totally mysterious, at least to me.
If anbody knows about them,
please let me know!). When you added a new technique, you need add a new shader linking to it inside a BRF file, using OpenBRF.
The safest is to take an existing shader (with OpenBRF), duplicate it, rename it, and make it point to your new techinque instead of the technique it pointed at before. You have done it. You can now make your mesh use a material which uses your new shader. End of mini-tutorial.
BEWARE A BUG: at least in M&B 1.011, you can find a problem if your new shader object inside a BRF file. The game will sometimes not load it. The problem goes away if you go windowed mode then full screen mode again. To kill the bug, you need to list your new shader inside the file "core_shaders.brf". Again you have the problem that that file needs be in game CommonRes folder, not your mod folder. So agian, the above menitoned IronLauncher can be your friend.
TESTING YOUR NEW SHADER: in old M&B 0.808, there was a little useful trick to test a new shader without having to reload the game. A key shortcut would just reload the shaders (I think it was ctrl+R but I might remember wrong). Maybe it is me but I cannot find that useful functionality any more.
If anyone knows,
please let me know!
Edit: I should mention that you have also an alternative: writing your new shader in ARB shading language instead of HLSL.
ARB is a lower level language for shaders (just like, for example, Assembler is lower level than C or Java). Some might hate it, some will love it.
If you follow this route, you write your new shader in a separate file, e.g. "foo.pp". You don't need to compile it, because what you wrote is already the "assembler of graphic cards". In the BRF file, you need to make your new "shader" object to point at that file, by setting "foo.pp" as the "technique" used by that shader (e.g. in OpenBRF).