This shader is based on Jacmoe's diffuse/normal/specular hardware skinning shader. Thanks to Jacmoe for posting that. Thanks to the help of toglia for the code allowing for two lights  and BSer and Jabberwocky for sharing their code for having an alpha channel in a shader.

Description

This shader is built on Jacmoe's hardware skinning with normal and specular channels. This shader adds an additional light and an alpha channel.
It should work with gpu's that support shader model 2 and above. A live Openspace scene is posted to: http://www.ifam.net/openspace/bakedspaceman/web/index.html. You need win os or linux running wine and the scol voyager plugin (from http://scolring.org/index.php/logiciels ) to view the scene. If the plugin is not installed on your system you will be prompted for an install. Openspace like Ogre is opensource. It uses the scol language to manipulate ogre and other environment components (windows, sounds, physics, etc.).

Advantages

One pass, hardware does the skinning, all your traditional 3d channels can be included.

Bugs and Disadvantages

You have to horizontally flip and then rotate the alpha channel image 90 degrees clockwise (or counterclockwise, if clockwise fails you) in order for the alpha to line up with the diffuse/normal/specular values.

Improvements

If you can figure out the alpha channel rotation problems, or add another light (or more), or add a hemispherical light, or an ao channel, if you can figure out how to get this shader to work on entities that don't use hardware skinning (i.e. entities that don't have skeletons), be my guest, especially if you don't go beyond the limited shader model 2 instruction count.

Here are a couple of screenshots of a normal baked figure. The alpha channel has been horizontally flipped and rotated so that the mohawk alpha lines up with the mohawk specular, normal, and diffuse maps. Below the screenshots are an image of the uv space, the diffuse map, normal map, specular map, and that annoying rotated and flipped alpha map.
Image
Image
Image
Image
Image
Image
Image

Usage


The figure in the screenshots above uses the material named bodymaterial.

Material file

//vertex program declaraction to refer to hlsl file

vertex_program AnimatedNormalSpecular_VP hlsl
{
source animatedNormalSpecular.hlsl
entry_point main_vp
target vs_2_0
column_major_matrices false		//required for hlsl skinning

includes_skeletal_animation true

default_params
{
//param_named_auto worldviewprojmatrix worldviewproj_matrix
param_named_auto light_position light_position_object_space 0
//begin added code as per your post
param_named_auto light_position1 light_position_object_space 1
//end added code as per your post
param_named_auto eye_position camera_position_object_space

param_named_auto worldMatrix3x4Array world_matrix_array_3x4
param_named_auto viewProjectionMatrix viewproj_matrix
param_named_auto invworldmatrix inverse_world_matrix
}
}
//fragment program declaraction to refer to hlsl file

fragment_program AnimatedNormalSpecular_FP hlsl
{
	source animatedNormalSpecular.hlsl
	entry_point main_fp
	target ps_2_0

	default_params
	{
		param_named_auto lightDiffuse light_diffuse_colour 0
		param_named_auto ambientLight ambient_light_colour 0
		param_named_auto specularLight light_specular_colour 0
		 //begin added code as per your post
		param_named_auto lightDiffuse1 light_diffuse_colour 1
		param_named_auto specularLight1 light_specular_colour 1
		 //end added code as per your post
		param_named specular_power float 124
		param_named bumpiness float 1
	}
}

// Same as below, but for use when rendering texture shadows
vertex_program HardwareSkinningFourWeightsShadowCasterHLSL hlsl
{
	source Example_Basic.hlsl
	entry_point hardwareSkinningFourWeights_vp
	target vs_1_1
	includes_skeletal_animation true
	column_major_matrices false
}

material bodymaterial
{		
        technique
	{
		pass Single Pass
		{
			scene_blend alpha_blend
			cull_hardware none
			cull_software none
			
			//this part is in the ogre samples somewhere
		
			shadow_caster_vertex_program_ref HardwareSkinningFourWeightsShadowCasterHLSL
			{
				param_named_auto worldMatrix3x4Array world_matrix_array_3x4
				param_named_auto viewProjectionMatrix viewproj_matrix
				param_named_auto ambient ambient_light_colour
			
			}
			
			
			vertex_program_ref AnimatedNormalSpecular_VP
			{
			}

			fragment_program_ref AnimatedNormalSpecular_FP
			{
			}		

			//diffuse map with alpha channel
			texture_unit
			{
				texture_alias base_map
				texture bodycolor.png
				filtering linear linear linear
			}

			//normal map
			texture_unit
			{
				texture_alias bump_map
				texture dannormalmap.png
				//texture blendernormalbake.png
				filtering linear linear linear
			}

		 // specular map
			 texture_unit specular_map
			 {
				texture_alias specular_map
				texture danspecular.png
			 }
		
		 // alhpa map
			 texture_unit alpha_map
			 {
				texture_alias alpha_map
				texture torsosalpha.png
			 }
		}
	}
}

material hairmaterial
{	
        technique
	{
		pass Single Pass
		{
			scene_blend alpha_blend
			cull_hardware none
			cull_software none
			
			//this part is in the ogre samples somewhere
		
			shadow_caster_vertex_program_ref HardwareSkinningFourWeightsShadowCasterHLSL
			{
				param_named_auto worldMatrix3x4Array world_matrix_array_3x4
				param_named_auto viewProjectionMatrix viewproj_matrix
				param_named_auto ambient ambient_light_colour
			
			}
			
			
			vertex_program_ref AnimatedNormalSpecular_VP
			{
			}

			fragment_program_ref AnimatedNormalSpecular_FP
			{
			}		

			//diffuse map with alpha channel
			texture_unit
			{
				texture_alias base_map
				texture mohawkcolor.jpg
				filtering linear linear linear
			}

			//normal map
			texture_unit
			{
				texture_alias bump_map
				texture mohawknormalmap.jpg
				//texture blendernormalbake.png
				filtering linear linear linear
			}

		 // specular map
			 texture_unit specular_map
			 {
				
				texture_alias specular_map
				texture mohawkspecular.jpg
			 }
		
	
		// alpha_map
			 texture_unit alpha_map
			 {
				
				texture_alias alpha_map
				texture mohawkalpha.jpg
			 }	
		}
	}
}

Here are the .hlsl files referenced in the .material file. I have included all of them here:
Example_Basic.hlsl:

!/*
  Basic ambient lighting vertex program
*/
void ambientOneTexture_vp(float4 position : POSITION,
						  float2 uv		  : TEXCOORD0,
						  
						  out float4 oPosition : POSITION,
						  out float2 oUv	   : TEXCOORD0,
						  out float4 colour    : COLOR,

						  uniform float4x4 worldViewProj,
						  uniform float4 ambient)
{
	oPosition = mul(worldViewProj, position);
	oUv = uv;
	colour = ambient;
}

/*
  Single-weight-per-vertex hardware skinning, 2 lights
  The trouble with vertex programs is they're not general purpose, but
  fixed function hardware skinning is very poorly supported
*/
void hardwareSkinningOneWeight_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float2 uv       : TEXCOORD0,
	float  blendIdx : BLENDINDICES,
	

	out float4 oPosition : POSITION,
	out float2 oUv       : TEXCOORD0,
	out float4 colour           : COLOR,
	// Support up to 24 bones of float3x4
	// vs_1_1 only supports 96 params so more than this is not feasible
	uniform float3x4   worldMatrix3x4Array[24],
	uniform float4x4 viewProjectionMatrix,
	uniform float4   lightPos[2],
	uniform float4   lightDiffuseColour[2],
	uniform float4   ambient)
{
	// transform by indexed matrix
	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
	// view / projection
	oPosition = mul(viewProjectionMatrix, blendPos);
	// transform normal
	float3 norm = mul((float3x3)worldMatrix3x4Array[blendIdx], normal);
	// Lighting - support point and directional
	float3 lightDir0 = 	normalize(
		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
	float3 lightDir1 = 	normalize(
		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));

	oUv = uv;
	colour = ambient + 
		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
	
}	

/*
  Single-weight-per-vertex hardware skinning, shadow-caster pass
*/
void hardwareSkinningOneWeightCaster_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float  blendIdx : BLENDINDICES,
	

	out float4 oPosition : POSITION,
	out float4 colour    : COLOR,
	// Support up to 24 bones of float3x4
	// vs_1_1 only supports 96 params so more than this is not feasible
	uniform float3x4   worldMatrix3x4Array[24],
	uniform float4x4 viewProjectionMatrix,
	uniform float4   ambient)
{
	// transform by indexed matrix
	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
	// view / projection
	oPosition = mul(viewProjectionMatrix, blendPos);
	
	colour = ambient;
	
}	

/*
  Two-weight-per-vertex hardware skinning, 2 lights
  The trouble with vertex programs is they're not general purpose, but
  fixed function hardware skinning is very poorly supported
*/
void hardwareSkinningTwoWeights_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float2 uv       : TEXCOORD0,
	float4 blendIdx : BLENDINDICES,
	float4 blendWgt : BLENDWEIGHT,
	

	out float4 oPosition : POSITION,
	out float2 oUv       : TEXCOORD0,
	out float4 colour           : COLOR,
	// Support up to 24 bones of float3x4
	// vs_1_1 only supports 96 params so more than this is not feasible
	uniform float3x4   worldMatrix3x4Array[24],
	uniform float4x4 viewProjectionMatrix,
	uniform float4   lightPos[2],
	uniform float4   lightDiffuseColour[2],
	uniform float4   ambient)
{
	// transform by indexed matrix
	float4 blendPos = float4(0,0,0,0);
	int i;
	for (i = 0; i < 2; ++i)
	{
		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
	}
	// view / projection
	oPosition = mul(viewProjectionMatrix, blendPos);
	// transform normal
	float3 norm = float3(0,0,0);
	for (i = 0; i < 2; ++i)
	{
		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
		blendWgt[i];
	}
	norm = normalize(norm);
	// Lighting - support point and directional
	float3 lightDir0 = 	normalize(
		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
	float3 lightDir1 = 	normalize(
		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));

	
	oUv = uv;
	colour = ambient + 
		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
	
}

/*
  Two-weight-per-vertex hardware skinning, shadow caster pass
*/
void hardwareSkinningTwoWeightsCaster_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float2 uv       : TEXCOORD0,
	float4 blendIdx : BLENDINDICES,
	float4 blendWgt : BLENDWEIGHT,
	

	out float4 oPosition : POSITION,
	out float4 colour           : COLOR,
	// Support up to 24 bones of float3x4
	// vs_1_1 only supports 96 params so more than this is not feasible
	uniform float3x4   worldMatrix3x4Array[24],
	uniform float4x4 viewProjectionMatrix,
	uniform float4   ambient)
{
	// transform by indexed matrix
	float4 blendPos = float4(0,0,0,0);
	int i;
	for (i = 0; i < 2; ++i)
	{
		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
	}
	// view / projection
	oPosition = mul(viewProjectionMatrix, blendPos);
	

	colour = ambient;	
}

/*
  Four-weight-per-vertex hardware skinning, 2 lights
  The trouble with vertex programs is they're not general purpose, but
  fixed function hardware skinning is very poorly supported
*/
void hardwareSkinningFourWeights_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float2 uv       : TEXCOORD0,
	float4 blendIdx : BLENDINDICES,
	float4 blendWgt : BLENDWEIGHT,
	

	out float4 oPosition : POSITION,
	out float2 oUv       : TEXCOORD0,
	out float4 colour           : COLOR,
	// Support up to 24 bones of float3x4
	// vs_1_1 only supports 96 params so more than this is not feasible
	uniform float3x4   worldMatrix3x4Array[24],
	uniform float4x4 viewProjectionMatrix,
	uniform float4   lightPos[2],
	uniform float4   lightDiffuseColour[2],
	uniform float4   ambient)
{
	// transform by indexed matrix
	float4 blendPos = float4(0,0,0,0);
	int i;
	for (i = 0; i < 4; ++i)
	{
		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
	}
	// view / projection
	oPosition = mul(viewProjectionMatrix, blendPos);
	// transform normal
	float3 norm = float3(0,0,0);
	for (i = 0; i < 4; ++i)
	{
		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
		blendWgt[i];
	}
	norm = normalize(norm);
	// Lighting - support point and directional
	float3 lightDir0 = 	normalize(
		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
	float3 lightDir1 = 	normalize(
		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));

	
	oUv = uv;
	colour = ambient + 
		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
	
}

void hardwareMorphAnimation(float3 pos1 : POSITION,
			  float4 normal		: NORMAL,
			  float2 uv		  : TEXCOORD0,
			  float3 pos2	  : TEXCOORD1,
						  
			  out float4 oPosition : POSITION,
			  out float2 oUv	   : TEXCOORD0,
			  out float4 colour    : COLOR,

			  uniform float4x4 worldViewProj, 
			  uniform float4 anim_t)
{
	// interpolate
	float4 interp = float4(pos1 + anim_t.x*(pos2 - pos1), 1.0f);
	
	oPosition = mul(worldViewProj, interp);
	oUv = uv;
	colour = float4(1,0,0,1);
}

void hardwarePoseAnimation(float3 pos : POSITION,
			  float4 normal		: NORMAL,
			  float2 uv		  : TEXCOORD0,
			  float3 pose1	  : TEXCOORD1,
			  float3 pose2	  : TEXCOORD2,
						  
			  out float4 oPosition : POSITION,
			  out float2 oUv	   : TEXCOORD0,
			  out float4 colour    : COLOR,

			  uniform float4x4 worldViewProj, 
			  uniform float4 anim_t)
{
	// interpolate
	float4 interp = float4(pos + anim_t.x*pose1 + anim_t.y*pose2, 1.0f);
	
	oPosition = mul(worldViewProj, interp);
	oUv = uv;
	colour = float4(1,0,0,1);
}

Here is animatedNormalSpecular.hlsl:

!!void main_vp(    
     float4 position : POSITION,
     float2 uv       : TEXCOORD0, 
     float3 normal   : NORMAL,
     float3 tangent  : TANGENT0,
 
     float4 blendIdx : BLENDINDICES,
     float4 blendWgt : BLENDWEIGHT,
     out float4 oPosition    : POSITION,
     out float2 oUV          : TEXCOORD0,
     out float3 oLightVector : TEXCOORD1,
     out float3 oHalfAngle   : TEXCOORD2,
     out float3 oLightVector1 : TEXCOORD3,
     uniform float4x4 worldviewprojmatrix,
     uniform float4   light_position,

      uniform float4 light_position1,
     
     uniform float4   eye_position,
     uniform float3x4 worldMatrix3x4Array[60],
     uniform float4x4 viewProjectionMatrix,
     uniform float4x4 invworldmatrix
  ) {
     
     oUV = uv;   
 
     
     float4 blendPos = float4(0,0,0,0);
     int i;
     for (i = 0; i < 3; ++i)
     {
         blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
     }
     // view / projection
     oPosition = mul(viewProjectionMatrix, blendPos);
 
 
     // transform normal
     float3 newnormal = float3(0,0,0);
     for (i = 0; i < 3; ++i)
     {
         newnormal += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) *      blendWgt[i];
     }
     newnormal = mul((float3x3)invworldmatrix, newnormal); 
     newnormal = normalize(newnormal);
 
     // transform tangent
     float3 newtangent = float3(0,0,0);
     for (i = 0; i < 3; ++i)
     {
         newtangent += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], tangent) *      blendWgt[i];
     }
     newtangent = mul((float3x3)invworldmatrix, newtangent); 
     newtangent = normalize(newtangent); 
 
     float3 binormal = cross(newtangent, newnormal);
     float3x3 rotation = float3x3(newtangent, binormal, newnormal);
 
     // Calculate the light vector in object space,
     // and then transform it into texture space.
     float3 temp_lightDir0 = normalize(light_position.xyz -  (blendPos * light_position.w));
     temp_lightDir0 = normalize(mul(rotation, temp_lightDir0));
     oLightVector = temp_lightDir0;
      //begin added code as per your post
     float3 temp_lightDir1 = normalize(light_position1.xyz -  (blendPos * light_position1.w));
     temp_lightDir1 = normalize(mul(rotation, temp_lightDir1));
     oLightVector1 = temp_lightDir1;
      //end added code as per your post
 
 
     // Calculate the view vector in object space,
     // and then transform it into texture space.
     float3 eyeDir = normalize(eye_position - blendPos);
     eyeDir = normalize(mul(rotation, eyeDir.xyz));
 
     // Calculate the half angle
     oHalfAngle = oLightVector + eyeDir; 
 } 
 
 float4 lightDiffuse ;
 float4 ambientLight;
 //begin added code as per your post
 float4 lightDiffuse1;
 float4 specularLight1;
 //end added code as per your post
 float4 specularLight;
 float specular_power;
 float bumpiness;
 sampler base_map;
 sampler bump_map;
 sampler specular_map;
 sampler alpha_map;
 
 struct PS_INPUT_STRUCT
 {
    float2 uv:     TEXCOORD0;
    float3 light_vector: TEXCOORD1;
    float3 half_angle:   TEXCOORD2;
    //begin added  code as per your post
    float3 light_vector1: TEXCOORD3;
    //end added  code as per your post
 };
 
 struct PS_OUTPUT_STRUCT
 {
    float4 color0:       COLOR0;
 };
 
 PS_OUTPUT_STRUCT main_fp( PS_INPUT_STRUCT psInStruct )
 {
    PS_OUTPUT_STRUCT psOutStruct; 
 
   float3 base = tex2D( base_map, psInStruct.uv );
   float3 bump = tex2D( bump_map, psInStruct.uv );
   float specularLevel = tex2D(specular_map, psInStruct.uv).r;
 
   //normalise
   float3 normalized_light_vector = normalize( psInStruct.light_vector );
   float3 normalized_half_angle = normalize( psInStruct.half_angle );
   
   //begin added  code as per your post
   float3 normalized_light_vector1 = normalize( psInStruct.light_vector1);
   float4 n_dot_l1 = dot( bump, normalized_light_vector1);
    //end added  code as per your post
    
   // "Smooth out" the bump based on the bumpiness parameter.
   // This is simply a linear interpolation between a "flat"
   // normal and a "bumped" normal.  Note that this "flat"
   // normal is based on the texture space coordinate basis.
   float3 smooth = { 0.5f, 0.5f, 1.0f };
   bump = lerp( smooth, bump, bumpiness );
   bump = normalize( ( bump * 2.0f ) - 1.0f );
 
   // These dot products are used for the lighting model
   // equations.  The surface normal dotted with the light
   // vector is denoted by n_dot_l.  The normal vector
   // dotted with the half angle vector is denoted by n_dot_h.
   float4 n_dot_l = dot( bump, normalized_light_vector );
   float4 n_dot_h = dot( bump, normalized_half_angle );
 
   // Calculate the resulting pixel color,
   // based on our lighting model.
   // Ambient + Diffuse + Specular
   //begin channges as per your post
psOutStruct.color0.rgb =
( base * ambientLight) +
( base * lightDiffuse * max( 0, n_dot_l ) ) +
( base * lightDiffuse1 * max( 0, n_dot_l1 ) ) +
( specularLight * specularLevel * pow( max( 0, n_dot_h ), specular_power ) )+
( specularLight1 * specularLevel * pow( max( 0, n_dot_h ), specular_power ) );
   //end channges as per your post

//psOutStruct.color0.a = 1.0f; //** Set the alpha component manually
psOutStruct.color0.a = tex2D (alpha_map, psInStruct.uv.yx);
    if (psOutStruct.color0.a < 0.2 ) 
    {
       discard;
    }
   return psOutStruct;
 }