Sorry, thought maybe this was a common problem with a simple answer. Anyway here's the shader.
string Description = "This shader uses preview lights to produce per pixel normal mapped lighting. This shader requires lights.";
string Thumbnail = "Normal Mapping.png";
//--------------
//Untweakables
//--------------
float4x4 WorldViewProj : WorldViewProjection;
float4x4 World : World;
float4x4 WorldT : WorldTranspose;
float4x4 WorldIT : WorldInverseTranspose;
float4 LightPos[8] : LIGHTPOSITION;
float3 LightColor[8] : LIGHTCOLOR;
float3 AmbientColor : AMBIENTCOLOR;
float3 eyepos : CameraPosition;
float time : TIME;
//--------------
//Tweakables
//--------------
float SpecularPower1
<
string UIWidget = "slider";
float UIMax = 30;
float UIMin = 1;
> = 2.230000;
texture BaseTex
<
string ResourceName = "sand1.jpg";
>;
sampler diffuse_smp = sampler_state
{
Texture = <BaseTex>;
MinFilter = Anisotropic;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
texture NormalMap
<
string ResourceName = "Sand1NORM.jpg";
>;
sampler normalmap_smp = sampler_state
{
Texture = <NormalMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
struct app_in
{
float4 pos : POSITION;
float3 normal : NORMAL0;
float3 tangent : TANGENT0;
float3 binormal : BINORMAL0;
float2 uv : TEXCOORD0;
};
struct vs_out
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
float3 normal : TEXCOORD1;
float3 tangent : TEXCOORD2;
float3 binormal : TEXCOORD3;
float4 wpos : TEXCOORD4;
};
vs_out VS( app_in IN )
{
vs_out OUT;
float4 pos = mul( IN.pos, WorldViewProj );
OUT.pos = pos;
OUT.wpos = mul( IN.pos, World );
OUT.uv = IN.uv;
float3 normal = normalize(mul(IN.normal.xyz,(float3x3)World ));
float3 tangent = normalize(mul(IN.tangent.xyz,(float3x3)World ));
float3 binormal = normalize(mul(IN.binormal.xyz,(float3x3)World ));
//smooth out the tangents and binormals with the normals
float3 b = normalize(cross( normal,tangent ));
b *= sign(dot(b,binormal));
float3 t = normalize(cross( normal,b ));
t *= sign(dot(t,tangent));
float3 t2 = normalize(cross( normal,binormal ));
t2 *= sign(dot(t2,tangent));
float3 b2 = normalize(cross( normal,t2 ));
b2 *= sign(dot(b2,binormal));
//pass normal, tangent, and binormal to pixel shader
OUT.normal = normal;
OUT.tangent = normalize((t+t2)*0.5);
OUT.binormal = normalize((b+b2)*0.5);
return OUT;
}
float luminance ( float3 rgb )
{
return rgb.r*0.3 + rgb.g*0.59 + rgb.b*0.11;
}
float4 PS( vs_out IN, uniform int numLights ) : COLOR
{
float3 color = AmbientColor;
float3 n = normalize(IN.normal);
float3 t = normalize(IN.tangent);
float3 b = normalize(IN.binormal);
//build transpose matrix
float3x3 TangentSpace = {t,b,n};
TangentSpace = transpose(TangentSpace);
n = normalize(tex2D(normalmap_smp, IN.uv)*2 - 1);
float3 e = normalize(eyepos - IN.wpos);
float eyeDist = length(eyepos - IN.wpos);
e = mul(e,TangentSpace);
float4 texColor = tex2D( diffuse_smp, IN.uv );
//cycle through all lights, number depending on technique chosen
for ( int i = 0; i < numLights; i++ )
{
float range = LightPos[i].w;
if ( range > 0 )
{
float3 l = (LightPos[i].xyz - IN.wpos.xyz);
l = mul(l,TangentSpace);
//calculate attenuation
float dist = length(l);
float att = saturate((range-dist) / range);
//calculate diffuse lighting
l = normalize(l);
float diffuse = saturate(dot(n,l));
//caculate specular lighting
float3 h = normalize(l+e);
float spec = pow( saturate(dot(n,h)), SpecularPower1 )*(1-pow(1-diffuse,10));
//add to final color
color += (diffuse * att * LightColor[i]) + (spec * att * LightColor[i] * smoothstep(0.3,0.6,luminance(texColor.xyz)));
}
}
return float4(color,1.0) * texColor;
}
//choose the technique corresponding to the number of lights in your application
technique PerPixelLighting
{
pass p0
{
VertexShader = compile vs_2_0 VS( );
PixelShader = compile ps_2_0 PS( 0 );
}
}
technique DBLight1
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 1 );
}
}
technique DBLight2
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 2 );
}
}
technique DBLight3
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 3 );
}
}
technique DBLight4
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 4 );
}
}
technique DBLight5
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 5 );
}
}
technique DBLight6
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 6 );
}
}
technique DBLight7
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 7 );
}
}
technique DBLight8
{
pass p0
{
VertexShader = compile vs_1_1 VS( );
PixelShader = compile ps_2_a PS( 8 );
}
}
and here's my DBPro code so far
Rem Project: Paprii Knight
Rem Created: Sunday, October 17, 2010
Rem ***** Main Source File *****
//*****************
//System Setup
//*****************
sync on : sync rate 0
set window on : set display mode 1024,768,32,1
hide mouse : disable escapekey
//*****************
//GameStatus variable used to control game progress
//*****************
global GameStatus = 1
//*****************
//Loading Splash Screen
//*****************
load image "media/splash/Parchment1.jpg",001
load image "media/splash/AmbulanceGames.png",002
load image "media/misc/Fade1.png",003
load music "media/splash/MenuMusic.mp3",001
splashLife = 150
splashAlpha = 0
//*****************
//*****************
//*****************
//MAIN GAME LOOP
//*****************
//*****************
//*****************
//SPLASH SCREEN
while GameStatus = 1
//creating the image and background
sprite 001,0,0,001 : size sprite 001,screen width(),screen height()
sprite 002,140,280,002 : set sprite alpha 002,splashAlpha : set sprite priority 002,1
//start music
play music 001
set music volume 001,0
//splash countdown
if splashLife = 150 and splashAlpha < 255
splashAlpha = splashAlpha + 1
endif
//splash images lifespan
if splashAlpha = 255
splashLife = splashLife - 1
endif
//splash alpha countdown
if splashLife = 0
splashAlpha = splashAlpha - 1
endif
//splash kill button
if keystate(1) = 1
splashLife = 0
splashAlpha = 0
endif
//splash screen end
if splashAlpha = 0
delete sprite 002 : delete image 002
GameStatus = 2
endif
sync
endwhile
//*****************
//MAIN MENU
//*****************
//Loading Main Menu images
load image "media/splash/PapriiKnight.png",011
load image "media/splash/NewGame.png",012
load image "media/splash/LoadGame.png",013
load image "media/splash/Options.png",014
load image "media/splash/ExitGame.png",015
load image "media/splash/Cursor.png",016
load image "media/splash/Drawing.png",017
//Main menu variables
mainmenuSwitch = 0
papriiAlpha = 0
drawingAlpha = 0
newgameAlpha = 0 : loadgameAlpha = 0 : optionsAlpha = 0 : exitgameAlpha = 0
fadeoutControl = 0 : fadeOut = 0
sprite 003,0,0,003 : set sprite alpha 003,fadeOut : set sprite priority 003,10 : size sprite 003,screen width(),screen height()
while GameStatus = 2
//Position and setup sprites
sprite 011,160,10,011 : set sprite alpha 011,papriiAlpha : set sprite priority 011,1
sprite 012,50,335,012 : set sprite alpha 012,newgameAlpha : scale sprite 012,50 : set sprite priority 012,1
sprite 013,50,390,013 : set sprite alpha 013,loadgameAlpha : scale sprite 013,50 : set sprite priority 013,1
sprite 014,50,450,014 : set sprite alpha 014,optionsAlpha : scale sprite 014,50 : set sprite priority 014,1
sprite 015,50,515,015 : set sprite alpha 015,exitgameAlpha : scale sprite 015,50 : set sprite priority 015,1
sprite 016,mousex(),mousey(),016 : set sprite alpha 016,0 : scale sprite 016,50 : set sprite priority 016,2
sprite 017,475,505,017 : set sprite alpha 017,drawingAlpha : set sprite priority 017,1
//Paprii Knight logo
if papriiAlpha < 255
papriiAlpha = papriiAlpha + 1
endif
//Controls the main menu sprite alphas
if papriiAlpha = 255
mainmenuSwitch = 1
endif
//fade in the drawing
if mainmenuSwitch = 1
if drawingAlpha < 255
drawingAlpha = drawingAlpha + 1.5
endif
endif
//switch
if drawingAlpha = 255 then mainmenuSwitch = 2
//Fade in the player options
if mainmenuSwitch = 2
if newgameAlpha < 255
newgameAlpha = newgameAlpha + 1
loadgameAlpha = loadgameAlpha + 1
optionsAlpha = optionsAlpha + 1
exitgameAlpha = exitgameAlpha + 1
endif
endif
//show cursor
if newgameAlpha = 255 then set sprite alpha 016,255
//control game option animations
//when the cursor is over new game, load game, ect, they will fade in and out
newgameFlash = 0 : loadgameFlash = 0 : optionsFlash = 0 : exitFlash = 0
if sprite collision (016,012) then newgameFlash = 1 else newgameFlash = 0
if sprite collision (016,013) then loadgameFlash = 1 else loadgameFlash = 0
if sprite collision (016,014) then optionsFlash = 1 else optionsFlash = 0
if sprite collision (016,015) then exitFlash = 1 else exitFlash = 0
//newgame sprite fade control
newgameOn = 0
if newgameFlash = 1
if newgameAlpha = 255 then newgameOn = 0
if newgameAlpha = 155 then newgameOn = 1
endif
//main menu actions - controls what happens when the player
//makes a choice and clicks on an option
//new game
if sprite collision (016,012)
if mouseclick() = 1
GameStatus = 3
endif
endif
//load game
loadGame = 0
if sprite collision (016,013)
if mouseclick() = 1 then loadGame = 1
endif
if loadGame = 1
delete sprite 012
delete sprite 013
delete sprite 014
delete sprite 015
endif
//exit game
if sprite exist (015)
if sprite collision (016,015)
if mouseclick() = 1
if fadeoutControl = 0 then fadeoutControl = 1
endif
endif
endif
if fadeoutControl = 1
if fadeOut < 255
fadeOut = fadeOut + 2
endif
if fadeOut = 255
delete sprite 003
exit
endif
endif
sync
endwhile
//cleaning up
delete music 001
delete sprite 011 : delete sprite 012 : delete sprite 013 : delete sprite 014
delete sprite 015 : delete sprite 016 : delete sprite 017
delete image 011 : delete image 012 : delete image 013 : delete image 014
delete image 015 : delete image 016 : delete image 017
//*****************
//LOADING SCREEN FOR SECTION 1
//*****************
//loading the load animation
load image "media/splash/LoadingAnim.png",018
//setting up variable that keeps track of when the sections ready
loadingLife = 100
while GameStatus = 3
//spinning sword animation
sprite 018,512,367,018
offset sprite 018,109,112
animAngle = wrapvalue(animAngle)+1
rotate sprite 018,animAngle
if loadingLife > 0
loadingLife = loadingLife - 1
endif
if loadingLife = 0
GameStatus = 4
endif
sync
endwhile
//*****************
//SECTION 1: DESERT OPENING
//*****************
//loading desert terrain
load effect "media/section1/Sand1.fx",1000,0
load image "media/section1/sand1.jpg",1000
load image "media/section1/Sand1NORM.jpg",1001
load object "media/section1/ball.x",1000
set object effect 1000,1000
//lights!
lm start
lm add collision object 1000
lm build collision data
lm add point light 80,0,-45,5000,255,255,255
//positioning camera
//delete loading screen
delete sprite 018 : delete image 018
delete sprite 001 : delete image 001
while GameStatus = 4
control camera using arrowkeys 0,2,2
sync
endwhile
//*****************
//*****************
//*****************
//*****************
//FUNCTIONS
//*****************
Hope this helps. Thanks.