#define USE_FXAA_ON_SPRITES
float2 ViewSize : ViewSize; //not enabled in this shader?

// constant buffer for rendering
cbuffer cbPerFrame : register( b0 )
{
   float4x4 World;
   float4x4 View;
   float4x4 Projection;
};
cbuffer cbPerMeshPS : register( b1 )
{
   float4 MaterialEmissive;
   float fAlphaOverride;
   float fRes1;
   float fRes2;
   float fRes3;
   float4x4 ViewInv;
   float4x4 ViewProjectionMatrix;
   float4x4 PreviousViewProjectionMatrix;
};
//float alphaoverride  : alphaoverride;

Texture2D DiffuseMap : register( t0 );

SamplerState SampleWrap
{
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Wrap;
    AddressV = Wrap;
};

struct appdata 
{
    float4 Position   : POSITION;
    uint Color      : COLOR0;
    float2 UV      : TEXCOORD0;    
};

struct vertexOutput
{
    float4 Position : POSITION;
    float4 Color   : TEXCOORD0;
    float2 UV       : TEXCOORD1; 
};

vertexOutput mainVS(appdata IN)   
{
    vertexOutput OUT;
    OUT.Position = mul(IN.Position, Projection);   
    OUT.Color = float4(0,0,0,0);
   OUT.Color.x = float((IN.Color & 0x00FF0000)>>16) / 255;
   OUT.Color.y = float((IN.Color & 0x0000FF00)>>8) / 255;
   OUT.Color.z = float((IN.Color & 0x000000FF)) / 255;
   OUT.Color.w = float((IN.Color & 0xFF000000)>>24) / 255;
    OUT.UV = IN.UV;
    return OUT;
}

#ifdef USE_FXAA_ON_SPRITES
//@https://www.opengl.org/discussion_boards/showthread.php/184192-GLSL-FXAA-rendering-off-screen
#define FXAA_REDUCE_MIN (1.0/128.0)
#define FXAA_REDUCE_MUL (1.0/8.0)
#define FXAA_SPAN_MAX 8.0

float4 fxaa(uniform texture2D sampler0,float2 fcoords, float4 curcolor )
{
   //float2 resolution = ViewSize;
   float2 resolution = float2(1920.0,1080.0); // ViewSize //engine change required to pass this into shader
   float3 rgbNW = sampler0.Sample(SampleWrap, (fcoords.xy + (float2(-1.0,-1.0)/resolution)) ).xyz;
   float3 rgbNE = sampler0.Sample(SampleWrap, (fcoords.xy + (float2(1.0,-1.0)/resolution)) ).xyz;
   float3 rgbSW = sampler0.Sample(SampleWrap, (fcoords.xy + (float2(-1.0,1.0)/resolution)) ).xyz;
   float3 rgbSE = sampler0.Sample(SampleWrap, (fcoords.xy + (float2(1.0,1.0)/resolution)) ).xyz;
   float3 rgbM  = curcolor.xyz;
 
   float3 luma = float3(0.299, 0.587, 0.114);
   float lumaNW = dot(rgbNW, luma);
   float lumaNE = dot(rgbNE, luma);
   float lumaSW = dot(rgbSW, luma);
   float lumaSE = dot(rgbSE, luma);
   float lumaM  = dot(rgbM,  luma);
   float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
   float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); 
   float2 dir;
   dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
   dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
   float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),FXAA_REDUCE_MIN);
   float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
   dir = min(float2( FXAA_SPAN_MAX,  FXAA_SPAN_MAX),max(float2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),dir * rcpDirMin)) / resolution;
   float3 rgbA = 0.5 * (sampler0.Sample(SampleWrap,   fcoords.xy  + dir * (1.0/3.0 - 0.5)).xyz + sampler0.Sample(SampleWrap,   fcoords.xy  + dir * (2.0/3.0 - 0.5)).xyz);
   float3 rgbB = rgbA * 0.5 + 0.25 * (sampler0.Sample(SampleWrap,  fcoords.xy  + dir *  - 0.5).xyz + sampler0.Sample(SampleWrap,  fcoords.xy + dir * 0.5).xyz);
   float lumaB = dot(rgbB, luma);
   float3 ori;
   if((lumaB < lumaMin) || (lumaB > lumaMax)) {
      ori = rgbA;
   } else {
      ori=rgbB;
   }

   return float4(ori,curcolor.a);
}

#endif


float4 mainPS(vertexOutput IN) : COLOR
{
   #ifdef USE_FXAA_ON_SPRITES
		float4 ScreenMap = DiffuseMap.Sample(SampleWrap,IN.UV);
		float2 texCoord = IN.UV;
		float4 fxaatex = fxaa( DiffuseMap , texCoord , ScreenMap );
		float4 result = fxaatex * IN.Color;
		return result;
   #else
		float4 result = DiffuseMap.Sample(SampleWrap,IN.UV) * IN.Color;
		return result;
   #endif
}

technique11 Main2D
{
    pass MainPass
    {
        SetVertexShader(CompileShader(vs_5_0, mainVS()));
        SetPixelShader(CompileShader(ps_5_0, mainPS()));
        SetGeometryShader(NULL);
    }
}
