Josh, I guess you will stick to ASM anyways, but I've found this one somewhere on my harddisk. It should work too...

Code:
 /**************************************************************/

// HLSL NormalMapping Shader

// -------------------------

// By: Daniel "Rhuarc" Niezgocki

// Requires: []VS 1.1

// []PS 1.4

// Skin1: Texture

// Skin2: Normal Map

//

// Usage: Free to use, credit is nice, but not required.

/**************************************************************/





function normalMap_init

{

mat_inverse(mtl.matrix, matWorld);

}





material normalMap_fx {

flags=tangent;

event = normalMap_init;





effect="

// VertexShader ------------------


float4x4 matWorldViewProj;

float4x4 matWorld;

float4 vecSunPos;

float4 vecViewPos;

float4x4 matMtl;


texture entSkin1;

texture entSkin2;


sampler base_map = sampler_state

{

texture = (entSkin1);

};


sampler bump_map = sampler_state

{

texture = (entSkin2);

};


struct VS_INPUT_STRUCT

{

float4 position : POSITION;

float3 normal : NORMAL;

float3 texcoord0 : TEXCOORD0;

float3 tangent : TEXCOORD2;

};


struct VS_OUTPUT_STRUCT

{

float4 position : POSITION;

float2 bump_map : TEXCOORD0;

float3 light_angle : TEXCOORD1;

};


VS_OUTPUT_STRUCT mainVS( VS_INPUT_STRUCT vsInStruct )

{

VS_OUTPUT_STRUCT vsOutStruct;

vsOutStruct.position = mul( vsInStruct.position, matWorldViewProj );


float3 position = mul( matWorld, vsInStruct.position );


vsOutStruct.bump_map = vsInStruct.texcoord0;


float3 light_normal_vector = mul( vsInStruct.normal, matWorld );


vsOutStruct.light_angle = light_normal_vector;


return vsOutStruct;

};


// PixelShader -------------------


float bumpiness = 0.5;

float specular = 0.5;

float4 vecAmbient;

float4 vecDiffuse;

float4 vecSpecular;

float vecViewDir;

struct PS_INPUT_STRUCT

{

float2 bump_map : TEXCOORD0;

float3 light_angle : TEXCOORD1;

};


struct PS_OUTPUT_STRUCT

{

float4 color0 : COLOR0;

};


PS_OUTPUT_STRUCT mainPS( PS_INPUT_STRUCT psInStruct )

{

PS_OUTPUT_STRUCT psOutStruct;


float3 base = tex2D( base_map, psInStruct.bump_map );

float3 bump = tex2D( bump_map, psInStruct.bump_map );


// Uncompress vectors ([0, 1] -> [-1, 1])

float3 lightVectorFinal = (psInStruct.light_angle - 0.5);

float3 bumpNormalVectorFinal = bumpiness * (bump - 0.5);


// Compute diffuse factor

float diffuse = dot(bumpNormalVectorFinal, lightVectorFinal);


psOutStruct.color0.rgb = ( diffuse * base + + max(diffuse-specular,0));

psOutStruct.color0.a = 1.0f;

return psOutStruct;

};


technique normalMap

{

pass P0

{

VertexShader = compile vs_1_1 mainVS();

PixelShader = compile ps_1_4 mainPS();

}

}

";

}



action normalMap_ent

{

my.material = normalMap_fx;

}




PHeMoX, Innervision Software (c) 1995-2008

For more info visit: Innervision Software