0% found this document useful (0 votes)
20 views11 pages

FXAA Shader Code for Image Processing

The document contains shader code for post-processing effects in graphics rendering, specifically implementing FXAA (Fast Approximate Anti-Aliasing) techniques. It includes configurations for blurring, sharpening, and noise effects, along with various parameters for sampling and texture manipulation. The code is structured with defined variables, functions for vertex and pixel shading, and conditional compilation for different effects based on user-defined macros.

Uploaded by

spideyboy7777
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views11 pages

FXAA Shader Code for Image Processing

The document contains shader code for post-processing effects in graphics rendering, specifically implementing FXAA (Fast Approximate Anti-Aliasing) techniques. It includes configurations for blurring, sharpening, and noise effects, along with various parameters for sampling and texture manipulation. The code is structured with defined variables, functions for vertex and pixel shading, and conditional compilation for different effects based on user-defined macros.

Uploaded by

spideyboy7777
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

// FXAA converted by Myster92. Thanks to him.

// All of the rest is from Boris Vorontsov :)


// And mixed by me
// Edited by H1Vltg3
//
//enable blurring, useless, disabled at all
#define EBLURRING

//enable sharpening
#define ESHARPENING

//if defined, color sharpen, otherwise sharp by gray


//#define ESHARPENINGCOLOR

//enable noise in dark areas


#define ENOISE

float ShiftSamplingRange=0.28;
float SamplingRange=0.0128; //sharpening or blurring range
float SharpeningAmount=128;
float ScanLineAmount=1.0;
float ScanLineRepeat=1.0;
float NoiseAmount=0.15;

//keyboard controled variables


float tempF1;
float tempF2;
float tempF3;
float tempF4;
float tempF5;
float tempF6;
float tempF7;
float tempF8;
float tempF9;
float tempF0;

//global variables, already set before executing this code


float ScreenSize; //width of the display resolution (1920 f.e.)
float ScreenScaleY; //screen proportions (1.333 for 1920/1080)

//textures
texture2D texColor;
texture2D texNoise;

sampler2D SamplerColor = sampler_state


{
Texture = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;//NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerNoise = sampler_state
{
Texture = <texNoise>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;//NONE;
AddressU = Wrap;
AddressV = Wrap;
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([Link].x,[Link].y,[Link].z,1.0);

[Link]=pos;
[Link]=[Link];

return OUT;
}

/*============================================================================
FXAA3 QUALITY - PC
NVIDIA FXAA III.8 by TIMOTHY LOTTES
============================================================================*/

#define FXAA_LINEAR 0
#define FXAA_QUALITY__EDGE_THRESHOLD (1.0/16.0)
#define FXAA_QUALITY__EDGE_THRESHOLD_MIN (1.0/16.0)
#define FXAA_QUALITY__SUBPIX_CAP (3.0/4.0)
#define FXAA_QUALITY__SUBPIX_TRIM (1.0/4.0)
#define FXAA_QUALITY__SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_QUALITY__SUBPIX_TRIM))
#define FXAA_SEARCH_STEPS 8
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)

float4 FxaaPixelShader(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR


{

#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))


#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
float2 pos = [Link];

float2 rcpFrame = float2(1/ScreenSize, ScreenScaleY/ScreenSize);


float4 rcpFrameOpt = float4(2/ScreenSize, 2*ScreenScaleY/ScreenSize,
0.5/ScreenSize, 0.5*ScreenScaleY/ScreenSize);

float lumaN = dot(FxaaTexOff(SamplerColor, [Link], float2(0, -1), [Link]).xyz,


float3(0.299, 0.587, 0.114));
float lumaW = dot(FxaaTexOff(SamplerColor, [Link], float2(-1, 0), [Link]).xyz,
float3(0.299, 0.587, 0.114));

float4 rgbyM;
[Link] = FxaaTexTop(SamplerColor, [Link]).xyz;
rgbyM.w = dot([Link], float3(0.299, 0.587, 0.114));
float lumaE = dot(FxaaTexOff(SamplerColor, [Link], float2( 1, 0), [Link]).xyz,
float3(0.299, 0.587, 0.114));
float lumaS = dot(FxaaTexOff(SamplerColor, [Link], float2( 0, 1), [Link]).xyz,
float3(0.299, 0.587, 0.114));
float lumaM = rgbyM.w;

float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));


float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
float range = rangeMax - rangeMin;

if(range < max(FXAA_QUALITY__EDGE_THRESHOLD_MIN, rangeMax *


FXAA_QUALITY__EDGE_THRESHOLD)) return rgbyM;

float lumaNW = dot(FxaaTexOff(SamplerColor, [Link], float2(-1,-1),


[Link]).xyz, float3(0.299, 0.587, 0.114));
float lumaNE = dot(FxaaTexOff(SamplerColor, [Link], float2( 1,-1),
[Link]).xyz, float3(0.299, 0.587, 0.114));
float lumaSW = dot(FxaaTexOff(SamplerColor, [Link], float2(-1, 1),
[Link]).xyz, float3(0.299, 0.587, 0.114));
float lumaSE = dot(FxaaTexOff(SamplerColor, [Link], float2( 1, 1),
[Link]).xyz, float3(0.299, 0.587, 0.114));

float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;


float rangeL = abs(lumaL - lumaM);
float blendL = saturate((rangeL / range) - FXAA_QUALITY__SUBPIX_TRIM) *
FXAA_QUALITY__SUBPIX_TRIM_SCALE;
blendL = min(FXAA_QUALITY__SUBPIX_CAP, blendL);

float edgeVert = abs(lumaNW + (-2.0 * lumaN) + lumaNE) + 2.0 * abs(lumaW + (-2.0 *


lumaM) + lumaE ) + abs(lumaSW + (-2.0 * lumaS) + lumaSE);
float edgeHorz = abs(lumaNW + (-2.0 * lumaW) + lumaSW) + 2.0 * abs(lumaN +
(-2.0 * lumaM) + lumaS ) + abs(lumaNE + (-2.0 * lumaE) + lumaSE);
bool horzSpan = edgeHorz >= edgeVert;

float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;


if(!horzSpan) lumaN = lumaW;
if(!horzSpan) lumaS = lumaE;
float gradientN = abs(lumaN - lumaM);
float gradientS = abs(lumaS - lumaM);
lumaN = (lumaN + lumaM) * 0.5;
lumaS = (lumaS + lumaM) * 0.5;

bool pairN = gradientN >= gradientS;


if(!pairN) lumaN = lumaS;
if(!pairN) gradientN = gradientS;
if(!pairN) lengthSign *= -1.0;
float2 posN;
posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);

gradientN *= FXAA_SEARCH_THRESHOLD;

float2 posP = posN;


float2 offNP = horzSpan ?
float2(rcpFrame.x, 0.0) :
float2(0.0f, rcpFrame.y);
float lumaEndN;
float lumaEndP;
bool doneN = false;
bool doneP = false;
posN += offNP * (-1.5);
posP += offNP * ( 1.5);
for(int i = 0; i < FXAA_SEARCH_STEPS; i++)
{
lumaEndN = dot(FxaaTexTop(SamplerColor, [Link]).xyz, float3(0.299, 0.587,
0.114));
lumaEndP = dot(FxaaTexTop(SamplerColor, [Link]).xyz, float3(0.299, 0.587,
0.114));
bool doneN2 = abs(lumaEndN - lumaN) >= gradientN;
bool doneP2 = abs(lumaEndP - lumaN) >= gradientN;
if(doneN2 && !doneN) posN += offNP;
if(doneP2 && !doneP) posP -= offNP;
if(doneN2 && doneP2) break;
doneN = doneN2;
doneP = doneP2;
if(!doneN) posN -= offNP * 2.0;
if(!doneP) posP += offNP * 2.0;
}

float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;


float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;

bool directionN = dstN < dstP;


lumaEndN = directionN ? lumaEndN : lumaEndP;

if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))


lengthSign = 0.0;

float spanLength = (dstP + dstN);


dstN = directionN ? dstN : dstP;
float subPixelOffset = 0.5 + (dstN * (-1.0/spanLength));
subPixelOffset += blendL * (1.0/8.0);
subPixelOffset *= lengthSign;
float3 rgbF = FxaaTexTop(SamplerColor, float2(pos.x + (horzSpan ? 0.0 :
subPixelOffset), pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;

#if (FXAA_LINEAR == 1)
lumaL *= lumaL;
#endif
float lumaF = dot(rgbF, float3(0.299, 0.587, 0.114)) + (1.0/(65536.0*256.0));
float lumaB = lerp(lumaF, lumaL, blendL);
float scale = min(4.0, lumaB/lumaF);
rgbF *= scale;

return float4(rgbF, lumaM);


}

float4 PS_PostProcess5(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR


{
float4 res;
float4 coord=0.0;

[Link]=[Link];
float4 origcolor;

coord.w=0.0;

origcolor=tex2Dlod(SamplerColor, coord);

// coord.x=[Link].x-(1.5/ScreenSize);
// float4 lshift=tex2Dlod(SamplerColor, coord);
// coord.x=[Link].x+(1.5/ScreenSize);
// float4 rshift=tex2Dlod(SamplerColor, coord);

float2 offset[8]=
{
float2(1.0, 1.0),
float2(-1.0, -1.0),
float2(-1.0, 1.0),
float2(1.0, -1.0),

float2(1.41, 0.0),
float2(-1.41, 0.0),
float2(0.0, 1.41),
float2(0.0, -1.41)
};
int i=0;

float4 tcol=origcolor;
float invscreensize=1.0/ScreenSize;
//for (i=0; i<8; i++) //higher quality
for (i=0; i<8; i++)
{
float2 tdir=offset[i].xy;
[Link]=[Link]+[Link]*invscreensize*SamplingRange;//*1.0;
float4 ct=tex2Dlod(SamplerColor, coord);

tcol+=ct;
}
tcol*=0.111; // 1.0/(4+1)
//tcol*=0.111; // 1.0/(8+1) //higher quality

/*
//not interesting
#ifdef EBLURRING
//blur
res=tcol;
#endif
*/

//sharp
#ifdef ESHARPENING

#ifdef ESHARPENINGCOLOR
//color
res=origcolor*(1.0+((origcolor-tcol)*SharpeningAmount));
#else
//non color
float difffact=dot(([Link]), 0.333);
res=origcolor*(1.0+difffact*SharpeningAmount);
#endif

//less sharpening for bright pixels


float rgray=origcolor.z; //blue fit well
//float rgray=max(origcolor.x, max(origcolor.y, origcolor.z));
rgray=pow(rgray, 3.0);
res=lerp(res, origcolor, saturate(rgray));

#endif

//grain noise
#ifdef ENOISE
float origgray=max(res.x, res.y);//dot([Link], 0.333);
origgray=max(origgray, res.z);
[Link]=[Link]*16.0 + origgray;
float4 cnoi=tex2Dlod(SamplerNoise, coord);
res=lerp(res, (cnoi.x+0.5)*res, NoiseAmount*saturate(1.0-origgray*1.8));
#endif

res.w=1.0;
return res;
}

float4 PS_Process6(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR


{
float4 res;
float4 coord=0.0;

[Link]=[Link];
float4 origcolor;

coord.w=0.0;

origcolor=tex2Dlod(SamplerColor, coord);

// coord.x=[Link].x-(1.5/ScreenSize);
// float4 lshift=tex2Dlod(SamplerColor, coord);
// coord.x=[Link].x+(1.5/ScreenSize);
// float4 rshift=tex2Dlod(SamplerColor, coord);

float2 offset[8]=
{
float2(1.0, 1.0),
float2(-1.0, -1.0),
float2(-1.0, 1.0),
float2(1.0, -1.0),

float2(1.41, 0.0),
float2(-1.41, 0.0),
float2(0.0, 1.41),
float2(0.0, -1.41)
};
int i=0;

float4 tcol=origcolor;
float2 invscreensize=1.0/ScreenSize;
invscreensize.y=invscreensize.y/ScreenScaleY;
//for (i=0; i<8; i++) //higher quality
/* for (i=0; i<4; i++)
{
float2 tdir=offset[i].xy;
[Link]=[Link]+[Link]*invscreensize*SamplingRange;//*1.0;
float4 ct=tex2Dlod(SamplerColor, coord);

tcol+=ct;
}
tcol*=0.2; // 1.0/(4+1)
//tcol*=0.111; // 1.0/(8+1) //higher quality
*/

[Link]=[Link];
origcolor=tex2Dlod(SamplerColor, coord);
res.y=origcolor.y;

[Link]=[Link];
coord.y-=invscreensize*ShiftSamplingRange;
origcolor=tex2Dlod(SamplerColor, coord);
res.x=origcolor.x;

[Link]=[Link];
coord.y+=invscreensize*ShiftSamplingRange;
origcolor=tex2Dlod(SamplerColor, coord);
res.z=origcolor.z;

res.w=1.0;
return res;
}

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

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

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

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

technique PostProcess3
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 FxaaPixelShader();

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

technique PostProcess4
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 FxaaPixelShader();

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

technique PostProcess5
{
pass P0
{

VertexShader = compile vs_3_0 VS_PostProcess();


PixelShader = compile ps_3_0 PS_PostProcess5();

DitherEnable=Enable;
ZEnable=Enable;
CullMode=NONE;
ALPHATESTENABLE=Enable;
SEPARATEALPHABLENDENABLE=Enable;
AlphaBlendEnable=Enable;
StencilEnable=Enable;
FogEnable=Enable;
SRGBWRITEENABLE=Enable;
}
}
technique PostProcess6
{
pass P0
{

VertexShader = compile vs_3_0 VS_PostProcess();


PixelShader = compile ps_3_0 PS_Process6();

DitherEnable=Enable;
ZEnable=Enable;
CullMode=Enable;
ALPHATESTENABLE=Enable;
SEPARATEALPHABLENDENABLE=Enable;
AlphaBlendEnable=Enable;
StencilEnable=Enable;
FogEnable=Enable;
SRGBWRITEENABLE=Enable;
}
}
// light position
float4 vLight;

// vertex transformations world


float4x4 mWorld;
// vertex transformation view/projection
float4x4 mViewProjection;

struct VS_OUTPUT
{
float4 Pos : POSITION;
float2 tc: TEXCOORD0;
float3 normal: TEXCOORD1;
float3 light: TEXCOORD2;
float3 view: TEXCOORD3;
};

VS_OUTPUT main(float3 Pos : POSITION0, float3 Normal: NORMAL2,


float2 tc: TEXCOORD0)
{
VS_OUTPUT Out;

// tranform vertex
float4 pos = mul(float4(Pos, 1), mWorld);
[Link] = mul(pos, mViewProjection);
[Link] = [Link] - [Link];
[Link] = float3(0, 0, 1);// наш вектор взгляда

float3 normal = mul(float4(Normal, 1), mWorld).xyz;


normal -= mul(float4(0,0,0, 1), mWorld).xyz;
[Link] = normal;

[Link] = tc;

return Out;
}
// vertex transformations world
float4x4 mWorld;
// vertex transformation view/projection
float4x4 mViewProjection;

struct VS_OUTPUT
{
float4 Pos : POSITION;
float4 Color: COLOR0;
};

VS_OUTPUT main(float3 Pos : POSITION0, float4 Color: COLOR0)


{
VS_OUTPUT Out;
// tranform vertex
float4 pos = mul(float4(Pos, 1), mWorld);
[Link] = mul(pos, mViewProjection);
[Link] = Color;
return Out;
}
// структура для хранения позиции и цвета вертекса
struct VertPosDiffuse
{
D3DXVECTOR4 m_pos;
D3DCOLOR m_color;
VertPosDiffuse(D3DXVECTOR4 pos, D3DCOLOR color)
: m_pos(pos), m_color(color)
{}
};
// три разноцветных вертекса = треугольник
VertPosDiffuse v[] =
{
VertPosDiffuse(D3DXVECTOR4( 0, 0, 0, 1), D3DCOLOR_XRGB(255, 0, 0)),
VertPosDiffuse(D3DXVECTOR4(400, 0, 0, 1), D3DCOLOR_XRGB(0, 0, 255)),
VertPosDiffuse(D3DXVECTOR4(400, 400, 0, 1), D3DCOLOR_XRGB(0, 255, 0))
};
m_pd3dDevice->BeginScene(); // начинаем рисовать
m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_STENCIL|
D3DCLEAR_ZBUFFER, 0x808080, 0, 0); // очистка экрана

// указываем формат данных


m_pd3dDevice->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE);
// рендерим треугольник
m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1/* 1 треугольник */,
v /* данные брать отсюда*/, sizeof(VertPosDiffuse)/*размер вертекса*/);
m_pd3dDevice->EndScene(); // закончили рендеринг сцены
m_pd3dDevice->Present(NULL, NULL, NULL, NULL); // копируем на экран

You might also like