shared float4x4 World          : WORLD          < string SasBindAddress = "Sas.Skeleton.MeshToJointToWorld[0]"; >;
shared float4x4 View           : VIEW           < string SasBindAddress = "Sas.Camera.WorldToView"; >;
shared float4x4 Projection     : PROJECTION     < string SasBindAddress = "Sas.Camera.Projection"; >;
shared float3   CameraPosition : CAMERAPOSITION < string SasBindAddress = "Sas.Camera.Position"; >;
shared float4   Time           : TIME           < string SasBindAddress = "Sas.Time.Now"; >;
shared float3   LightDir       : DIRECTION      < string SasBindAddress = "Sas.DirectionalLight[0].Direction"; >;

//===========================================================================
float2 MapToTexCoord (float2 coord) {
    return (float2(coord.x, -coord.y) + 1) * 0.5f;
}

texture2D tex0 <
    string Name = "diffuse";
    string SasResourceAddress = ".\\arrow.tga";
>;
texture2D tex1 <
    string Name = "normal";
    string SasResourceAddress = ".\\dot3.tga";
>;
texture2D tex2 <
    string Name = "light";
    string SasResourceAddress = ".\\ex_tex_lighting.tga";
>;

sampler2D sampler0 <
    string Texture = "tex0";
> = sampler_state{
    Texture   = <tex0>;
    AddressU  = Wrap;
    AddressV  = Wrap;
    MagFilter = Linear;
    MinFilter = Linear;
    MipFilter = Point;
};
sampler2D sampler1 <
    string Texture = "tex1";
> = sampler_state{
    Texture   = <tex1>;
    AddressU  = Wrap;
    AddressV  = Wrap;
    MagFilter = Linear;
    MinFilter = Linear;
    MipFilter = Linear;
};
sampler2D sampler2 <
    string Texture = "tex2";
> = sampler_state{
    Texture   = <tex2>;
    AddressU  = Clamp;
    AddressV  = Clamp;
    MagFilter = Linear;
    MinFilter = Linear;
    MipFilter = Linear;
};

//===========================================================================
void VertexShader0 (
    float3 position : POSITION,
    float3 normal : NORMAL,
    float2 texCoord0 : TEXCOORD0,
    float3 tangent : TANGENT0,
    float3 binormal : BINORMAL0,
    out float2 oT0 : TEXCOORD0,
    out float2 oT1 : TEXCOORD1,
    out float3 oT2 : TEXCOORD2,
    out float3 oT3 : TEXCOORD3,
    out float4 oPos : POSITION
) {
    oPos = mul(mul(mul(float4(position, 1), World), View), Projection);
    float3 eyeDir = normalize(CameraPosition - mul(float4(position, 1), World));
    float3 halfAngle = normalize(-LightDir + eyeDir);
    float3x3 objToTangentSpace;
    objToTangentSpace[0] = tangent;
    objToTangentSpace[1] = binormal;
    objToTangentSpace[2] = normal;
    oT0 = texCoord0;
    oT1 = texCoord0;
    oT2 = mul(objToTangentSpace, mul(World, -LightDir));
    oT3 = mul(objToTangentSpace, mul(World, halfAngle));
}

//===========================================================================
float4 PixelShader0 (
    float2 texCoord0_s0 : TEXCOORD0,
    float2 texCoord0_s1 : TEXCOORD1,
    float3 lightDir_Tan_s2 : TEXCOORD2,
    float3 halfAngle_Tan_s2 : TEXCOORD3
) : COLOR {
    float4 texData7 = tex2D(sampler0, texCoord0_s0);
    float4 normalTemp1 = tex2D(sampler1, texCoord0_s1) * 2 - 1;
    float NdotL1 = dot(normalTemp1, lightDir_Tan_s2);
    float NdotH1 = dot(normalTemp1, halfAngle_Tan_s2);
    normalTemp1 = tex2D(sampler2, float2(NdotL1, NdotH1));
    float3 diffuse1 = normalTemp1.xyz;
    float specular1 = normalTemp1.a;
    float4 op8 = texData7 * float4(diffuse1.x, diffuse1.y, diffuse1.z, 0);
    float4 op9 = op8 + float4(specular1, specular1, specular1, specular1);
    op9.a = 1;
    return op9;
}

technique T0 < string SortTri = "Off"; > {
    pass P0 <
        string TexGen[] = {"texCoord0", "texCoord0", "lightDir_Tan", "halfAngle_Tan"};
    > {
        CullMode         = CCW;
        PixelShader      = compile ps_1_1 PixelShader0();
        VertexShader     = compile vs_1_1 VertexShader0();
    }
}
