//
// Basic Shading Effect File
//

float4 MaterialAmbient : MATERIALAMBIENT = {0.1f, 0.1f, 0.1f, 1.0f};
float4 MaterialDiffuse : MATERIALDIFFUSE = {0.8f, 0.8f, 0.8f, 1.0f};
float4 MaterialSpecular : MATERIALSPECULAR = {1.0f, 1.0f, 1.0f, 7.0f};
float4x3 TransformMatrix;
float4x4 ProjectionMatrix;

// light information
vector LightVector;
vector LightPos;
vector EyePos;
float4 LightColor;


///////////////////////////////////////////////////////
struct VS_INPUT
{
    float3  Pos             : POSITION;
    float3  Normal          : NORMAL;
    float2  Tex0            : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4  Pos     : POSITION;
    float4  Diffuse  : COLOR0;
    float4  Specular : COLOR1;
    float2  Tex0    : TEXCOORD0;
};

// Vertex Shader
VS_OUTPUT VShade(VS_INPUT i)
{
	VS_OUTPUT   o;
	
	// perform transformation
	float3 P = mul(float4(i.Pos, 1), (float4x3)TransformMatrix);
	o.Pos  = mul(float4(P, 1), ProjectionMatrix);
	i.Normal = normalize(i.Normal);
	
	// perform lighting
    // do shading - Oren-Nayar shading
    vector VertexToEye = normalize(EyePos - float4(i.Pos, 1));
    float VdotN = dot(VertexToEye, i.Normal);
	float LdotN = dot(LightVector, i.Normal);
	float Irradiance = max(0.0f, LdotN);
	
	float AngleViewNormal = acos(VdotN);
	float AngleLightNormal = acos(LdotN);
	float AngleDifference = max (0.0f, dot(normalize(VertexToEye - i.Normal * VdotN), normalize(LightVector - i.Normal * LdotN)));
	float Alpha = max(AngleViewNormal, AngleLightNormal);
	float Beta = min(AngleViewNormal, AngleLightNormal);
	
	float RoughnessSquared = 0.5f;
	float A = 1.0f - (0.5f * RoughnessSquared) / (RoughnessSquared + 0.33f);
	float B = (0.45f * RoughnessSquared) / (RoughnessSquared + 0.09f);
	
	o.Diffuse = LightColor * MaterialDiffuse * (A + B * AngleDifference * sin(Alpha) * tan(Beta)) * Irradiance;
	o.Specular = 0.0;
	
	// copy texture coord
    o.Tex0  = i.Tex0;
	
	return o;
}


//////////////////////////////////////
// Techniques specs follow
//////////////////////////////////////
technique t0
{
    pass p0
    {
        VertexShader = compile vs_2_0 VShade();
    }
}