// scene.fx

float4 LightPos0      = { 0.0f, 0.0f, -1.0f, 1.0f };  // Light Position
float4 LightPos1      = { 0.0f, 0.0f, -1.0f, 1.0f };  // Light Position
float4 LightDiffuse0   = { 0.0f, 0.2f, 0.0f, 1.0f };   // Light Diffuse
float4 LightDiffuse1   = { 0.0f, 1.0f, 0.0f, 1.0f };   // Light Diffuse
float4 LightAmbient   = { 0.3f, 0.3f, 0.3f, 1.0f };   // Light Ambient

float4x4     WorldViewProj;
float4x4     World;
float4x4     ViewInverse;

float4       EyePos; 

float SpecularExponent = 155.0f;
float Kd = 0.9f;
float Ks = 0.8f;
float LightIntensity = 1.0f;

//--------------------------------------------------------------------------------------
// Textures and Samplers
//--------------------------------------------------------------------------------------

texture texDiffuse;                                   // Diffuse Texture

// diffuse texture sampler
sampler g_samDiffuse =
sampler_state
{
    Texture = <texDiffuse>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Point;
    AddressU = Wrap;
    AddressV = Wrap;
};


//--------------------------------------------------------------------------------------
// Vertex Data Structures
//--------------------------------------------------------------------------------------

struct VS_INPUT
{
    float4        Pos                :    POSITION;
    float3        Normal             :    NORMAL;
    float4        Tex                :    TEXCOORD0;
    float3        Tangent            :    TANGENT;
    float3        BlendWeights       :    BLENDWEIGHT;
    float4        BlendIndices       :    BLENDINDICES;
};

struct VS_OUTPUT
{
    float4        Pos                :    POSITION;
    float4        Tex                :    TEXCOORD0;
    float3        LightVec0          :    TEXCOORD1;
    float3        LightVec1          :    TEXCOORD2;
    float3        WorldView          :    TEXCOORD3;
    float3        WorldNormal        :    TEXCOORD4;
    float3        WorldTangent       :    TEXCOORD5;

};


//--------------------------------------------------------------------------------------
// Non-Skinning Vertex Shader
//--------------------------------------------------------------------------------------

VS_OUTPUT VS_NonSkinningWorldSpace ( VS_INPUT i )
{
    VS_OUTPUT   o;
     
    float4 Po = float4( i.Pos.xyz, 1.0f); 
    float4 Pw = mul ( Po, World );

    float4 vLightWorldPos0 = mul ( LightPos0, ViewInverse );
    float4 vLightWorldPos1 = mul ( LightPos1, ViewInverse );
    

    o.LightVec0 = normalize ( vLightWorldPos0.xyz - Po.xyz );
    o.LightVec1 = normalize ( vLightWorldPos1.xyz - Po.xyz );

    o.Tex = i.Tex;
    
    o.WorldView = EyePos - Pw.xyz;    
    o.Pos = mul ( Po, WorldViewProj );

    float4x4 vInstanceMatrix  = World;
    vInstanceMatrix._41 = vInstanceMatrix._42 = vInstanceMatrix._43 = 0.0f;
    o.WorldNormal = mul ( i.Normal, vInstanceMatrix).xyz;
    o.WorldTangent = mul ( i.Tangent, vInstanceMatrix).xyz;    

    return o;
}

void PS_Plastic_Shared (                float4 hPos                         : POSITION,
                                        float2 vTex0                        : TEXCOORD0,
                                        float3 LightVec                    : TEXCOORD1,
                                        float3 WorldNormal                  : TEXCOORD2,
                                        float3 WorldTangent                 : TEXCOORD3,
                                        float3 WorldView                    : TEXCOORD4,
                                        float3 LightColor,
                                        out float3 DiffuseContrib,
                                        out float3 SpecularContrib                             ) 
{
    float3 Ln = normalize ( LightVec.xyz );
    float3 Nn = normalize ( WorldNormal ); 
    float3 Vn = normalize ( WorldView );
    float3 Hn = normalize ( Vn + Ln );
    float4 litV = lit(dot(Nn,Ln),dot(Nn,Hn),SpecularExponent);
    
    DiffuseContrib = litV.y * Kd * LightColor + LightAmbient;
    SpecularContrib = litV.z * Ks * LightColor;
           
}

float4 PS_NonSkinningWorldSpace ( VS_OUTPUT i ) : COLOR0
{

    float3 diffContrib0, diffContrib1;
    float3 specContrib0, specContrib1;
    
    float3 Col0 = ( LightIntensity / dot ( i.LightVec0.xyz, i.LightVec0.xyz ) ) * LightDiffuse0;
   
    PS_Plastic_Shared ( i.Pos, i.Tex, i.LightVec0, i.WorldNormal, i.WorldTangent, i.WorldView, Col0, diffContrib0, specContrib0 );

    float3 Col1 = ( LightIntensity / dot ( i.LightVec1.xyz, i.LightVec1.xyz ) ) * LightDiffuse1;
    
    PS_Plastic_Shared ( i.Pos, i.Tex, i.LightVec1, i.WorldNormal, i.WorldTangent, i.WorldView, Col1, diffContrib1, specContrib1 );
    
    float3 map = tex2D ( g_samDiffuse, i.Tex );
    float3 result;
    result = saturate ( specContrib0 + ( map * diffContrib0 ) +
             specContrib1 + ( map * diffContrib1 ) );
   
    return float4 ( result, 1.0f );


}

float4 PS_NonSkinningWorldSpaceTransparency ( VS_OUTPUT i ) : COLOR0
{
   

    float3 diffContrib0, diffContrib1;
    float3 specContrib0, specContrib1;
    
    float3 Col0 = ( LightIntensity / dot ( i.LightVec0.xyz, i.LightVec0.xyz ) ) * LightDiffuse0;
   
    PS_Plastic_Shared ( i.Pos, i.Tex, i.LightVec0, i.WorldNormal, i.WorldTangent, i.WorldView, Col0, diffContrib0, specContrib0 );

    float3 Col1 = ( LightIntensity / dot ( i.LightVec1.xyz, i.LightVec1.xyz ) ) * LightDiffuse1;
    
    PS_Plastic_Shared ( i.Pos, i.Tex, i.LightVec1, i.WorldNormal, i.WorldTangent, i.WorldView, Col1, diffContrib1, specContrib1 );
    
    float4 map = tex2D ( g_samDiffuse, i.Tex );
    float3 result = saturate ( specContrib0 + ( map * diffContrib0 ) +
                 specContrib1 + ( map * diffContrib1 ) );

    return float4 ( result, map.a );


}


//--------------------------------------------------------------------------------------
// Techniques
//--------------------------------------------------------------------------------------
technique NonSkinningDiffuse20
{
    pass p0
    {
        CullMode = None;
        AlphaBlendEnable = false;
        //ZEnable = true;
        VertexShader = compile vs_2_0 VS_NonSkinningWorldSpace();
        PixelShader = compile ps_2_0 PS_NonSkinningWorldSpace();
    }

    pass p1
    {
        CullMode = None;
        AlphaBlendEnable = true;
        //ZEnable = true;
        VertexShader = compile vs_2_0 VS_NonSkinningWorldSpace();
        PixelShader = compile ps_2_0 PS_NonSkinningWorldSpaceTransparency();
    }
}

technique NonSkinning20
{
    pass p0
    {
        CullMode = None;
//        ZEnable = true;
        AlphaBlendEnable = false;
        VertexShader = compile vs_2_0 VS_NonSkinningWorldSpace();
        PixelShader = compile ps_2_0 PS_NonSkinningWorldSpace();
    }

    pass p1
    {
        CullMode = None;
        //ZEnable = true;
        AlphaBlendEnable = false;
        VertexShader = compile vs_2_0 VS_NonSkinningWorldSpace();
        PixelShader = compile ps_2_0 PS_NonSkinningWorldSpaceTransparency();
    }

}
