Shaders.rfa - The final frontier....
Posted: Sun May 30, 2010 5:11 pm
Shaders. The mysterious rfa that no mod (that I have seen) has touched. This file is found only in the vanilla files thus far and to most modders is completely alien. Unlike most the other files there is no "tool" that edits them or converts them. Thus why they have been left untouched for so long.
Recently (last night), I finally got a succesfull "compile" of a vso file. I found that the Singleplayer demo (the oldest version of the game I can get my hands on since I still can't find a beta version of the game which for me would be the modder's holy grail.
) has uncompiled versions of most of the shaders present in the retail game.
Curously it also has shaders not present in the retail game. SkidMark shaders, A cloudshader and a "shimmerSprite" shader to name a few. It also has a few pixal shaders (PSO is the compiled versions of these)
Before this I used one of the SDKs of Direct X to compile these, but I was on the wrong track as the resulting VSO files did not resemble that of the game's official files at all.
Here is what a typical VSO file looks like:
A mess basically and clearly not something designed to be "edited".
Here is what a typical uncompiled shader looks like (vs file extension. note the lack of the "o" at the end)
Now that is recognizable code and can be changed. For awhile I was using VSA.exe which is a compiler for vertex shaders that comes with most versions of the DirectX SDK. However they did not come out looking like the VSO files as shown above. Unsurpriingly the game rejects them.
So for awhile I had shader mods on the backburner. Then I dove into the demo which I found the uncompiled shaders. That wasn't the good part though. There was file at the root of the game folder called "nvasm.exe".
I ignored it for the longest time untill last night. I opened up command line and ran the program to see what it is. It appeared it was designed to use a input file and outputs something as vaguely explained by it's help text that it displayed since I didn't give it a input file.
So I dropped in a VS file and gave the program that. To my surprise it outputted a VSO file AND it had the same data structure as the official game VSO files. BINGO!
I found the app I need to compile them. So now I can finally get on the interesting part.
Now my theory here is that new shaders can't be made since the game is probably hardcoded to only load a certain list of shaders as the game is only programmed to use said shaders. However there is one shader that can be added because the retail game doesn't have it yet the debugger complains about not finding this shader. But this error only appears in the debugger log and the retail game doesn't say a peep about it.
The "SpritePointSprite.vso" file is what the debugger expects to find and yet it is mysteriously absent from from both the retail game and the demo (in compiled form). Now the demo did have an uncompiled vesrion of the shader but with a xvs extension. Here is what it looks like:
Only difference in the file from that of a VS is that it has "xvs.1.1" as the starting code and not "vs.1.1" like the other shaders.
I have compiled this shader and tried it in the retail and the debugger still pukes it up with the same error in the logs. I had the debugger stay quite on it by copying the sprite shader and renaming it to SpritePointSprite. but this didn't seem to work ingame to the effect I was expecting.
First off my theory here is that SpritePointSprite is used in the weather system. The weather codes don't work as we know, but I can bet that a missing shader might be why. The debugger does report loading the texture that is set up to be loaded by the weather code so the code works. But nothing is shown ingame.
There is a couple of key commands that leads me to believe that the SpritePointSprite shader is what the weather system needs:
"PointSprite" Key word there. It matches that of the SpritePointSprite file name. So I believe this is the shader needed for the weather code to work.
I have recompiled different shader as well the "newbf2_SkinningShader2Bones.vs" shader which is the only uncompiled shader found in in the retail game. I then took off the "newBF2_" from the file name so this replaces the compiled shader "SkinningShader2Bones.vso". I got a noticable effect ingame. The game didn't reject the shader and plus it had an effect to how animated meshes appeared ingame. The soldier mesh lost some detail and had "holes" in the hands and some other places. It looked kind of odd. This is not the same as a "broken" shader. When I broke the shader animated meshes would appear all blue or some other solid color and looked very bad. So it does seem a compiled shader does define how some elements in the game behave.
So if I can figure out why the SpritePointSprite shader code is getting rejected I could end up reviving the weather system!
I'll keep you updated if I find anything out. First I will look for a newer version of NVASM. Perhaps using one dated to the retail game might give better results. I will also play around with the code of the shader to see if I can get the game to accept it.
Recently (last night), I finally got a succesfull "compile" of a vso file. I found that the Singleplayer demo (the oldest version of the game I can get my hands on since I still can't find a beta version of the game which for me would be the modder's holy grail.

Curously it also has shaders not present in the retail game. SkidMark shaders, A cloudshader and a "shimmerSprite" shader to name a few. It also has a few pixal shaders (PSO is the compiled versions of these)
Before this I used one of the SDKs of Direct X to compile these, but I was on the wrong track as the resulting VSO files did not resemble that of the game's official files at all.
Here is what a typical VSO file looks like:
Code: Select all
þÿþÿ FILEC:\New_Battlefield\Shaders\FlareShader.vs þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE
þÿ LINE þÿ LINE þÿ LINE þÿ LINE
þÿ LINE
þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE þÿ LINE € Tþÿ LINE þÿ LINE € T€ Uþÿ LINE þÿ LINE € T€ þÿ LINE þÿ LINE € € U€þÿ LINE þÿ LINE € U€ þÿ LINE þÿ LINE þÿ LINE À T T€þÿ LINE þÿ LINE À ªþÿ LINE þÿ LINE þÿ LINE þÿ LINE à Tþÿ LINE þÿ LINE þÿ LINE! þÿ LINE" þÿ LINE# þÿ LINE# Ð äþÿ LINE$ ÿÿ
Here is what a typical uncompiled shader looks like (vs file extension. note the lack of the "o" at the end)
Code: Select all
; (c) Copyright 2000 - Digital Illusions CE AB, All Rights Reserved
;
;
; @file SkinningShader2Bones.vs
;
; @author Marco Hjerpe, Mats Dal
;
//-------------------- DEFINES --------------------------------------------------------
#define VERTEX_OFFSET0 v7
#define VERTEX_OFFSET1 v8
#define VERTEX_OFFSET2 v9
#define VERTEX_OFFSET3 v10
#define WEIGHTS v1
#define VERTEX_NORMAL v3
#define INDICES v5
#define TEX_COORDS v0
#define WORLD_VIEW_PROJ_MATRIX_1 c[0]
#define WORLD_VIEW_PROJ_MATRIX_2 c[1]
#define WORLD_VIEW_PROJ_MATRIX_3 c[2]
#define WORLD_VIEW_PROJ_MATRIX_4 c[3]
#define CONST c[4]
#define C_FOGDATA c[5]
#define LOCAL_SPACE_LIGHT_DIR c[6]
#define C_LIGHT_COLOR c[7]
#define C_SHADOW_COLOR c[8]
#define BONE_START_1 9
#define BONE_START_2 10
#define BONE_START_3 11
vs.1.1
mul r3, INDICES.zyxw,CONST.xxxx
mov a0.x, r3.x
// Transform offset 0 by bone0.
dp4 r1.x, VERTEX_OFFSET0, c[a0.x+BONE_START_1]
dp4 r1.y, VERTEX_OFFSET0, c[a0.x+BONE_START_2]
dp4 r1.z, VERTEX_OFFSET0, c[a0.x+BONE_START_3]
m3x3 r5.xyz, VERTEX_NORMAL, c[a0.x+BONE_START_1]
// Weigh vertex.
mul r2.xyz, r1.xyz, WEIGHTS.x
mul r4.xyz, r5.xyz, WEIGHTS.x
mov a0.x, r3.y
// Transform offset 1 by bone1.
dp4 r1.x, VERTEX_OFFSET0, c[a0.x+BONE_START_1]
dp4 r1.y, VERTEX_OFFSET0, c[a0.x+BONE_START_2]
dp4 r1.z, VERTEX_OFFSET0, c[a0.x+BONE_START_3]
m3x3 r5.xyz, VERTEX_NORMAL, c[a0.x+BONE_START_1]
// Weigh vertex.
mad r2.xyz, r1.xyz, WEIGHTS.y, r2.xyz
mad r4.xyz, r5.xyz, WEIGHTS.y, r4.xyz
mov r2.w, CONST.y
dp4 oPos.x, r2, WORLD_VIEW_PROJ_MATRIX_1
dp4 oPos.y, r2, WORLD_VIEW_PROJ_MATRIX_2
dp4 oPos.z, r2, WORLD_VIEW_PROJ_MATRIX_3
dp4 oPos.w, r2, WORLD_VIEW_PROJ_MATRIX_4
;dp4 oPos.x, VERTEX_OFFSET0, WORLD_VIEW_PROJ_MATRIX_1
;dp4 oPos.y, VERTEX_OFFSET0, WORLD_VIEW_PROJ_MATRIX_2
;dp4 oPos.z, VERTEX_OFFSET0, WORLD_VIEW_PROJ_MATRIX_3
;dp4 oPos.w, VERTEX_OFFSET0, WORLD_VIEW_PROJ_MATRIX_4
// Compute fog.
dp4 r1.x, r2, WORLD_VIEW_PROJ_MATRIX_4
mad oFog.x, C_FOGDATA.y, r1.x, C_FOGDATA.x // ((-1/Range)*d)+End/Range = (End-d)/Range
// Animate texture coordinates. Tracks on tanks etc.
mad oT0, TEX_COORDS, CONST.y, CONST.zwww // TEX_COORDS + [Offset,0,0,0]
// Lighting.
// normalize normals
mov r4.x, r4.x
mov r4.z, r4.z
dp3 r4.w, r4, r4;
rsq r4.w, r4.w
mul r4, r4, r4.w;
dp3 r1.x, r4.xyz, -LOCAL_SPACE_LIGHT_DIR.xyz
max r3.x, r1.x, CONST.w
// Compute color.
mov r2, C_SHADOW_COLOR
mad oD0, C_LIGHT_COLOR, r3.x, r2 // oD0.w implicitly set to C_SHADOW_COLOR.w = 1
So for awhile I had shader mods on the backburner. Then I dove into the demo which I found the uncompiled shaders. That wasn't the good part though. There was file at the root of the game folder called "nvasm.exe".
I ignored it for the longest time untill last night. I opened up command line and ran the program to see what it is. It appeared it was designed to use a input file and outputs something as vaguely explained by it's help text that it displayed since I didn't give it a input file.
So I dropped in a VS file and gave the program that. To my surprise it outputted a VSO file AND it had the same data structure as the official game VSO files. BINGO!
I found the app I need to compile them. So now I can finally get on the interesting part.
Now my theory here is that new shaders can't be made since the game is probably hardcoded to only load a certain list of shaders as the game is only programmed to use said shaders. However there is one shader that can be added because the retail game doesn't have it yet the debugger complains about not finding this shader. But this error only appears in the debugger log and the retail game doesn't say a peep about it.
The "SpritePointSprite.vso" file is what the debugger expects to find and yet it is mysteriously absent from from both the retail game and the demo (in compiled form). Now the demo did have an uncompiled vesrion of the shader but with a xvs extension. Here is what it looks like:
Code: Select all
; (c) Copyright 2000 - Digital Illusions CE AB, All Rights Reserved
;
;
; @file SpritePointSprite.vsh
;
; @author Marco Hjerpe
;
//-------------------- DEFINES --------------------------------------------------------
#define VERTEX_POSITION v0
#define DIFFUSE v4
#define SPRITE_WH v12
#define SPRITE_SIN_COS v13
#define TEX_COORDS v14
#define VIEW_MATRIX_1 c[0]
#define VIEW_MATRIX_2 c[1]
#define VIEW_MATRIX_3 c[2]
#define VIEW_MATRIX_4 c[3]
#define PROJ_MATRIX_1 c[4]
#define PROJ_MATRIX_2 c[5]
#define PROJ_MATRIX_3 c[6]
#define PROJ_MATRIX_4 c[7]
#define CONST c[8]
#define C_CAMPOS c[9]
xvs.1.1
dp4 oPos.x, VERTEX_POSITION, VIEW_MATRIX_1
dp4 oPos.y, VERTEX_POSITION, VIEW_MATRIX_2
dp4 oPos.z, VERTEX_POSITION, VIEW_MATRIX_3
dp4 oPos.w, VERTEX_POSITION, VIEW_MATRIX_4
//--- Get delta position (vertex position (world coord)) - (camera pos (world coord))
;add r6, VERTEX_POSITION, -C_CAMPOS
//--- Transform by world-view transform. (in this case only View matrix with out transformation) and transposed
//----------- OPTIMIZED STEP 1 ------------------------------------------------
;dp3 oPos.x, r6, VIEW_MATRIX_1 //X component of all angles don't need the position part (W) here because it is 0,0,0,1 therefor the dp3
;dp3 oPos.y, r6, VIEW_MATRIX_2 //Y component of all angles
;dp3 oPos.z, r6, VIEW_MATRIX_3 //Z component of all angles
;mov oPos.w, CONST.y //set 1 to w
// Output color
mov oD0, DIFFUSE
// Output width as point size.
mov oPts.x, SPRITE_WH.x
I have compiled this shader and tried it in the retail and the debugger still pukes it up with the same error in the logs. I had the debugger stay quite on it by copying the sprite shader and renaming it to SpritePointSprite. but this didn't seem to work ingame to the effect I was expecting.
First off my theory here is that SpritePointSprite is used in the weather system. The weather codes don't work as we know, but I can bet that a missing shader might be why. The debugger does report loading the texture that is set up to be loaded by the weather code so the code works. But nothing is shown ingame.
There is a couple of key commands that leads me to believe that the SpritePointSprite shader is what the weather system needs:
Code: Select all
wPart.pointSpriteMinSize
wPart.pointSpriteMaxSize
I have recompiled different shader as well the "newbf2_SkinningShader2Bones.vs" shader which is the only uncompiled shader found in in the retail game. I then took off the "newBF2_" from the file name so this replaces the compiled shader "SkinningShader2Bones.vso". I got a noticable effect ingame. The game didn't reject the shader and plus it had an effect to how animated meshes appeared ingame. The soldier mesh lost some detail and had "holes" in the hands and some other places. It looked kind of odd. This is not the same as a "broken" shader. When I broke the shader animated meshes would appear all blue or some other solid color and looked very bad. So it does seem a compiled shader does define how some elements in the game behave.
So if I can figure out why the SpritePointSprite shader code is getting rejected I could end up reviving the weather system!
I'll keep you updated if I find anything out. First I will look for a newer version of NVASM. Perhaps using one dated to the retail game might give better results. I will also play around with the code of the shader to see if I can get the game to accept it.