//vertex shader:
float3 fvLightPosition;
float3 fvEyePosition;
float4x4 matView;
float4x4 matViewProjection;
struct VS_INPUT 
{
   float4 Position : POSITION0;
   float2 Texcoord : TEXCOORD0;
   float3 Normal :   NORMAL0;//通常只需要两个向量,因为另一个可以叉乘得到
   float3 Binormal : BINORMAL0;
   float3 Tangent :  TANGENT0;
   
};
struct VS_OUTPUT 
{
   float4 Position :        POSITION0;
   float2 Texcoord :        TEXCOORD0;
   float3 ViewDirection :   TEXCOORD1;
   float3 LightDirection:   TEXCOORD2;
   
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
   Output.Position         = mul( Input.Position, matViewProjection );
   Output.Texcoord         = Input.Texcoord;
   
   float3 fvObjectPosition = mul( Input.Position, matView );
   
   float3 fvViewDirection  = fvEyePosition - fvObjectPosition;
   float3 fvLightDirection = fvLightPosition - fvObjectPosition;
     
   float3 fvNormal         = mul( Input.Normal, matView );
   float3 fvTangent        = mul( Input.Tangent, matView );
   float3 fvBinormal       = mul( Input.Binormal, matView );//通常输入只需要nornal和tangent,binormal可以由两者叉乘得到
   //fvBinormal = cross( fvNormal, fvTangent );
  
//将视方向和光线方向都转换到法线空间(或者称切线空间)    
   Output.ViewDirection.x  = dot( fvTangent, fvViewDirection );
   Output.ViewDirection.y  = dot( fvBinormal, fvViewDirection );
   Output.ViewDirection.z  = dot( fvNormal, fvViewDirection );
   
   Output.LightDirection.x  = dot( fvTangent, fvLightDirection );
   Output.LightDirection.y  = dot( fvBinormal, fvLightDirection );
   Output.LightDirection.z  = dot( fvNormal, fvLightDirection );
   
   return( Output );
   
}
//Pixel Shader
float4 fvAmbient;
float4 fvSpecular;
float4 fvDiffuse;
float fSpecularPower;
sampler2D baseMap;
sampler2D bumpMap;
struct PS_INPUT 
{
   float2 Texcoord :        TEXCOORD0;
   float3 ViewDirection :   TEXCOORD1;
   float3 LightDirection:   TEXCOORD2;
   
};
float4 ps_main( PS_INPUT Input ) : COLOR0
{      
   float3 fvLightDirection = normalize( Input.LightDirection );
   float3 fvNormal         = normalize( ( tex2D( bumpMap, Input.Texcoord ).xyz * 2.0f ) - 1.0f );
   float  fNDotL           = dot( fvNormal, fvLightDirection ); 
   
   float3 fvReflection     = normalize( ( ( 2.0f * fvNormal ) * ( fNDotL ) ) - fvLightDirection ); 
   float3 fvViewDirection  = normalize( Input.ViewDirection );
   float  fRDotV           = max( 0.0f, dot( fvReflection, fvViewDirection ) );
   
   float4 fvBaseColor      = tex2D( baseMap, Input.Texcoord );
   
   float4 fvTotalAmbient   = fvAmbient * fvBaseColor; 
   float4 fvTotalDiffuse   = fvDiffuse * fNDotL * fvBaseColor; 
   float4 fvTotalSpecular  = fvSpecular * pow( fRDotV, fSpecularPower );
   
   return( saturate( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular ) );
      
}