Yes, this shader is done using 3.0 shaders, because that saved passes.
However, it can easily be converted to 2.0 .. just make each pass do only 2 lights..and add some passes.

For instance here is the normal mapping shader form the SPhere Engine(you wont be able to use this as is, but it will show you waht to do):
Code:
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//normalmapping

struct VS_INPUT_STRUCT
{
half4 position: POSITION;
half3 tangent: TEXCOORD1;
half3 binormal: TEXCOORD2;
half3 normal: NORMAL;
half2 texcoord0: TEXCOORD0;
};

struct VS_OUTPUT_STRUCT
{
half4 position: POSITION;
half2 bump_map: TEXCOORD0;
half3 tangentlight: TEXCOORD1;
half3 tangenteye: TEXCOORD3;
half3 Att1 : TEXCOORD4;
half3 Att2 : TEXCOORD6;
half3 tangentlight2: TEXCOORD2;
half4 eyeLinear: TEXCOORD5;
half Fog : FOG;
};

VS_OUTPUT_STRUCT VS_PASS0( VS_INPUT_STRUCT vsInStruct )
{
VS_OUTPUT_STRUCT vsOutStruct;
vsOutStruct.Fog = 10000;
vsOutStruct.position = mul( vsInStruct.position,matWorldViewProj );
vsOutStruct.bump_map = vsInStruct.texcoord0;

// compute the 3x3 tranform matrix
// to transform from world space to tangent space
half3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul(vsInStruct.tangent, matWorld);
// worldToTangentSpace[1] = mul(cross(vsInStruct.tangent, vsInStruct.normal), -matWorld);
worldToTangentSpace[1] = mul(vsInStruct.binormal, -matWorld);
worldToTangentSpace[2] = mul(vsInStruct.normal, matWorld);

half3 PosWorld = mul(vsInStruct.position, matWorld);

// Output the projective texture coordinates
vsOutStruct.eyeLinear= mul( vsInStruct.position, matTexture );

//light 1
half3 objectspace_light_vector = PosWorld - vecLightPos ;
vsOutStruct.tangentlight = mul(worldToTangentSpace, -objectspace_light_vector); // L
half3 objectspace_view_vector = PosWorld - vecViewPos;
vsOutStruct.tangenteye = mul(worldToTangentSpace, -objectspace_view_vector); // V
vsOutStruct.Att1 = objectspace_light_vector * (vecLightColor.w*0.6);

//light 2
half3 objectspace_light_vector2 = PosWorld - vecLightPos2 ;
vsOutStruct.tangentlight2 = mul(worldToTangentSpace, -objectspace_light_vector2); // L
vsOutStruct.Att2 = objectspace_light_vector2 * (vecLightColor2.w*0.6);

return vsOutStruct;
}

struct PS_INPUT_STRUCT
{
half2 bump_map: TEXCOORD0;
half3 tangentlight: TEXCOORD1;
half3 tangenteye: TEXCOORD3;
half3 Att1 : TEXCOORD4;
half3 Att2 : TEXCOORD6;
half3 tangentlight2: TEXCOORD2;
half4 eyeLinear: TEXCOORD5;
};

struct PS_OUTPUT_STRUCT
{
half4 color0: COLOR0;
};


PS_OUTPUT_STRUCT PS_PASS0( PS_INPUT_STRUCT psInStruct )
{
PS_OUTPUT_STRUCT psOutStruct;

half4 Attenuation1 = mul(psInStruct.Att1, psInStruct.Att1);
half4 Attenuation2 = mul(psInStruct.Att2, psInStruct.Att2);

half3 eyevect = normalize(psInStruct.tangenteye);

// half2 modified_texcoord = ParallaxTexCoord(psInStruct.bump_map, BumpMapSampler, eyevect, parallax);

// half4 base = tex2D( ColorMapSampler, modified_texcoord);
half4 base = tex2D( ColorMapSampler, psInStruct.bump_map);
// half3 bump = bumpheight * (tex2D(BumpMapSampler, modified_texcoord) - 0.5); // fetch bump map
half3 bump = bumpheight * (tex2D(BumpMapSampler, psInStruct.bump_map) - 0.5); // fetch bump map
// normalize(bump);

half3 LightDir1 = normalize(psInStruct.tangentlight);
half3 ViewDir1 = normalize(psInStruct.tangenteye);
half4 diff1 = saturate(dot(bump, LightDir1)); // diffuse component
half3 Reflect1 = normalize(2 * diff1 * bump - LightDir1); // R
half4 spec1 = pow(saturate(dot(Reflect1, ViewDir1)), 15);

half3 LightDir2 = normalize(psInStruct.tangentlight2);
half4 diff2 = saturate(dot(bump, LightDir2)); // diffuse component
half3 Reflect2 = normalize(2 * diff2 * bump - LightDir2); // R
half4 spec2 = pow(saturate(dot(Reflect2, ViewDir1)), 15);

// half shadow1 = saturate(4 * diff1);
// half shadow2 = saturate(4 * diff2);

half4 shadow_map =tex2Dproj(shadowmap_1, psInStruct.eyeLinear);

if (enable_shadows==0)
{
shadow_map =1;
}


half4 shadow_map1 = shadow_map.r;
half4 shadow_map2 = shadow_map.g;

psOutStruct.color0.rgb = (ambientcolor * base) + saturate((((/*shadow1*/ (base * diff1 + (spec1*base.w)) * (1-Attenuation1))*(vecLightColor)))*saturate(shadow_map1))+
saturate(((/*shadow2*/ (base * diff2 + (spec2*base.w)) * (1-Attenuation2))*(vecLightColor2))*saturate(shadow_map2));

psOutStruct.color0.a = 1.0f;

return psOutStruct;
}


///////////////////////////////////////////////////////////////////////////////////////////
struct VS_INPUT_STRUCT1
{
half4 position: POSITION;
half3 tangent: TEXCOORD1;
half3 binormal: TEXCOORD2;
half3 normal: NORMAL;
half2 texcoord0: TEXCOORD0;
};

struct VS_OUTPUT_STRUCT1
{
half4 position: POSITION;
half2 bump_map: TEXCOORD0;
half3 tangentlight: TEXCOORD1;
half3 tangentlight2:TEXCOORD2;
half3 tangenteye: TEXCOORD3;
half3 Att1 : TEXCOORD4;
half3 Att2 : TEXCOORD6;
half4 eyeLinear: TEXCOORD5;
half Fog : FOG;
};

VS_OUTPUT_STRUCT1 VS_PASS1( VS_INPUT_STRUCT1 vsInStruct )
{
VS_OUTPUT_STRUCT1 vsOutStruct;
vsOutStruct.Fog = 10000;
vsOutStruct.position = mul( vsInStruct.position,matWorldViewProj );
vsOutStruct.bump_map = vsInStruct.texcoord0;

// compute the 3x3 tranform matrix
// to transform from world space to tangent space
half3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul(vsInStruct.tangent, matWorld);
// worldToTangentSpace[1] = mul(cross(vsInStruct.tangent, vsInStruct.normal), -matWorld);
worldToTangentSpace[1] = mul(vsInStruct.binormal, -matWorld);
worldToTangentSpace[2] = mul(vsInStruct.normal, matWorld);

half3 PosWorld = mul(vsInStruct.position, matWorld);

vsOutStruct.eyeLinear= mul( vsInStruct.position, matTexture );

half3 objectspace_light_vector = PosWorld - vecLightPos3 ;
vsOutStruct.tangentlight = mul(worldToTangentSpace, -objectspace_light_vector); // L
half3 objectspace_view_vector = PosWorld - vecViewPos;
vsOutStruct.tangenteye = mul(worldToTangentSpace, -objectspace_view_vector); // V
vsOutStruct.Att1 = objectspace_light_vector * (vecLightColor3.w*0.6);

half3 objectspace_light_vector2 = PosWorld - vecLightPos4 ;
vsOutStruct.tangentlight2 = mul(worldToTangentSpace, -objectspace_light_vector2); // L
vsOutStruct.Att2 = objectspace_light_vector2 * (vecLightColor4.w*0.6);

return vsOutStruct;
}

struct PS_INPUT_STRUCT1
{
half2 bump_map: TEXCOORD0;
half3 tangentlight: TEXCOORD1;
half3 tangentlight2:TEXCOORD2;
half3 tangenteye: TEXCOORD3;
half3 Att1 : TEXCOORD4;
half3 Att2 : TEXCOORD6;
half4 eyeLinear: TEXCOORD5;
};

struct PS_OUTPUT_STRUCT1
{
half4 color0: COLOR0;
};

PS_OUTPUT_STRUCT1 PS_PASS1( PS_INPUT_STRUCT1 psInStruct )
{
PS_OUTPUT_STRUCT1 psOutStruct;

half4 Attenuation1 = mul(psInStruct.Att1, psInStruct.Att1);
half4 Attenuation2 = mul(psInStruct.Att2, psInStruct.Att2);

half3 eyevect = normalize(psInStruct.tangenteye);

// half2 modified_texcoord = ParallaxTexCoord(psInStruct.bump_map, BumpMapSampler, eyevect, parallax);

// half4 base = tex2D( ColorMapSampler, modified_texcoord);
half4 base = tex2D( ColorMapSampler, psInStruct.bump_map);
// half3 bump = bumpheight * (tex2D(BumpMapSampler, modified_texcoord) - 0.5); // fetch bump map
half3 bump = bumpheight * (tex2D(BumpMapSampler, psInStruct.bump_map) - 0.5); // fetch bump map
// normalize(bump);

half3 LightDir1 = normalize(psInStruct.tangentlight);
half3 ViewDir1 = normalize(psInStruct.tangenteye);
half4 diff1 = saturate(dot(bump, LightDir1)); // diffuse component
half3 Reflect1 = normalize(2 * diff1 * bump - LightDir1); // R
half4 spec1 = pow(saturate(dot(Reflect1, ViewDir1)), 15);


half3 LightDir2 = normalize(psInStruct.tangentlight2);
half4 diff2 = saturate(dot(bump, LightDir2)); // diffuse component
half3 Reflect2 = normalize(2 * diff2 * bump - LightDir2); // R
half4 spec2 = pow(saturate(dot(Reflect2, ViewDir1)), 15);


// half shadow1 = saturate(4 * diff1);
// half shadow2 = saturate(4 * diff2);

half4 shadow_map = tex2Dproj(shadowmap_1, psInStruct.eyeLinear);
half4 shadow_mapa = tex2Dproj(shadowmap_2, psInStruct.eyeLinear);

if (enable_shadows==false)
{
shadow_map =1;
shadow_mapa =1;
}

half4 shadow_map1 = shadow_map.b;
half4 shadow_map2 = shadow_mapa.r;

psOutStruct.color0.rgb =saturate((((/*shadow1*/ (base * diff1 + (spec1*base.w)) * (1-Attenuation1))*(vecLightColor3)))*saturate(shadow_map1))+
saturate(((/*shadow2*/ (base * diff2 + (spec2*base.w)) * (1-Attenuation2))*(vecLightColor4))*saturate(shadow_map2));

psOutStruct.color0.a = 1.0f;

return psOutStruct;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


struct VS_INPUT_STRUCT2
{
half4 position: POSITION;
half3 tangent: TEXCOORD1;
half3 binormal: TEXCOORD2;
half3 normal: NORMAL;
half2 texcoord0: TEXCOORD0;
};

struct VS_OUTPUT_STRUCT2
{
half4 position: POSITION;
half2 bump_map: TEXCOORD0;
half3 tangentlight: TEXCOORD1;
half3 tangenteye: TEXCOORD3;
half3 Att1 : TEXCOORD4;
half3 Att2 : TEXCOORD6;
half3 tangentlight2: TEXCOORD2;
half4 eyeLinear: TEXCOORD5;
half Fog : FOG;
};

VS_OUTPUT_STRUCT2 VS_PASS2( VS_INPUT_STRUCT2 vsInStruct )
{
VS_OUTPUT_STRUCT2 vsOutStruct;
vsOutStruct.Fog = 10000;
vsOutStruct.position = mul( vsInStruct.position,matWorldViewProj );
vsOutStruct.bump_map = vsInStruct.texcoord0;

// compute the 3x3 tranform matrix
// to transform from world space to tangent space
half3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul(vsInStruct.tangent, matWorld);
// worldToTangentSpace[1] = mul(cross(vsInStruct.tangent, vsInStruct.normal), -matWorld);
worldToTangentSpace[1] = mul(vsInStruct.binormal, -matWorld);
worldToTangentSpace[2] = mul(vsInStruct.normal, matWorld);

half3 PosWorld = mul(vsInStruct.position, matWorld);

// Output the projective texture coordinates
vsOutStruct.eyeLinear= mul( vsInStruct.position, matTexture );

//light 1
half3 objectspace_light_vector = PosWorld - vecLightPos5 ;
vsOutStruct.tangentlight = mul(worldToTangentSpace, -objectspace_light_vector); // L
half3 objectspace_view_vector = PosWorld - vecViewPos;
vsOutStruct.tangenteye = mul(worldToTangentSpace, -objectspace_view_vector); // V
vsOutStruct.Att1 = objectspace_light_vector * (vecLightColor5.w*0.6);

//light 2
half3 objectspace_light_vector2 = PosWorld - vecLightPos6 ;
vsOutStruct.tangentlight2 = mul(worldToTangentSpace, -objectspace_light_vector2); // L
vsOutStruct.Att2 = objectspace_light_vector2 * (vecLightColor6.w*0.6);

return vsOutStruct;
}


struct PS_INPUT_STRUCT2
{
half2 bump_map: TEXCOORD0;
half3 tangentlight: TEXCOORD1;
half3 tangenteye: TEXCOORD3;
half3 Att1 : TEXCOORD4;
half3 Att2 : TEXCOORD6;
half3 tangentlight2: TEXCOORD2;
half4 eyeLinear: TEXCOORD5;
};

struct PS_OUTPUT_STRUCT2
{
half4 color0: COLOR0;
};


PS_OUTPUT_STRUCT2 PS_PASS2( PS_INPUT_STRUCT2 psInStruct )
{
PS_OUTPUT_STRUCT2 psOutStruct;

half4 Attenuation1 = mul(psInStruct.Att1, psInStruct.Att1);
half4 Attenuation2 = mul(psInStruct.Att2, psInStruct.Att2);

half4 base = tex2D( ColorMapSampler, psInStruct.bump_map);

half3 bump = bumpheight * (tex2D(BumpMapSampler, psInStruct.bump_map) - 0.5); // fetch bump map
// normalize(bump);

half3 LightDir1 = normalize(psInStruct.tangentlight);
half3 ViewDir1 = normalize(psInStruct.tangenteye);
half4 diff1 = saturate(dot(bump, LightDir1)); // diffuse component
half3 Reflect1 = normalize(2 * diff1 * bump - LightDir1); // R
half4 spec1 = pow(saturate(dot(Reflect1, ViewDir1)), 15);

half3 LightDir2 = normalize(psInStruct.tangentlight2);
half4 diff2 = saturate(dot(bump, LightDir2)); // diffuse component
half3 Reflect2 = normalize(2 * diff2 * bump - LightDir2); // R
half4 spec2 = pow(saturate(dot(Reflect2, ViewDir1)), 15);

// half shadow1 = saturate(4 * diff1);
// half shadow2 = saturate(4 * diff2);

half4 shadow_map =tex2Dproj(shadowmap_2, psInStruct.eyeLinear);

if (enable_shadows==false)
{
shadow_map =1;

}

half4 shadow_map1 = shadow_map.g;
half4 shadow_map2 = shadow_map.b;

psOutStruct.color0.rgb = (ambientcolor * base) + saturate((((/*shadow1**/ (base * diff1 + (spec1*base.w)) * (1-Attenuation1))*(vecLightColor5)))*saturate(shadow_map1))+
saturate(((/*shadow2* */(base * diff2 + (spec2*base.w)) * (1-Attenuation2))*(vecLightColor6))*saturate(shadow_map2));

psOutStruct.color0.a = 1.0f;

return psOutStruct;
}




Sphere Engine--the premier A6 graphics plugin.