/////////////////////////////////////////////////////////////////////////////////////////////////////////////
float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 LightView;
float4x4 LightProjection;
static const float SHADOW_EPSILON = 0.0005f;
int SCREENWIDTH;
int SCREENHEIGHT;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
float g_fAlpha;
float3 EyePos;
float3 g_LightPos;
float3 g_LightColor;
float3 g_ShadowColor;
// ADJUST DEPTH OF BLUR //
float FocusFar;
float FocusNear;
float BlurMulti;
float XBlur;
float YBlur;
// CHARACTER FRAMES //
float FrameDivide;
int FrameX;
int FrameY;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct VertexOut
{
    float4 Pos      : POSITION;
    float3 Normal    : TEXCOORD0;
    float2 TexUV     : TEXCOORD1;
    float3 toEyeT    : TEXCOORD2;
    float3 lightDirT : TEXCOORD3;
    float3 toEyeL    : TEXCOORD4;
    float3 lightDirL : TEXCOORD5;
    float4 projtex   : TEXCOORD6;
    float2 Depth     : TEXCOORD7;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
texture g_MeshTexture;
sampler MeshTextureSampler = sampler_state
{
    Texture = <g_MeshTexture>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;
};
texture g_Input1;
sampler Input1Sampler = sampler_state
{
    Texture = <g_Input1>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = CLAMP;
    AddressV = CLAMP;
};
texture g_Input2;
sampler Input2Sampler = sampler_state
{
    Texture = <g_Input2>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = CLAMP;
    AddressV = CLAMP;
};
texture g_Ref1;
sampler Ref1Sampler = sampler_state
{
    Texture = <g_Ref1>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = CLAMP;
    AddressV = CLAMP;
};
texture g_Ref2;
sampler Ref2Sampler = sampler_state
{
    Texture = <g_Ref2>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = CLAMP;
    AddressV = CLAMP;
};
texture g_Light;
sampler LightSampler = sampler_state
{
    Texture = <g_Light>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;
};
texture g_ShadowMap;
sampler ShadowMapSampler = sampler_state
{
    Texture = <g_ShadowMap>;
    MinFilter = POINT;
    MagFilter = POINT;
    MipFilter = POINT;
    AddressU = CLAMP;
    AddressV = CLAMP;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
VertexOut StandardVS(float4 Pos : POSITION,      float3 Normal : NORMAL, float2 tex : TEXCOORD0,
		     float3 tangentL : TANGENT0, float3 binormalL : BINORMAL0)
{
	VertexOut Vert = (VertexOut)0;
	
	float4x4 Transform;
	Pos = mul(Pos, World);

	Normal = normalize(mul(Normal, World));
	tangentL = normalize(mul(tangentL,World));
	binormalL = normalize(mul(binormalL,World));

	Vert.Normal = Normal;
	Transform = mul(LightView, LightProjection);
	Vert.projtex = mul(Pos, Transform);		

	Transform = mul(View, Projection);
	Vert.Pos = mul(Pos, Transform);
        Vert.Depth = Vert.Pos.zw;
	tex.x /= FrameDivide;
	tex.y /= FrameDivide;
	tex.x += (1/FrameDivide) * FrameX;
	tex.y += (1/FrameDivide) * FrameY;
	Vert.TexUV = tex;

	float3x3 TBN;
	TBN[0] = tangentL;
	TBN[1] = binormalL;
	TBN[2] = Normal;
		
	float3x3 toTangentSpace = transpose(TBN);

	float3 toEyeL = normalize(EyePos - Pos);
	Vert.toEyeL = toEyeL * float3(1,-1,1);
	Vert.toEyeT = mul(toEyeL, toTangentSpace);
	float3 lightDirL = normalize(g_LightPos - Pos);
	Vert.lightDirL = lightDirL;
	Vert.lightDirT = normalize(mul(lightDirL, toTangentSpace));
	
	return Vert;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
float4 RGBEffectsPS(float3 normalW   : TEXCOORD0,
		float3 texuv     : TEXCOORD1,
		float3 toEyeT    : TEXCOORD2,
		float3 lightDirT : TEXCOORD3,
		float3 toEyeL    : TEXCOORD4,
		float3 lightDirL : TEXCOORD5,
		float4 ProjTex   : TEXCOORD6,
		float2 Depth     : TEXCOORD7) : COLOR
{
	// shadow projection //
	float2 ShadowTexC = 0.5 * (ProjTex.xy / ProjTex.w) + float2( 0.5, 0.5 );
	ShadowTexC.y = 1.0f - ShadowTexC.y;
	float2 texelpos = 1024 * ShadowTexC;
   	float s0 = (tex2D(ShadowMapSampler, ShadowTexC.xy).r + SHADOW_EPSILON < (ProjTex.z / ProjTex.w)) ? 0.0f : 1.0f;		
	
	// Depth //
	float DepthBlur = (Depth.x-FocusFar)/(Depth.y/2); 
	DepthBlur *= 1-((Depth.x-FocusNear)/(Depth.y/2)); 
	DepthBlur *= min(s0+0.5f,1);
	
	return float4(0,0,-DepthBlur,tex2D(MeshTextureSampler,texuv).a);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
float4 RBlurPS(float2 Tex : TEXCOORD0) : COLOR
{
	float Blur = tex2D(Input1Sampler,Tex).b * BlurMulti;
	float texelx = Blur / float(SCREENWIDTH);
	float texely = Blur / float(SCREENHEIGHT);
	float3 Color = tex2D(Ref1Sampler,Tex);
	float3 BlurSamp = Color;
	BlurSamp+= tex2D(Ref1Sampler,Tex + float2(0,texely));
	BlurSamp+= tex2D(Ref1Sampler,Tex + float2(0,-texely));
	BlurSamp+= tex2D(Ref1Sampler,Tex + float2(texelx,0));
	BlurSamp+= tex2D(Ref1Sampler,Tex + float2(-texelx,0));
	BlurSamp/=5;
	Color+=BlurSamp/6;
	
	//Color = min((Color/4),1);
	return float4(Color,1);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
float4 RBlur2PS(float2 Tex : TEXCOORD0) : COLOR
{
	float Blur = tex2D(Input2Sampler,Tex).b * BlurMulti;
	float texelx = Blur / float(SCREENWIDTH);
	float texely = Blur / float(SCREENHEIGHT);
	float3 Color = tex2D(Ref2Sampler,Tex);
	float3 BlurSamp = Color;
	BlurSamp+= tex2D(Ref2Sampler,Tex + float2(0,texely));
	BlurSamp+= tex2D(Ref2Sampler,Tex + float2(0,-texely));
	BlurSamp+= tex2D(Ref2Sampler,Tex + float2(texelx,0));
	BlurSamp+= tex2D(Ref2Sampler,Tex + float2(-texelx,0));
	BlurSamp/=5;
	Color+=BlurSamp/6;
	//Color = min((Color/4),1) + ((Color/4) * (g_LightColor*Blur))/12;
	//Color = min((Color/5),1);
	return float4(Color,1);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
technique RGBEffects
{  
   pass P0
   {
	PixelShader = compile ps_2_0 RGBEffectsPS();
        VertexShader = compile vs_2_0 StandardVS();
	AlphaTestEnable = true;
	AlphaRef = 100;
	AlphaFunc = GreaterEqual;
	CullMode = CCW;
   }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
technique RBlur
{  pass P0
   {
	PixelShader = compile ps_2_0 RBlurPS();
   }
pass P1
   {
	PixelShader = compile ps_2_0 RBlur2PS();
   }
}