//++++++++++++++++++++++++++++++++++++++++++++
// ENBSeries effect file
// visit http://enbdev.com for updates
// Copyright (c) 2007-2017 Boris Vorontsov
// Shader add-ons by RG2PS (c) 2026 MIT License
// Specifically for SA-VF ENB
//++++++++++++++++++++++++++++++++++++++++++++

float4	ScreenSize;
texture2D texColor;

sampler2D SamplerColor = sampler_state
{
    Texture   = <texColor>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = NONE;
    AddressU  = Clamp;
    AddressV  = Clamp;
    SRGBTexture=FALSE;
    MaxMipLevel=0;
    MipMapLodBias=0;
};

struct VS_OUTPUT_POST 
{
    float4 vpos  : POSITION;
    float2 txcoord : TEXCOORD0;
};

struct VS_INPUT_POST 
{
    float3 pos  : POSITION;
    float2 txcoord : TEXCOORD0;
};

VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
    VS_OUTPUT_POST OUT;

    float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);

    OUT.vpos=pos;
    OUT.txcoord.xy=IN.txcoord.xy;

    return OUT;
}

float4 PS_FXAA(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
    #define FXAA_SUBPIX_SHIFT (1.0/8.0)
    #define FXAA_REDUCE_MIN   (1.0/32.0)
    #define FXAA_REDUCE_MUL   (1.0/16.0)
    #define FXAA_SPAN_MAX     8.0

    half2 rcpFrame = half2(1/ScreenSize.x, 1/(ScreenSize.x/ScreenSize.z));

    half4 posPos;
    posPos.xy = IN.txcoord.xy;
    posPos.zw = posPos.xy - (rcpFrame.xy * (0.5 + FXAA_SUBPIX_SHIFT));

    half3 rgbNW = tex2D(SamplerColor, posPos.zw ).xyz;
    half3 rgbNE = tex2D(SamplerColor, posPos.zw + half2(rcpFrame.x, 0.0) ).xyz;
    half3 rgbSW = tex2D(SamplerColor, posPos.zw + half2(0.0, rcpFrame.y) ).xyz;
    half3 rgbSE = tex2D(SamplerColor, posPos.zw +rcpFrame.xy ).xyz;
    half3 rgbM  = tex2D(SamplerColor, posPos.xy).xyz;
       
    half3 luma = half3(0.299, 0.587, 0.114);
    half lumaNW = dot(rgbNW, luma);
    half lumaNE = dot(rgbNE, luma);
    half lumaSW = dot(rgbSW, luma);
    half lumaSE = dot(rgbSE, luma);
    half lumaM  = dot(rgbM,  luma);
       
    half lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
    half lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
       
    half2 dir; 
       
    half lumaNWNE = lumaNW + lumaNE;
    half lumaSWSE = lumaSW + lumaSE;
       
    dir.x = -((lumaNWNE) - (lumaSWSE));
    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
       
    half dirReduce = max( (lumaSWSE + lumaNWNE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
    half rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
    dir = min(half2( FXAA_SPAN_MAX,  FXAA_SPAN_MAX), max(half2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * rcpFrame.xy;
             
    half3 rgbA = (1.0/2.0) * (tex2D(SamplerColor, posPos.xy + dir * (1.0/3.0 - 0.5) ).xyz + tex2D(SamplerColor, posPos.xy + dir * (2.0/3.0 - 0.5) ).xyz);
    half3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (tex2D(SamplerColor, posPos.xy + dir * (0.0/3.0 - 0.5) ).xyz + tex2D(SamplerColor, posPos.xy + dir * (3.0/3.0 - 0.5)).xyz);
    half lumaB = dot(rgbB, luma);
       
    return ((lumaB < lumaMin) || (lumaB > lumaMax)) ? half4(rgbA, 1.0) : half4(rgbB, 1.0);
}

float4 PS_CAS(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
    float3 color = tex2D(SamplerColor, IN.txcoord).rgb;

    float2 pixelsize = float2(ScreenSize.y, ScreenSize.y * ScreenSize.z);

    float3 sum[9];

    float n = 0.0;
    float3 mean = 0.0;

    for (int i = -1; i <= 1; i++)
    for (int j = -1; j <= 1; j++) if (i != 0 || j != 0)
    {
	float2 pos = IN.txcoord + float2(i, j) * pixelsize;
	float3 k = tex2Dlod(SamplerColor, float4(pos, 0, 0)).rgb;
	sum[int(n)] = k;
	mean += k;
	n++;
    }

    mean /= n; 

    float3 sd = 0.0;
    for (int i = 0; i < n; i++) 
    {
	sd += abs(sum[i] - mean);
    }

    sd /= n;

    float weight = 1.0 - dot(sd, float3(0.2126729, 0.7151522, 0.072175));
    color = color * (1.0 + weight) - (sum[4] + sum[3] + sum[1] + sum[7] + (sum[6] + sum[5] + sum[0] + sum[2]) * 0.5) / 6.0 * weight;

    return float4(color, 1);
}

technique PostProcess
{
   pass P0
   {
	VertexShader = compile vs_3_0 VS_PostProcess();
	PixelShader  = compile ps_3_0 PS_FXAA();

	FogEnable=FALSE;
	ALPHATESTENABLE=FALSE;
	SEPARATEALPHABLENDENABLE=FALSE;
	AlphaBlendEnable=FALSE;
	FogEnable=FALSE;
	SRGBWRITEENABLE=FALSE;
   }
}

technique PostProcess2
{
   pass P0
   {
	VertexShader = compile vs_3_0 VS_PostProcess();
	PixelShader  = compile ps_3_0 PS_CAS();

	FogEnable=FALSE;
	ALPHATESTENABLE=FALSE;
	SEPARATEALPHABLENDENABLE=FALSE;
	AlphaBlendEnable=FALSE;
	FogEnable=FALSE;
	SRGBWRITEENABLE=FALSE;
   }
}