/*
phong specular and blinn specular
both use the same vs, which output 
	projectiong pos, 
	object space normal
	object space lightDir
	object space viewDir
	
phongPS:

		R       = (2 * dotNL * N) ¨C L
	Specular	= pow (dotRV, [how shiny])	

blinn:
		H 		= ( L + V )
	Specular	= pow (dotNH, [how shiny])
	
	
where

	R : specular reflection vector;
	N : vertex normal vector;
	L : light direction vector; 
	V : view direction
	H : half way vectory of L and V
	
	dotNL : dot(N, L)
	dotRV: dot(R, V)
	dotNH: dot(n, H)
	
	
	    
Attenuation:

	Luminosity = 1 / Attenuation 
    Attenuation = Constant + Linear * Distance + Quadratic * Distance ^ 2 
	attenRange = distance (when attenuation = 0), which means fully black, 
	
*/

float4x4 gWorldViewProj: WORLDVIEWPROJECTION;
float4 gLightPosObj;
float4 gCameraPosObj;

float4 gAmbient: COLOR;
float4 gDiffuse: COLOR;
float4 gSpecular: COLOR;

float   gSpecShine;


struct VsInput
{
	float4 pos    	: POSITION;
	float3 normal	: NORMAL;
};
 
struct VsOutput
{
	float4 pos		: POSITION;
	float3 normal	: TEXCOORD0;
	float3 lightDir	: TEXCOORD1;
	float3 viewDir 	: TEXCOORD2;
};
 
 //ps only accept color and texcoord, so we will set senmantic to texcoord
 //ps will help up imterpolate them
struct PixelIn
{	
	float3 normal	: TEXCOORD0;
	float3 lightDir	: TEXCOORD1; 
	float3 viewDir	: TEXCOORD2;
};
 

float4 phongPS(PixelIn input) : COLOR0
{
	input.lightDir	= normalize( input.lightDir );
	input.viewDir	= normalize( input.viewDir );
	input.normal 	= normalize(input.normal);
	
	float 	dotNL 	= dot ( input.lightDir, input.normal );
	float 	diff 	= saturate(dotNL);
	//as long as L and N is normalized, ref will be normalized, it's just a reflection
	float3 	ref 	= (input.normal * 2 * dotNL) - input.lightDir;
	float	dotRV	= dot(ref, input.viewDir);
	float 	spec	= pow(saturate(dotRV), gSpecShine);
 
	return gAmbient + diff * gDiffuse +  spec * gSpecular ;

}


float4 blinnPS( PixelIn input ) : COLOR
{
	input.lightDir	= normalize( input.lightDir );
	input.viewDir	= normalize( input.viewDir );
	input.normal 	= normalize( input.normal );
 
	float 	dotNL 	= dot ( input.lightDir, input.normal );
 
	float 	diff 	= saturate(dotNL);
	//need to normalize
	float3 	halfway	= normalize(input.viewDir + input.lightDir);
	float 	dotNH	= dot(halfway, input.normal);
	float  	spec 	= pow(saturate(dotNH), gSpecShine);
 
	return gAmbient + diff * gDiffuse +  spec * gSpecular ;
}


//instead of transform vertex pos and normal into world coor,
//it's easier to just transfrom one light position

VsOutput specularVS( VsInput input)
{
	VsOutput output= (VsOutput)0;
 
	output.pos = mul(gWorldViewProj, input.pos);
	output.normal 	= input.normal;
	
	output.lightDir	= gLightPosObj - input.pos;
	output.viewDir	= gCameraPosObj - input.pos;
 
	return output;
}




