
// Shader output, position and diffuse color
struct VS_OUTPUT
{
    float4 pos  : POSITION;
    float4 diff : COLOR0;
    float2 Txcoord0 : TEXCOORD0;
    float fog : FOG;
};

// The world view and projection matrices
float4x4 World: WORLD;
float4x4 View: VIEW;
float4x4 Proj:PROJ;

float4 EyeLocation;

float4 LightDir0;
float4 LightDir1;

float4 LightColor0;
float4 LightColor1;

float4 DiffuseColor;
float4 SpecularColor;
float SpecularPower;
float4 AmbientColor;

float Radius;
float CurvRate;
float SwingAngle;
float SpreadRate;
float MaxZ;
float MinZ;
float BlurAllRate;
float BlurWidthRate;
float BlurRadiusRate;

float GlowSize;


VS_OUTPUT BladeBlur(float4 Pos  : POSITION, float3 Normal : NORMAL0, float2 Txcoord0 : TEXCOORD0)
{
    // Declare our return variable
    VS_OUTPUT Out = (VS_OUTPUT)0;

    // Transform our position
    float4 p = Pos;     
    float rLen = sqrt(Pos.x*Pos.x + Pos.z*Pos.z);
    float offSetAngle = asin(Pos.z/rLen);
    float radiusRate = rLen/Radius;
    offSetAngle += SpreadRate*offSetAngle*radiusRate;
    offSetAngle += SwingAngle*radiusRate;
    p.x = rLen*cos(offSetAngle);
    p.z = rLen*sin(offSetAngle);
    

    
    float dr = (rLen - Radius/8.0f)/Radius;
    if(dr > 0)
    {
	   p.y -= CurvRate*dr*dr*Radius;
    }

    float3 wNormal = normalize(mul(Normal, World));
 
    float4 wPos = mul(p, World);
    
    p = mul(wPos, View);
    p = mul(p, Proj);  
    Out.pos = p;
    Out.Txcoord0 = Txcoord0;
    
    
    //Set our color
    float3 eyeDir = normalize(EyeLocation - wPos);    
    
    // 1st light
    float diffuse0 = dot(wNormal, LightDir0);  
	float4 diffuseColor0 = LightColor0*max(diffuse0, 0);    
   
    float4 specular0 = 0.0f;
    if(diffuse0 > 0.0f)
    {
		float3 reflection0 = normalize(2*diffuse0*wNormal - LightDir0);
		float baseSpecular = dot(reflection0, eyeDir);
		if(baseSpecular > 0.0f)
			specular0 = pow(baseSpecular, SpecularPower);
    }
	float4 specularColor0 = specular0;


    
    // 2nd light  
    float diffuse1 = dot(wNormal, LightDir1);
	float4 diffuseColor1 = LightColor1*max(diffuse1, 0);    
    
    float4 specular1 = 0.0f;
    if(diffuse1 > 0.0f)
    {
		float3 reflection1 = normalize(2*diffuse1*wNormal - LightDir1);
		float baseSpecular = dot(reflection1, eyeDir);
		if(baseSpecular > 0.0f)		
			specular1 = pow(baseSpecular, SpecularPower);
    }
	float4 specularColor1 = specular1;

       
       
    //    
    float4 specularColorSum = specularColor0;
    float4 diffuseColorSum = diffuseColor0 + diffuseColor1;
	Out.diff = AmbientColor + DiffuseColor*diffuseColorSum + SpecularColor*specularColorSum;		


	////
	float wRate;
	if(Pos.z > 0)
		wRate = Pos.z/MaxZ;
	else
		wRate = Pos.z/MinZ;
		
	float radiusAlphaEffect = (1.0f - BlurRadiusRate*Pos.x/Radius);
	Out.diff.a = (1.0f - wRate*wRate*BlurWidthRate - BlurAllRate)*pow(radiusAlphaEffect, 3)*DiffuseColor.a;  
	
	//fog
	Out.fog = 1.0f;  

    // Return
    return Out;
}


VS_OUTPUT BladeGlow(float4 Pos  : POSITION, float3 Normal : NORMAL0)
{
    // Declare our return variable
    VS_OUTPUT Out = (VS_OUTPUT)0;

    // Transform our position
    float4 p = Pos;     
    float rLen = sqrt(Pos.x*Pos.x + Pos.z*Pos.z);
    float offSetAngle = asin(Pos.z/rLen);
    float radiusRate = rLen/Radius;
    offSetAngle += SpreadRate*offSetAngle*radiusRate;
    offSetAngle += SwingAngle*radiusRate;
    p.x = rLen*cos(offSetAngle);
    p.z = rLen*sin(offSetAngle);
    

    
    float dr = (rLen - Radius/8.0f)/Radius;
    if(dr > 0)
    {
	   p.y -= CurvRate*dr*dr*Radius;
    }

    float3 wNormal = normalize(mul(Normal, World));
 
    float3 wPos = mul(p, World);
    wPos += wNormal*GlowSize;
    
    float4 posOut = mul(float4(wPos.xyz, 1.0f), View);
    posOut = mul(posOut, Proj);  
    Out.pos = posOut;
    		
	Out.diff = DiffuseColor;
		
	float wRate;
	if(Pos.z > 0)
		wRate = Pos.z/MaxZ;
	else
		wRate = Pos.z/MinZ;
		
	float radiusAlphaEffect = (1.0f - BlurRadiusRate*Pos.x/Radius);
	Out.diff.a = (1.0f - wRate*wRate*BlurWidthRate - BlurAllRate)*pow(radiusAlphaEffect, 3)*DiffuseColor.a;  
	
	//fog
	Out.fog = 1.0f;  

    // Return
    return Out;
}


technique BladeBlur
{
    pass P0
    {    
        FogEnable = True;
        // shaders
        VertexShader = compile vs_1_1 BladeBlur();
        PixelShader  = NULL;
    }
}


technique BladeGlow
{
    pass P0
    {    
        FogEnable = True;
        // shaders
        VertexShader = compile vs_1_1 BladeGlow();
        PixelShader  = NULL;
    }
}

