Posted: 15th Jun 2007 1:41
Please forgive me if the following is naive:

Before i started using Normal Mapping on my character, the object (.x) was lit by 4 of DBPros built in Hardware lights, and I really liked the result on the textured object.

Then I started playing with Ninja Matts shader, which uses vector lights, which are limited to 2, but gives my character so much more depth.

Has anybody worked out an effective way of having either:

a) The object effected by the vector lights in the shader for the bump effect, AND also by DBPro hardware lights ( i'm guessing this isnt possible )

OR

b) Some kind of workaround, using just the 2 vector lights.

Thanks

Danny
Posted: 15th Jun 2007 7:51
Hm, I'm not sure I really understood what you actually want to achieve.
The answer to a) would be no. Objects that have the normal map shader applied only respond to the lights which are set in the shader.

Now I guess the 2 lights are not sufficient for you, and that's what you are looking for a workaround for ? If that's the case, there is actually a version of Ninja Matts shader that has 8 lights.


+ Code Snippet
//  Normalmap Specular Shader - 2.1
//      by Ninja Matt
//------------------------------------
float4x4 WorldViewProj : WorldViewProjection;
float4x4 World : WorldInverseTranspose;
float3 EyePos : CameraPosition;

//------------------------------------
float4 Light1Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light1Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

float4 Light2Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light2Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

float4 Light3Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light3Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

float4 Light4Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light4Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

float4 Light5Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light5Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

float4 Light6Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light6Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

float4 Light7Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light7Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

float4 Light8Col <> = {1.0f, 1.0f, 1.0f, 1.0f};
float4 Light8Pos <> = {1.0f, -1.0f, 1.0f, 0.0f};

texture BaseMap
<
	string ResourceName = "CrateBase.tga";
>;

texture NormMap
<
	string ResourceName = "CrateNormal.tga";
>;

texture SpecMap
<
	string ResourceName = "CrateSpecular.tga";
>;

//------------------------------------
technique Lights2
{
	pass OneTwo
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light1Pos>;
		VertexShaderConstant[12] = <Light1Col>;
		VertexShaderConstant[13] = <Light2Pos>;
		VertexShaderConstant[14] = <Light2Col>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Scale and Bias Value
			def c20, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			mov oT1, v2
			
			// Output Light Colours
			mov oD0, c12
			mov oD1, c14
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 1
			add r0, r0.xyz, -v0
			
			// Normalise Light Vector 1
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 1 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c12.w
			rcp oD0.w, r2
			
			// Move Light Vector 1 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1

			// Scale and Bias Vector 1
			add r1, r1, c20.x
			mul oT2, r1, c20.y

			// Move Light 2 to Object Space
			mov r1, c13
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 2
			add r0, r0, -v0
			
			// Normalise Light Vector 2
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 2 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c14.w
			rcp oD1.w, r2
			
			// Move Light Vector 2 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1
			
			// Scale and Bias Vector 2
			add r1, r1, c20.x
			mul oT3, r1, c20.y
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			tex t1
			
			// Get Per-Pixel Light Vectors
			texcoord t2
			texcoord t3
			
			// DP3 Light Vector 1 and Colour It
			dp3_sat r0, t1_bx2, t2_bx2
			mul r0, r0, v0
			mul r0, r0, v0.a
			
			// DP3 Light Vector 2 and Colour It
			dp3_sat r1, t1_bx2, t3_bx2
			mul r1, r1, v1
			mul r1, r1, v1.a
			
			// Add Lights Together
			add r0, r0, r1
			
			// Multiply Diffuse with Lighting
			mul r0, r0, t0
		};

		Texture[0] = <BaseMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[1] = <NormMap>;
		MinFilter[1] = Linear;
		MagFilter[1] = Linear;
		MipFilter[1] = Linear;
		AddressU[1]  = Wrap;
		AddressV[1]  = Wrap;
		AddressW[1]  = Wrap;
	}

	pass SpecOne
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light1Pos>;
		VertexShaderConstant[12] = <Light1Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			def c22, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecTwo
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light2Pos>;
		VertexShaderConstant[12] = <Light2Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}
};

//------------------------------------
technique Lights4
{
	pass OneTwo
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light1Pos>;
		VertexShaderConstant[12] = <Light1Col>;
		VertexShaderConstant[13] = <Light2Pos>;
		VertexShaderConstant[14] = <Light2Col>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Scale and Bias Value
			def c20, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			mov oT1, v2
			
			// Output Light Colours
			mov oD0, c12
			mov oD1, c14
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 1
			add r0, r0.xyz, -v0
			
			// Normalise Light Vector 1
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 1 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c12.w
			rcp oD0.w, r2
			
			// Move Light Vector 1 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1

			// Scale and Bias Vector 1
			add r1, r1, c20.x
			mul oT2, r1, c20.y

			// Move Light 2 to Object Space
			mov r1, c13
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 2
			add r0, r0, -v0
			
			// Normalise Light Vector 2
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 2 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c14.w
			rcp oD1.w, r2
			
			// Move Light Vector 2 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1
			
			// Scale and Bias Vector 2
			add r1, r1, c20.x
			mul oT3, r1, c20.y
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			tex t1
			
			// Get Per-Pixel Light Vectors
			texcoord t2
			texcoord t3
			
			// DP3 Light Vector 1 and Colour It
			dp3_sat r0, t1_bx2, t2_bx2
			mul r0, r0, v0
			mul r0, r0, v0.a
			
			// DP3 Light Vector 2 and Colour It
			dp3_sat r1, t1_bx2, t3_bx2
			mul r1, r1, v1
			mul r1, r1, v1.a
			
			// Add Lights Together
			add r0, r0, r1
			
			// Multiply Diffuse with Lighting
			mul r0, r0, t0
		};

		Texture[0] = <BaseMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[1] = <NormMap>;
		MinFilter[1] = Linear;
		MagFilter[1] = Linear;
		MipFilter[1] = Linear;
		AddressU[1]  = Wrap;
		AddressV[1]  = Wrap;
		AddressW[1]  = Wrap;
	}

	pass ThreeFour
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light3Pos>;
		VertexShaderConstant[12] = <Light3Col>;
		VertexShaderConstant[13] = <Light4Pos>;
		VertexShaderConstant[14] = <Light4Col>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Scale and Bias Value
			def c20, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			mov oT1, v2
			
			// Output Light Colours
			mov oD0, c12
			mov oD1, c14
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 1
			add r0, r0.xyz, -v0
			
			// Normalise Light Vector 1
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 1 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c12.w
			rcp oD0.w, r2
			
			// Move Light Vector 1 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1

			// Scale and Bias Vector 1
			add r1, r1, c20.x
			mul oT2, r1, c20.y

			// Move Light 2 to Object Space
			mov r1, c13
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 2
			add r0, r0, -v0
			
			// Normalise Light Vector 2
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 2 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c14.w
			rcp oD1.w, r2
			
			// Move Light Vector 2 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1
			
			// Scale and Bias Vector 2
			add r1, r1, c20.x
			mul oT3, r1, c20.y
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			tex t1
			
			// Get Per-Pixel Light Vectors
			texcoord t2
			texcoord t3
			
			// DP3 Light Vector 1 and Colour It
			dp3_sat r0, t1_bx2, t2_bx2
			mul r0, r0, v0
			mul r0, r0, v0.a
			
			// DP3 Light Vector 2 and Colour It
			dp3_sat r1, t1_bx2, t3_bx2
			mul r1, r1, v1
			mul r1, r1, v1.a
			
			// Add Lights Together
			add r0, r0, r1
			
			// Multiply Diffuse with Lighting
			mul r0, r0, t0
		};

		Texture[0] = <BaseMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[1] = <NormMap>;
		MinFilter[1] = Linear;
		MagFilter[1] = Linear;
		MipFilter[1] = Linear;
		AddressU[1]  = Wrap;
		AddressV[1]  = Wrap;
		AddressW[1]  = Wrap;

		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecOne
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light1Pos>;
		VertexShaderConstant[12] = <Light1Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			def c22, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecTwo
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light2Pos>;
		VertexShaderConstant[12] = <Light2Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecThree
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light3Pos>;
		VertexShaderConstant[12] = <Light3Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecFour
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light4Pos>;
		VertexShaderConstant[12] = <Light4Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;
		
		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}
};

//------------------------------------
technique Lights8
{
	pass OneTwo
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light1Pos>;
		VertexShaderConstant[12] = <Light1Col>;
		VertexShaderConstant[13] = <Light2Pos>;
		VertexShaderConstant[14] = <Light2Col>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Scale and Bias Value
			def c20, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			mov oT1, v2
			
			// Output Light Colours
			mov oD0, c12
			mov oD1, c14
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 1
			add r0, r0.xyz, -v0
			
			// Normalise Light Vector 1
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 1 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c12.w
			rcp oD0.w, r2
			
			// Move Light Vector 1 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1

			// Scale and Bias Vector 1
			add r1, r1, c20.x
			mul oT2, r1, c20.y

			// Move Light 2 to Object Space
			mov r1, c13
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 2
			add r0, r0, -v0
			
			// Normalise Light Vector 2
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 2 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c14.w
			rcp oD1.w, r2
			
			// Move Light Vector 2 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1
			
			// Scale and Bias Vector 2
			add r1, r1, c20.x
			mul oT3, r1, c20.y
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			tex t1
			
			// Get Per-Pixel Light Vectors
			texcoord t2
			texcoord t3
			
			// DP3 Light Vector 1 and Colour It
			dp3_sat r0, t1_bx2, t2_bx2
			mul r0, r0, v0
			mul r0, r0, v0.a
			
			// DP3 Light Vector 2 and Colour It
			dp3_sat r1, t1_bx2, t3_bx2
			mul r1, r1, v1
			mul r1, r1, v1.a
			
			// Add Lights Together
			add r0, r0, r1
			
			// Multiply Diffuse with Lighting
			mul r0, r0, t0
		};

		Texture[0] = <BaseMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[1] = <NormMap>;
		MinFilter[1] = Linear;
		MagFilter[1] = Linear;
		MipFilter[1] = Linear;
		AddressU[1]  = Wrap;
		AddressV[1]  = Wrap;
		AddressW[1]  = Wrap;
	}

	pass ThreeFour
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light3Pos>;
		VertexShaderConstant[12] = <Light3Col>;
		VertexShaderConstant[13] = <Light4Pos>;
		VertexShaderConstant[14] = <Light4Col>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Scale and Bias Value
			def c20, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			mov oT1, v2
			
			// Output Light Colours
			mov oD0, c12
			mov oD1, c14
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 1
			add r0, r0.xyz, -v0
			
			// Normalise Light Vector 1
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 1 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c12.w
			rcp oD0.w, r2
			
			// Move Light Vector 1 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1

			// Scale and Bias Vector 1
			add r1, r1, c20.x
			mul oT2, r1, c20.y

			// Move Light 2 to Object Space
			mov r1, c13
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 2
			add r0, r0, -v0
			
			// Normalise Light Vector 2
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 2 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c14.w
			rcp oD1.w, r2
			
			// Move Light Vector 2 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1
			
			// Scale and Bias Vector 2
			add r1, r1, c20.x
			mul oT3, r1, c20.y
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			tex t1
			
			// Get Per-Pixel Light Vectors
			texcoord t2
			texcoord t3
			
			// DP3 Light Vector 1 and Colour It
			dp3_sat r0, t1_bx2, t2_bx2
			mul r0, r0, v0
			mul r0, r0, v0.a
			
			// DP3 Light Vector 2 and Colour It
			dp3_sat r1, t1_bx2, t3_bx2
			mul r1, r1, v1
			mul r1, r1, v1.a
			
			// Add Lights Together
			add r0, r0, r1
			
			// Multiply Diffuse with Lighting
			mul r0, r0, t0
		};

		Texture[0] = <BaseMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[1] = <NormMap>;
		MinFilter[1] = Linear;
		MagFilter[1] = Linear;
		MipFilter[1] = Linear;
		AddressU[1]  = Wrap;
		AddressV[1]  = Wrap;
		AddressW[1]  = Wrap;

		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass FiveSix
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light5Pos>;
		VertexShaderConstant[12] = <Light5Col>;
		VertexShaderConstant[13] = <Light6Pos>;
		VertexShaderConstant[14] = <Light6Col>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Scale and Bias Value
			def c20, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			mov oT1, v2
			
			// Output Light Colours
			mov oD0, c12
			mov oD1, c14
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 1
			add r0, r0.xyz, -v0
			
			// Normalise Light Vector 1
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 1 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c12.w
			rcp oD0.w, r2
			
			// Move Light Vector 1 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1

			// Scale and Bias Vector 1
			add r1, r1, c20.x
			mul oT2, r1, c20.y

			// Move Light 2 to Object Space
			mov r1, c13
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 2
			add r0, r0, -v0
			
			// Normalise Light Vector 2
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 2 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c14.w
			rcp oD1.w, r2
			
			// Move Light Vector 2 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1
			
			// Scale and Bias Vector 2
			add r1, r1, c20.x
			mul oT3, r1, c20.y
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			tex t1
			
			// Get Per-Pixel Light Vectors
			texcoord t2
			texcoord t3
			
			// DP3 Light Vector 1 and Colour It
			dp3_sat r0, t1_bx2, t2_bx2
			mul r0, r0, v0
			mul r0, r0, v0.a
			
			// DP3 Light Vector 2 and Colour It
			dp3_sat r1, t1_bx2, t3_bx2
			mul r1, r1, v1
			mul r1, r1, v1.a
			
			// Add Lights Together
			add r0, r0, r1
			
			// Multiply Diffuse with Lighting
			mul r0, r0, t0
		};

		Texture[0] = <BaseMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[1] = <NormMap>;
		MinFilter[1] = Linear;
		MagFilter[1] = Linear;
		MipFilter[1] = Linear;
		AddressU[1]  = Wrap;
		AddressV[1]  = Wrap;
		AddressW[1]  = Wrap;

		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SevenEight
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light7Pos>;
		VertexShaderConstant[12] = <Light7Col>;
		VertexShaderConstant[13] = <Light8Pos>;
		VertexShaderConstant[14] = <Light8Col>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Scale and Bias Value
			def c20, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			mov oT1, v2
			
			// Output Light Colours
			mov oD0, c12
			mov oD1, c14
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 1
			add r0, r0.xyz, -v0
			
			// Normalise Light Vector 1
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 1 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c12.w
			rcp oD0.w, r2
			
			// Move Light Vector 1 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1

			// Scale and Bias Vector 1
			add r1, r1, c20.x
			mul oT2, r1, c20.y

			// Move Light 2 to Object Space
			mov r1, c13
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Find Light Vector 2
			add r0, r0, -v0
			
			// Normalise Light Vector 2
			dp3 r1, r0, r0
			rsq r1, r1
			mul r0, r0, r1
			
			// Compute Light 2 Quadratic Falloff
			rcp r1, r1
			mul r2, r1, r1
			mul r2, r2, c14.w
			rcp oD1.w, r2
			
			// Move Light Vector 2 to Texture Space
			dp3 r1.x, r0, v3
			dp3 r1.y, r0, v4
			dp3 r1.z, r0, v1
			
			// Scale and Bias Vector 2
			add r1, r1, c20.x
			mul oT3, r1, c20.y
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			tex t1
			
			// Get Per-Pixel Light Vectors
			texcoord t2
			texcoord t3
			
			// DP3 Light Vector 1 and Colour It
			dp3_sat r0, t1_bx2, t2_bx2
			mul r0, r0, v0
			mul r0, r0, v0.a
			
			// DP3 Light Vector 2 and Colour It
			dp3_sat r1, t1_bx2, t3_bx2
			mul r1, r1, v1
			mul r1, r1, v1.a
			
			// Add Lights Together
			add r0, r0, r1
			
			// Multiply Diffuse with Lighting
			mul r0, r0, t0
		};

		Texture[0] = <BaseMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[1] = <NormMap>;
		MinFilter[1] = Linear;
		MagFilter[1] = Linear;
		MipFilter[1] = Linear;
		AddressU[1]  = Wrap;
		AddressV[1]  = Wrap;
		AddressW[1]  = Wrap;

		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecOne
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light1Pos>;
		VertexShaderConstant[12] = <Light1Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			def c22, 1.0f, 0.5f, 0.0f, 0.0f
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecTwo
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light2Pos>;
		VertexShaderConstant[12] = <Light2Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecThree
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light3Pos>;
		VertexShaderConstant[12] = <Light3Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;

		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecFour
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light4Pos>;
		VertexShaderConstant[12] = <Light4Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;
		
		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecFive
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light5Pos>;
		VertexShaderConstant[12] = <Light5Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;
		
		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecSix
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light6Pos>;
		VertexShaderConstant[12] = <Light6Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;
		
		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecSeven
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light7Pos>;
		VertexShaderConstant[12] = <Light7Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;
		
		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}

	pass SpecEight
	{		
		VertexShaderConstant[0] = <WorldViewProj>;
		VertexShaderConstant[4] = <World>;
		VertexShaderConstant[11] = <Light8Pos>;
		VertexShaderConstant[12] = <Light8Col>;
		VertexShaderConstant[20] = <EyePos>;

		VertexShader = asm
		{
			// Initilise Shader
			vs.1.1
			dcl_position	v0
			dcl_normal	v1
			dcl_texcoord	v2
			dcl_tangent	v3
			dcl_binormal	v4
			
			// Transform Position to Clip
			m4x4 oPos, v0, c0
			
			// Output Texture Coordinates
			mov oT0, v2
			
			// Move Eye Position to Object Space
			mov r1, c20
			dp3 r4.x, r1, c4
			dp3 r4.y, r1, c5
			dp3 r4.z, r1, c6
			
			// Compute Normalised Eye Vector
			add r4, r4.xyz, -v0
			dp3 r4.w, r4, r4
			rsq r4.w, r4.w
			mul r4, r4, r4.w
			
			// Move Light 1 to Object Space
			mov r1, c11
			dp3 r0.x, r1, c4
			dp3 r0.y, r1, c5
			dp3 r0.z, r1, c6
			
			// Compute Normalised Light Vector
			add r0, r0.xyz, -v0
			dp3 r0.w, r0, r0
			rsq r0.w, r0.w
			mul r0, r0, r0.w
			
			// Compute Normalised Half-Vector
			add r1, r0, r4
			dp3 r1.w, r1, r1
			rsq r1.w, r1.w
			mul r1, r1, r1.w
			
			// Move Half-Vector to Texture Space
			dp3 r0.x, r1, v3
			dp3 r0.y, r1, v4
			dp3 r0.z, r1, v1
			
			// Output Half-Vector and Colour
			mov oT1, r0
			mov oD0, c12
		};
		
		PixelShader = asm
		{
			// Initialise Shader
			ps.1.1
			
			// Read Texture Data
			tex t0
			
			// Perform DP3 Normal Map
			texm3x2pad t1, t0_bx2
			texm3x2tex t2, t0_bx2
			
			// Multiply by Specularity Map and Colour
			mul r0, t2, t0.a
			mul r0, r0, v0
		};

		Texture[0] = <NormMap>;
		MinFilter[0] = Linear;
		MagFilter[0] = Linear;
		MipFilter[0] = Linear;
		AddressU[0]  = Wrap;
		AddressV[0]  = Wrap;
		AddressW[0]  = Wrap;
		
		Texture[2] = <SpecMap>;
		MinFilter[2] = Linear;
		MagFilter[2] = Linear;
		MipFilter[2] = Linear;
		AddressU[2]  = Clamp;
		AddressV[2]  = Clamp;
		AddressW[2]  = Clamp;
		
		AlphaBlendEnable = True;
		SrcBlend = One;
		DestBlend = One;
	}
};


Hope this helped.
Posted: 15th Jun 2007 11:27
Thanks Irradic. Thats exactly what i'm after. I dont suppose there's a downloadable demo version with the spinning cube is there..?

Thanks

Danny
Posted: 15th Jun 2007 14:09
I've been looking through my files, but I could only find demos for his version 2.0 and 2.2 which both have 2 lights.
Probably you should check the old "Ultimate shader thread".
Another option would be to just add the other lights into one of his demos.
Posted: 15th Jun 2007 16:38
Thanks for your help Irradic,

I replaced the .fx file in the demo with the new '8 light' one and got it working fine with the 2 lights.

However, I've tried to add a new light ( a green one ) and cant seem to get it to show

Can anyone include a code snippet showing how to add extra lights.

Thanks

Danny
Posted: 15th Jun 2007 23:55
First add 1 or more vector4
+ Code Snippet
 null=make vector4(number)
, so you can pass on the values which the shader uses for its tweakables. Then when you load and apply the shader make sure you are using the correct technique, in this case it should be "Lights4". Afterwards just set the values and pass them on to the shader. Here is an example:
+ Code Snippet
set vector4 1, 100, 0, 50, 0        
set vector4 2, 1.0, 1.0, 1.0, 0.0        

set vector4 3, 50, 0, 50, 0        
set vector4 4, 0.5, 0.5, 0.7, 0.0 

set vector4 5, 200, 0, 50, 0        
set vector4 6, 1.0, 1.0, 1.0, 0.0 

set effect constant vector effectcount, "LightPos1", 1
set effect constant vector effectcount, "LightCol1", 2

set effect constant vector effectcount, "LightPos2", 3
set effect constant vector effectcount, "LightCol2", 4

set effect constant vector effectcount, "LightPos3", 5
set effect constant vector effectcount, "LightCol3", 6


I think the tweakables in Ninja Matts shader are LightPos1-8 and LightCol1-8, not sure though. Make sure you replace the "effectcount" with the proper effect number. Just give it anoher try. Good luck
Posted: 16th Jun 2007 17:21
Sorry guys,

Could somebody please have a quick scan through this and tell me why its still only showing the first 2 lights. i'm using the correct .fx file from NinjaMatt which should allow up to 8 lights...

+ Code Snippet
`  ======================================
`  ==   SHADER: Normal Map Version 2   ==
`  ======================================
`                Made for DBPro 5.2

`=== Set Resolution =======================================
if check display mode(1024,768,32)=1 THEN set display mode 1024,768,32

`=== Initialise System ====================================
autocam off
sync on : sync rate 60
hide mouse
set global collision off
backdrop on
color backdrop rgb(10,100,10)
randomize timer()

`=== Load a Cube ==========================================
load object "wolfoutput4.x",1

`=== Load and Apply Normalmap Shader ======================
load effect "bump.fx",1,1
set effect technique 1,"NormalSpecular"
set object effect 1,1

`=== Create Light Vectors =================================
null=make vector4(1)
null=make vector4(2)
null=make vector4(3)
null=make vector4(4)
null=make vector4(5)
null=make vector4(6)
null=make vector4(7) : `Light 4 Position
null=make vector4(8) : `Light 4 Colour



`=== Colour Lights ========================================


set vector4 1,100,20,0,0.0
set vector4 2,0.5,1.0,0.5,0.00001

set vector4 3,0,25,100,0.0
set vector4 4,1.0,0.5,0.5,0.00001

set vector4 5,100,25,100,0.0
set vector4 6,0.5,0.5,1.0,0.00001

set vector4 7,80,25,50,0.0
set vector4 8,0.5,0.5,1.0,0.00001


set effect constant vector 1,"Light1Pos",1
set effect constant vector 1,"Light1Col",2

set effect constant vector 1,"Light2Pos",3
set effect constant vector 1,"Light2Col",4

set effect constant vector 1,"Light3Pos",5
set effect constant vector 1,"Light3Col",6

set effect constant vector 1,"Light4Pos",7
set effect constant vector 1,"Light4Col",8



`=== LOOP BEGINS ====================================================
while escapekey()=0

`=== Display Instructions =================================
set cursor 0,0
print "Press ESCAPE to exit"


`=== Rotate Camera and Crate ==============================
position camera 200,45,200
point camera 0.0,0.0,0.0

loop object 1, 0, 450


`=== LOOP ENDS ======================================================
sync
endwhile


Thanks

Dan
Posted: 16th Jun 2007 19:33
You are using the wrong technique. I know in the sample demo it says set effect technique to "NormalSpecular". But if you scan the shader file the only techniques you'll find are Lights2,Lights4 and Lights8. Like I already mentioned in my previous post, set the effect technique to "Lights4" and it should work fine.

I edited the original sample to include 4 lights, I tested it and it's working.

+ Code Snippet
`  ======================================
`  ==   SHADER: Normal Map Version 2   ==
`  ======================================
`                Made for DBPro 5.2

`=== Set Resolution =======================================
if check display mode(1024,768,32)=1 THEN set display mode 1024,768,32

`=== Initialise System ====================================
autocam off
sync on : sync rate 60
hide mouse
set global collision off
backdrop on
color backdrop 0
randomize timer()

`=== Load a Cube ==========================================
load object "Files\8Cube.x",1

`=== Load and Apply Normalmap Shader ======================
load effect "Files\NormalSpecular21.fx",1,1
set effect technique 1,"Lights4"
set object effect 1,1

`=== Create Light Vectors =================================
null=make vector4(1) : `Light 1 Position
null=make vector4(2) : `Light 2 Position
null=make vector4(3) : `Light 1 Colour
null=make vector4(4) : `Light 2 Colour
null=make vector4(5) : `Camera Position
null=make vector4(6) : `Light 3 Position
null=make vector4(7) : `Light 4 Position
null=make vector4(8) : `Light 3 Colour
null=make vector4(9) : `Light 4 Colour

make object sphere 2,16.0,8,16
color object 2,rgb(0,0,255)

make object sphere 3,16.0,8,16
color object 3,rgb(255,0,0)

make object sphere 4,16.0,8,16
color object 4,rgb(0,255,0)

make object sphere 5,16.0,8,16
color object 5,rgb(255,255,255)
`=== Colour Lights ========================================
Light1Red#  = 0.0
Light1Grn#  = 0.5
Light1Blu#  = 1.0
Light1Fall# = 0.0002

Light2Red#  = 1.0
Light2Grn#  = 0.5
Light2Blu#  = 0.5
Light2Fall# = 0.0002

Light3Red#  = 0.5
Light3Grn#  = 1.0
Light3Blu#  = 0.5
Light3Fall# = 0.0002

Light4Red#  = 1.0
Light4Grn#  = 1.0
Light4Blu#  = 1.0
Light4Fall# = 0.0002

set vector4 3,Light1Red#,Light1Grn#,Light1Blu#,Light1Fall#
set vector4 4,Light2Red#,Light2Grn#,Light2Blu#,Light2Fall#
set vector4 8,Light3Red#,Light3Grn#,Light3Blu#,Light3Fall#
set vector4 9,Light4Red#,Light4Grn#,Light4Blu#,Light4Fall#

set effect constant vector 1,"Light1Col",3
set effect constant vector 1,"Light2Col",4
set effect constant vector 1,"Light3Col",8
set effect constant vector 1,"Light4Col",9
`=== Pre-set Values =======================================
light1#=0.0
light2#=0.0
light3#=0.0
light4#=0.0
camera#=0.0

`=== LOOP BEGINS ====================================================
while escapekey()=0

`=== Display Instructions =================================
set cursor 0,0
print "Press ESCAPE to exit"

`=== Position and Rotate Lights ===========================
light1#=wrapvalue(light1#+1.4)
light2#=wrapvalue(light2#+1.9)
light3#=wrapvalue(light3#+0.9)
light4#=wrapvalue(light4#+1.9)

set vector4 1,sin(light1#)*96.0,cos(light1#)*32.0,cos(light1#)*96.0,0.0
set vector4 2,cos(light2#)*32.0,sin(light2#)*96.0,cos(light2#)*96.0,0.0
set vector4 6,sin(light3#)*96.0,cos(light3#)*32.0,cos(light3#)*96.0,0.0
set vector4 7,cos(light4#)*32.0,sin(light4#)*96.0,cos(light4#)*96.0,0.0

set effect constant vector 1,"Light1Pos",1
set effect constant vector 1,"Light2Pos",2
set effect constant vector 1,"Light3Pos",6
set effect constant vector 1,"Light4Pos",7

position object 2,x vector4(1),y vector4(1),z vector4(1)
position object 3,x vector4(2),y vector4(2),z vector4(2)
position object 4,x vector4(6),y vector4(6),z vector4(6)
position object 5,x vector4(7),y vector4(7),z vector4(7)

`=== Rotate Camera and Crate ==============================
camera#=wrapvalue(camera#+0.3)
position camera -sin(camera#)*128.0,32.0,cos(camera#)*128.0
point camera 0.0,0.0,0.0
set vector4 5,camera position x(),camera position y(),camera position z(),0.0
set effect constant vector 1,"EyePos",5

xrotate object 1,wrapvalue(object angle x(1)+0.5)
yrotate object 1,wrapvalue(object angle y(1)+0.2)

`=== LOOP ENDS ======================================================
sync
endwhile