Code: Select all
/**
* SHADER ADDON
* Featuring BlurShift, Sharpen, Noise, LumaSharpen, Vibrance, Contrast, Black Level
* Exterior/Interior separation ready, GUI-enabled
* By ZeroKing
*/
/**
* ENBSeries
* visit http://enbdev.com for updates
* Copyright (c) 2007-2014 Boris Vorontsov
*/
//--------------------------//
// Internal parameters //
// Can be modified //
//--------------------------//
//////////////////
// DEFINES //
//////////////////
#define ESHARPENING
#define ESHARPENINGCOLOR
#define ECOLORSHIFT
#define SharpMethod 4
#define NoiseMethod 0
// Set your resolution here
float2 fvTexelSize = float2(1.0 / 2400.0, 1.0 / 1350.0);
///////////////
// CHOICES //
///////////////
bool C_BLACKLEVEL <
string UIName = "Enable Black Level";
> = {false};
bool C_CONTRASTCURVES <
string UIName = "Enable Contrast";
> = {false};
bool C_VIBRANCE <
string UIName = "Enable Vibrance";
> = {false};
//////////////////////////////
// BLUR-SHIFT AND SHARPEN //
//////////////////////////////
#define BlurSamplingRange BlurRange
#define SharpSamplingRange SharpRange
#define SharpeningAmount SharpAmount
#define ShiftSamplingRange ShiftRange
float BlurRange <
string UIName="Blur Sampling Range";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0.5};
float SharpRange <
string UIName="Sharp Sampling Range";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0.5};
float SharpAmount <
string UIName="Sharpening Amount";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=5.0;
> = {1.0};
float ShiftRange <
string UIName="Shift Sampling Range";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0.5};
//////////////
// NOISE //
//////////////
float NoiseAmountExt <
string UIName="Noise Amount - Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0.0};
float NoiseAmountInt <
string UIName="Noise Amount - Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0.0};
float NoiseFinenessExt <
string UIName="Noise Fineness - Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=100.0;
> = {50};
float NoiseFinenessInt <
string UIName="Noise Fineness - Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=100.0;
> = {50};
//////////////////
// CONTRAST //
//////////////////
float ContrastCurveExt <
string UIName="Contrast - Exterior";
string UIWidget="Spinner";
float UIMin=-1.0;
float UIMax=1.0;
> = {0};
float ContrastCurveInt <
string UIName="Contrast - Interior";
string UIWidget="Spinner";
float UIMin=-1.0;
float UIMax=1.0;
> = {0};
//////////////////
// VIBRANCE //
//////////////////
float VibranceExt <
string UIName="Vibrance - Exterior";
string UIWidget="Spinner";
float UIMin=-1.0;
float UIMax=1.0;
> = {0};
float VibranceInt <
string UIName="Vibrance - Interior";
string UIWidget="Spinner";
float UIMin=-1.0;
float UIMax=1.0;
> = {0};
////////////////////
// LUMASHARPEN //
////////////////////
float sharp_strengthExt <
string UIName="LumaSharpen Strength - Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=5.0;
> = {0};
float sharp_strengthInt <
string UIName="LumaSharpen Strength - Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=5.0;
> = {0};
float sharp_clampExt <
string UIName="LumaSharpen Clamp - Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0};
float sharp_clampInt <
string UIName="LumaSharpen Clamp - Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0};
////////////////////
// BLACK LEVELS //
////////////////////
float BlackPointExt <
string UIName="Black Level - Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=255.0;
> = {16};
float BlackPointInt <
string UIName="Black Level - Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=255.0;
> = {16};
float WhitePointExt <
string UIName="White Level - Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=255.0;
> = {235};
float WhitePointInt <
string UIName="White Level - Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=255.0;
> = {235};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//--------------------------//
// External parameters //
// Do not modify //
//--------------------------//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Keyboard controlled temporary variables.
// Press and hold key 1,2,3...8 together with PageUp or PageDown to modify.
// By default all set to 1.0
float4 tempF1; //0,1,2,3
float4 tempF2; //5,6,7,8
float4 tempF3; //9,0
float4 Timer; //x=generic timer in range 0..1, period of 16777216 ms (4.6 hours), w=frame time elapsed (in seconds)
float4 ScreenSize; //x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY
float ENightDayFactor; //changes in range 0..1, 0 means that night time, 1 - day time
float EInteriorFactor; //changes 0 or 1. 0 means that exterior, 1 - interior
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////
// TEXTURES //
//////////////////
texture2D texColor;
texture2D texNoise;
///////////////////
// SAMPLERS //
///////////////////
sampler2D SamplerColor = sampler_state
{
Texture = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerNoise = sampler_state
{
Texture = <texNoise>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU = Wrap;
AddressV = Wrap;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
//////////////////
// STRUCTS //
//////////////////
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;
}
//////////////////
// SHADERS //
//////////////////
float4 PS_ProcessLumaSharpen(VS_OUTPUT_POST IN, float2 vPos : VPOS, float2 tex : TEXCOORD0) : COLOR
{
float2 coord = IN.txcoord.xy;
#define px fvTexelSize.x
#define py fvTexelSize.y
// Bias value
float offset_bias = 1.0;
float sharp_strength = sharp_strengthExt;
float sharp_clamp = sharp_clampExt;
if (EInteriorFactor)
{
sharp_strength = sharp_strengthInt;
sharp_clamp = sharp_clampInt;
};
#define sharp_strength_luma (CoefLuma * sharp_strength)
#define CoefLuma float4(0.2126, 0.7152, 0.0722, 0)
half4 ori = tex2D(SamplerColor, coord.xy);
[branch] if (any(frac(ori.rgb)))
{
#if SharpMethod == 1
// -- Gaussian filter --
// [ 2/9, 4/9, ] [ 1 , 2 , ]
// [ 4/9, 8/9, 4/9] = [ 2 , 4 , 2 ]
// [ , 2/9, 2/9] [ , 2 , 1 ]
half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,py,-px,py) / 3 * offset_bias); // North West
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,-py,px,-py) / 3 * offset_bias); // South East
//Divide by the number of texture fetches
blur_ori /= 2;
#endif
// -- Pattern 2 -- A 9 tap gaussian using 4+1 texture fetches.
#if SharpMethod == 2
// -- Gaussian filter --
// [ .25, .50, .25] [ 1 , 2 , 1 ]
// [ .50, 1, .50] = [ 2 , 4 , 2 ]
// [ .25, .50, .25] [ 1 , 2 , 1 ]
half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,py,-px,py) * 0.5 * offset_bias); // North West
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,-py,px,-py) * 0.5 * offset_bias); // South East
if (any((blur_ori.rgb / 2) - ori.rgb))
{
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,-py,-px,-py) * 0.5 * offset_bias); // South West
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,py,px,py) * 0.5 * offset_bias); // North East
//Divide by the number of texture fetches
blur_ori *= 0.25;;
}
//Divide by the number of texture fetches
blur_ori *= 0.25;;
#endif
// -- Pattern 3 -- An experimental 17 tap gaussian using 4+1 texture fetches.
#if SharpMethod == 3
// -- Gaussian filter --
// [ , 4 , 6 , , ]
// [ ,16 ,24 ,16 , 4 ]
// [ 6 ,24 ,50 ,24 , 6 ]
// [ 4 ,16 ,24 ,16 , ]
// [ , , 6 , 4 , ]
half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(-0.4*px,1.2*py,-0.4*px,1.2*py) * offset_bias); // North North West
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(0.4*px,-1.2*py,0.4*px,-1.2*py) * offset_bias); // South South East
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(1.2*px,0.4*py,0,0) * offset_bias); // East North East
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(-1.2*px,-0.4*py,0,0) * offset_bias); // West South West
blur_ori += ori; // Probably not needed. Only serves to lessen the effect.
blur_ori /= 5; //Divide by the number of texture fetches
#endif
// -- Pattern 4 -- A 9 tap high pass using 4+1 texture fetches.
#if SharpMethod == 4
// -- Gaussian filter --
// [ .50, .50, .50] [ 1 , 1 , 1 ]
// [ .50, , .50] = [ 1 , , 1 ]
// [ .50, .50, .50] [ 1 , 1 , 1 ]
half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(0.5 * -px,py,0.5 * -px,py) * offset_bias); // North North West
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(0.5 * px,-py,0.5 * px,-py)); // South South East
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,0.5 * -py,-px,0.5 * -py)); // West South West
blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,0.5 * py,px,0.5 * py) * offset_bias); // East North East
blur_ori += (2 * ori); // Probably not needed. Only serves to lessen the effect.
blur_ori /= 6; //Divide by the number of texture fetches
#endif
// -- Calculate the sharpening --
half sharp = ori - blur_ori;
// -- Adjust strength of the sharpening --
sharp = dot(sharp, sharp_strength_luma);
// -- Clamping the maximum amount of sharpening to prevent halo artifacts --
sharp = clamp(sharp, -sharp_clamp, sharp_clamp);
// -- Combining the values to get the final sharpened pixel --
half4 done = ori + sharp;
return done;
}
else
{
return ori;
}
}
float4 PS_ProcessBlur(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res;
float4 coord=0.0;
coord.xy=IN.txcoord.xy;
float4 origcolor;
coord.w=0.0;
origcolor=tex2Dlod(SamplerColor, coord);
float2 offset[16]=
{
float2(1.0, 1.0),
float2(-1.0, -1.0),
float2(-1.0, 1.0),
float2(1.0, -1.0),
float2(1.0, 0.0),
float2(-1.0, 0.0),
float2(0.0, 1.0),
float2(0.0, -1.0),
float2(1.41, 0.0),
float2(-1.41, 0.0),
float2(0.0, 1.41),
float2(0.0, -1.41),
float2(1.41, 1.41),
float2(-1.41, -1.41),
float2(-1.41, 1.41),
float2(1.41, -1.41)
};
int i=0;
float4 tcol=origcolor;
float invscreensize=1.0/ScreenSize;
for (i=0; i<16; i++)
{
float2 tdir=offset[i].xy;
coord.xy=IN.txcoord.xy+tdir.xy*invscreensize*BlurSamplingRange;
float4 ct=tex2Dlod(SamplerColor, coord);
tcol+=ct;
}
tcol*=0.05882353;
res.xyz=tcol.xyz;
res.w=1.0;
return res;
}
float4 PS_ProcessSharpen(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res;
float4 coord=0.0;
coord.xy=IN.txcoord.xy;
float4 origcolor;
coord.w=0.0;
origcolor=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++)
{
float2 tdir=offset[i].xy;
coord.xy=IN.txcoord.xy+tdir.xy*invscreensize*SharpSamplingRange;
float4 ct=tex2Dlod(SamplerColor, coord);
tcol+=ct;
}
tcol*=0.1111;
//sharp
#ifdef ESHARPENING
#ifdef ESHARPENINGCOLOR
//color
res=origcolor*(1.0+((origcolor-tcol)*SharpeningAmount));
#else
//non color
float difffact=dot((origcolor.xyz-tcol.xyz), 0.333);
res=origcolor*(1.0+difffact*SharpeningAmount);
#endif
//less sharpening for bright pixels
float rgray=origcolor.z;
rgray=pow(rgray, 3.0);
res=lerp(res, origcolor, saturate(rgray));
#endif
res.w=1.0;
return res;
}
float4 PS_ProcessShift(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res;
float4 coord=0.0;
coord.xy=IN.txcoord.xy;
float4 origcolor;
coord.w=0.0;
origcolor=tex2Dlod(SamplerColor, coord);
int i=0;
#ifdef ECOLORSHIFT
float4 tcol=origcolor;
float2 invscreensize=1.0/ScreenSize.x;
invscreensize.y=invscreensize.y/ScreenSize.z;
coord.xy=IN.txcoord.xy;
origcolor=tex2Dlod(SamplerColor, coord);
res.y=origcolor.y;
coord.xy=IN.txcoord.xy;
coord.y-=invscreensize*ShiftSamplingRange;
origcolor=tex2Dlod(SamplerColor, coord);
res.x=origcolor.x;
coord.xy=IN.txcoord.xy;
coord.y+=invscreensize*ShiftSamplingRange;
origcolor=tex2Dlod(SamplerColor, coord);
res.z=origcolor.z;
#endif
res.w=1.0;
return res;
}
float4 PS_ProcessContrast(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float ContrastCurve = ContrastCurveExt;
if (EInteriorFactor)
{
ContrastCurve = ContrastCurveInt;
};
float4 res;
float3 origcolor=tex2D(SamplerColor, IN.txcoord.xy);
float3 lumCoeff = float3(0.212656, 0.715158, 0.072186); //Calculate luma with these values
float luma = dot(lumCoeff, origcolor.rgb);
float3 chroma = origcolor.rgb - luma;
float Curves_contrast_blend = ContrastCurve;
float PI = 3.1415926535897932384626433832795;
float x = luma; //If the curve should be applied to Luma
x = x - 0.5;
x = x / ((abs(x)*1.25) + 0.375 ) + 0.5;
x = lerp(luma, x, Curves_contrast_blend); //if the curve should be applied to both Luma and Chroma
if (C_CONTRASTCURVES==true)
{
res.rgb = x + chroma; //Blend by Curves_contrast
}
if (C_CONTRASTCURVES==false)
{
res.rgb = origcolor.rgb;
}
res.w=1.0;
return res;
}
float4 PS_ProcessVibrance(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float Vibrance = VibranceExt;
if (EInteriorFactor)
{
Vibrance = VibranceInt;
};
float4 res;
float3 origcolor = tex2D(SamplerColor, IN.txcoord.xy);
float3 lumCoeff = float3(0.212656, 0.715158, 0.072186); //Calculate luma with these values
float max_color = max(origcolor.r, max(origcolor.g,origcolor.b)); //Find the strongest color
float min_color = min(origcolor.r, min(origcolor.g,origcolor.b)); //Find the weakest color
float color_saturation = max_color - min_color; //Saturation is the difference between min and max
float luma = dot(lumCoeff, origcolor.rgb); //Calculate luma (grey)
if (C_VIBRANCE==true)
{
res.rgb = lerp(luma, origcolor.rgb, (1.0 + (Vibrance * (1.0 - (sign(Vibrance) * color_saturation))))); //Extrapolate between luma and original by 1 + (1-saturation) - current
}
if (C_VIBRANCE==false)
{
res.rgb = origcolor.rgb;
}
res.w=1.0;
return res;
}
float4 PS_ProcessNoise(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float NoiseAmount = NoiseAmountExt;
float NoiseFineness = NoiseFinenessExt;
if (EInteriorFactor)
{
NoiseAmount = NoiseAmountInt;
NoiseFineness = NoiseFinenessInt;
};
float4 coord=0.0;
coord.xy=IN.txcoord.xy;
coord.w=0.0;
#define noise_strength_luma (CoefLuma * NoiseAmount)
#define CoefLuma float4(0.2126, 0.7152, 0.0722, 0)
float4 tcol=tex2Dlod(SamplerColor, coord);
float origgray=max(tcol.x, tcol.y);
origgray=max(origgray, tcol.z);
coord.xy=IN.txcoord.xy*NoiseFineness + frac(Timer.x * 100000.0 + Timer.x);
float4 cnoi=tex2Dlod(SamplerNoise, coord);
#if NoiseMethod == 1
tcol=lerp(tcol, (cnoi.x+0.5)*tcol, noise_strength_luma*saturate(1.0-origgray*0.5));
#endif
#if NoiseMethod == 0
tcol=lerp(tcol, (cnoi.x+0.5)*tcol, NoiseAmount*saturate(1.0-origgray*0.5));
#endif
tcol.w=1.0;
return tcol;
}
float4 PS_LevelsPass(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float Levels_black_point = BlackPointExt;
float Levels_white_point = WhitePointExt;
if (EInteriorFactor)
{
Levels_black_point = BlackPointInt;
Levels_white_point = WhitePointInt;
};
#define black_point_float ( Levels_black_point / 255.0 )
#define white_point_float ( 255.0 / (Levels_white_point - Levels_black_point))
float4 res;
float3 origcolor = tex2D(SamplerColor, IN.txcoord.xy);
if (C_BLACKLEVEL==true)
{
res.rgb = origcolor.rgb * white_point_float - (black_point_float * white_point_float);
}
if (C_BLACKLEVEL==false)
{
res.rgb = origcolor.rgb;
}
res.w=1.0;
return res;
}
///////////////////////
// TECHNIQUES //
///////////////////////
technique PostProcess
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessNoise();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess2
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessBlur();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess3
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessSharpen();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess4
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessShift();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess5
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessContrast();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess6
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessVibrance();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess7
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessLumaSharpen();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess8
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_LevelsPass();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
**********************************************************************************
And I want to add in these functions, specifically the Gaussianbloom, softlight , intensity and luma blen:
Code: Select all
/**
* SHADER ADDON
* Featuring: Gaussian blur passes for Photoshop: Soft Light and Screen blending techniques ( finest Contrast bloom )
* Effect is FPS heavy and subtle. Use as you see fit. Scaled for 1080 resolution. Higher resolutions and effect is minimal ( blur is pixel based ) and FPS hit bigger.
* LumaSharpen by CeeJay.dk & ZeroKing
* By prod80 - Serenity ENB
*/
/**
* ENBSeries
* visit http://enbdev.com for updates
* Copyright (c) 2007-2014 Boris Vorontsov
*/
//--------------------------//
// Internal parameters //
// Can be modified //
//--------------------------//
//////////////////
// DEFINES //
//////////////////
#define SharpMethod 4 //[1, 2, 3, 4] Comment out (add // in front) to disable sharpening pass and GUI for it
////////////////////
// CONTRAST BLOOM //
////////////////////
float sl_mix_set <
string UIName="Soft Light Intensity";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
float UIStep=0.001;
> = {0.275};
float gauss_bloom <
string UIName="Gaussian Bloom Intensity";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
float UIStep=0.001;
> = {0.550};
bool lumabloom <
string UIName="Luma based Bloom";
> = {true};
float lumasource <
string UIName="Luma Src 1_orig 2_softlight 3_blend";
string UIWidget="Spinner";
float UIMin=1;
float UIMax=3;
float UIStep=1;
> = {2};
float gauss_blur <
string UIName="Gaussian Blur Strength";
string UIWidget="Spinner";
float UIMin=1;
float UIMax=3;
float UIStep=1;
> = {2};
////////////////////
// LUMASHARPEN //
////////////////////
#ifdef SharpMethod
bool Section_Luma <
string UIName="------Lumasharpen-----------";
> = {false};
float sharp_strengthExt <
string UIName="LumaSharpen Strength Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=5.0;
float UIStep=0.001;
> = {0.315};
float sharp_strengthInt <
string UIName="LumaSharpen Strength Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=5.0;
float UIStep=0.001;
> = {0.315};
float sharp_clampExt <
string UIName="LumaSharpen Clamp Exterior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
float UIStep=0.001;
> = {0.017};
float sharp_clampInt <
string UIName="LumaSharpen Clamp Interior";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
float UIStep=0.001;
> = {0.017};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//--------------------------//
// External parameters //
// Do not modify //
//--------------------------//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Keyboard controlled temporary variables.
// Press and hold key 1,2,3...8 together with PageUp or PageDown to modify.
// By default all set to 1.0
float4 tempF1; //0,1,2,3
float4 tempF2; //5,6,7,8
float4 tempF3; //9,0
float4 Timer; //x=generic timer in range 0..1, period of 16777216 ms (4.6 hours), w=frame time elapsed (in seconds)
float4 ScreenSize; //x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY
float ENightDayFactor; //changes in range 0..1, 0 means that night time, 1 - day time
float EInteriorFactor; //changes 0 or 1. 0 means that exterior, 1 - interior
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////
// TEXTURES //
//////////////////
texture2D texOriginal;
texture2D texColor;
texture2D texNoise;
///////////////////
// SAMPLERS //
///////////////////
sampler2D SamplerColor = sampler_state
{
Texture = <texOriginal>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerColor2 = sampler_state
{
Texture = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerNoise = sampler_state
{
Texture = <texNoise>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU = Wrap;
AddressV = Wrap;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
//////////////////
// STRUCTS //
//////////////////
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;
}
//////////////////
// HELPER FUNCS //
//////////////////
//GAUSSIAN WEIGHTS - Linear sampled for high performance
//9 tap reduced to 3 weights ( 17 pixels wide )
static const float sampleOffsets_1[3] = { 0.0, 1.137453814668, 3.013581103919 };
static const float sampleWeights_1[3] = { 0.441440131387, 0.277468870531, 0.001811063775 };
//17 tap reduced to 5 weights ( 33 pixels wide )
static const float sampleOffsets_2[5] = { 0.0, 1.263686497497, 3.083471450524, 5.022636787155, 7.005855649638 };
static const float sampleWeights_2[5] = { 0.330086281980, 0.318351147970, 0.016540813281, 0.000064880504, 0.000000017255 };
//21 tap reduced to 6 weights ( 41 pixels wide )
static const float sampleOffsets_3[6] = { 0.0, 1.452313744966, 3.390210239952, 5.331472958797, 7.277552900121, 9.229394260785 };
static const float sampleWeights_3[6] = { 0.142479385858, 0.244115579374, 0.131636577371, 0.043283482080, 0.008668409765, 0.001056258481 };
float3 softlight(float3 a, float3 b, float s)
{
float3 ret;
float3 b_x2 = 2.0 * b;
float3 a_b_x2 = a * b_x2;
float3 c1 = a_b_x2 + a * a - a * a_b_x2;
float3 c2 = sqrt(a) * ( b_x2 - 1.0 ) + 2.0 * a - a_b_x2;
ret = ( b >= 0.5 ) ? c1 : c2;
return lerp( a, ret, s );
}
float3 screen(float3 a, float3 b)
{
return (1.0f - (1.0f - a) * (1.0f - b));
}
//////////////////
// SHADERS //
//////////////////
float4 PS_ProcessGaussianH(VS_OUTPUT_POST IN) : COLOR
{
float sHeight = ScreenSize.x * ScreenSize.w;
float2 fvTexelSize = float2(ScreenSize.y, 1.0 / sHeight);
float px = fvTexelSize.x;
float py = fvTexelSize.y;
float4 color = 0.0;
if ( gauss_blur==1 )
{
color = tex2D(SamplerColor2, IN.txcoord.xy) * sampleWeights_1[0];
for(int i = 1; i < 3; ++i) {
color += tex2D(SamplerColor2, IN.txcoord.xy + float2(sampleOffsets_1[i]*px, 0.0)) * sampleWeights_1[i];
color += tex2D(SamplerColor2, IN.txcoord.xy - float2(sampleOffsets_1[i]*px, 0.0)) * sampleWeights_1[i];
}
}
if ( gauss_blur==2 )
{
color = tex2D(SamplerColor2, IN.txcoord.xy) * sampleWeights_2[0];
for(int i = 1; i < 5; ++i) {
color += tex2D(SamplerColor2, IN.txcoord.xy + float2(sampleOffsets_2[i]*px, 0.0)) * sampleWeights_2[i];
color += tex2D(SamplerColor2, IN.txcoord.xy - float2(sampleOffsets_2[i]*px, 0.0)) * sampleWeights_2[i];
}
}
if ( gauss_blur==3 )
{
color = tex2D(SamplerColor2, IN.txcoord.xy) * sampleWeights_3[0];
for(int i = 1; i < 6; ++i) {
color += tex2D(SamplerColor2, IN.txcoord.xy + float2(sampleOffsets_3[i]*px, 0.0)) * sampleWeights_3[i];
color += tex2D(SamplerColor2, IN.txcoord.xy - float2(sampleOffsets_3[i]*px, 0.0)) * sampleWeights_3[i];
}
}
color.w = 1.0f;
return color;
}
float4 PS_ProcessGaussianV(VS_OUTPUT_POST IN) : COLOR
{
float sHeight = ScreenSize.x * ScreenSize.w;
float2 fvTexelSize = float2(ScreenSize.y, 1.0 / sHeight);
float px = fvTexelSize.x;
float py = fvTexelSize.y;
float4 color = 0.0;
if ( gauss_blur==1 )
{
color = tex2D(SamplerColor2, IN.txcoord.xy) * sampleWeights_1[0];
for(int i = 1; i < 3; ++i) {
color += tex2D(SamplerColor2, IN.txcoord.xy + float2(0.0, sampleOffsets_1[i]*py)) * sampleWeights_1[i];
color += tex2D(SamplerColor2, IN.txcoord.xy - float2(0.0, sampleOffsets_1[i]*py)) * sampleWeights_1[i];
}
}
if ( gauss_blur==2 )
{
color = tex2D(SamplerColor2, IN.txcoord.xy) * sampleWeights_2[0];
for(int i = 1; i < 5; ++i) {
color += tex2D(SamplerColor2, IN.txcoord.xy + float2(0.0, sampleOffsets_2[i]*py)) * sampleWeights_2[i];
color += tex2D(SamplerColor2, IN.txcoord.xy - float2(0.0, sampleOffsets_2[i]*py)) * sampleWeights_2[i];
}
}
if ( gauss_blur==3 )
{
color = tex2D(SamplerColor2, IN.txcoord.xy) * sampleWeights_3[0];
for(int i = 1; i < 6; ++i) {
color += tex2D(SamplerColor2, IN.txcoord.xy + float2(0.0, sampleOffsets_3[i]*py)) * sampleWeights_3[i];
color += tex2D(SamplerColor2, IN.txcoord.xy - float2(0.0, sampleOffsets_3[i]*py)) * sampleWeights_3[i];
}
}
color.w = 1.0f;
return color;
}
float4 PS_ProcessSoftLight(VS_OUTPUT_POST IN) : COLOR
{
float4 color = 0.0;
float4 baseC = tex2D(SamplerColor, IN.txcoord.xy);
float4 blendC = tex2D(SamplerColor2, IN.txcoord.xy);
float3 base = baseC.xyz;
float3 blend = blendC.xyz;
color.xyz = softlight( base, blend, sl_mix_set );
color.w = 1.0f;
return color;
}
float4 PS_ProcessGaussBloom(VS_OUTPUT_POST IN) : COLOR
{
float4 scrcolor = 0.0;
float4 color = 0.0;
float3 luma = float3(0.2125, 0.7154, 0.0721);
float pixluma = 0.0;
float4 baseC = tex2D(SamplerColor, IN.txcoord.xy);
float4 blendC = tex2D(SamplerColor2, IN.txcoord.xy);
float3 base = baseC.xyz;
float3 blend = blendC.xyz;
scrcolor.xyz = screen( base, blend );
//Bloom on luma
if (lumabloom==true)
{
if (lumasource==1) pixluma = dot( base, luma );
if (lumasource==2) pixluma = dot( blend, luma );
if (lumasource==3) pixluma = dot( scrcolor, luma );
color.xyz = lerp( base.xyz, scrcolor.xyz, gauss_bloom * pixluma );
};
if (lumabloom==false)
{
color.xyz = lerp( base.xyz, scrcolor.xyz, gauss_bloom );
};
color.w = 1.0f;
return color;
}
#ifdef SharpMethod
float4 PS_ProcessLumaSharpen(VS_OUTPUT_POST IN, float2 vPos : VPOS, float2 tex : TEXCOORD0) : COLOR
{
float2 coord = IN.txcoord.xy;
float sHeight = ScreenSize.x * ScreenSize.w;
float2 fvTexelSize = float2(ScreenSize.y, 1.0 / sHeight);
float px = fvTexelSize.x;
float py = fvTexelSize.y;
// Bias value
float offset_bias = 1.0;
float sharp_strength = sharp_strengthExt;
float sharp_clamp = sharp_clampExt;
if (EInteriorFactor)
{
sharp_strength = sharp_strengthInt;
sharp_clamp = sharp_clampInt;
};
#define sharp_strength_luma (CoefLuma * sharp_strength)
#define CoefLuma float4(0.2126, 0.7152, 0.0722, 0)
half4 ori = tex2D(SamplerColor2, coord.xy);
[branch] if (any(frac(ori.rgb)))
{
#if SharpMethod == 1
// -- Gaussian filter --
// [ 2/9, 4/9, ] [ 1 , 2 , ]
// [ 4/9, 8/9, 4/9] = [ 2 , 4 , 2 ]
// [ , 2/9, 2/9] [ , 2 , 1 ]
half4 blur_ori = tex2Dlod(SamplerColor2, float4(tex,tex) + float4(-px,py,-px,py) / 3 * offset_bias); // North West
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(px,-py,px,-py) / 3 * offset_bias); // South East
//Divide by the number of texture fetches
blur_ori /= 2;
#endif
// -- Pattern 2 -- A 9 tap gaussian using 4+1 texture fetches.
#if SharpMethod == 2
// -- Gaussian filter --
// [ .25, .50, .25] [ 1 , 2 , 1 ]
// [ .50, 1, .50] = [ 2 , 4 , 2 ]
// [ .25, .50, .25] [ 1 , 2 , 1 ]
half4 blur_ori = tex2Dlod(SamplerColor2, float4(tex,tex) + float4(-px,py,-px,py) * 0.5 * offset_bias); // North West
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(px,-py,px,-py) * 0.5 * offset_bias); // South East
if (any((blur_ori.rgb / 2) - ori.rgb))
{
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(-px,-py,-px,-py) * 0.5 * offset_bias); // South West
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(px,py,px,py) * 0.5 * offset_bias); // North East
//Divide by the number of texture fetches
blur_ori *= 0.25;;
}
//Divide by the number of texture fetches
blur_ori *= 0.25;;
#endif
// -- Pattern 3 -- An experimental 17 tap gaussian using 4+1 texture fetches.
#if SharpMethod == 3
// -- Gaussian filter --
// [ , 4 , 6 , , ]
// [ ,16 ,24 ,16 , 4 ]
// [ 6 ,24 ,50 ,24 , 6 ]
// [ 4 ,16 ,24 ,16 , ]
// [ , , 6 , 4 , ]
half4 blur_ori = tex2Dlod(SamplerColor2, float4(tex,tex) + float4(-0.4*px,1.2*py,-0.4*px,1.2*py) * offset_bias); // North North West
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(0.4*px,-1.2*py,0.4*px,-1.2*py) * offset_bias); // South South East
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(1.2*px,0.4*py,0,0) * offset_bias); // East North East
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(-1.2*px,-0.4*py,0,0) * offset_bias); // West South West
blur_ori += ori; // Probably not needed. Only serves to lessen the effect.
blur_ori /= 5; //Divide by the number of texture fetches
#endif
// -- Pattern 4 -- A 9 tap high pass using 4+1 texture fetches.
#if SharpMethod == 4
// -- Gaussian filter --
// [ .50, .50, .50] [ 1 , 1 , 1 ]
// [ .50, , .50] = [ 1 , , 1 ]
// [ .50, .50, .50] [ 1 , 1 , 1 ]
half4 blur_ori = tex2Dlod(SamplerColor2, float4(tex,tex) + float4(0.5 * -px,py,0.5 * -px,py) * offset_bias); // North North West
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(0.5 * px,-py,0.5 * px,-py)); // South South East
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(-px,0.5 * -py,-px,0.5 * -py)); // West South West
blur_ori += tex2Dlod(SamplerColor2, float4(tex,tex) + float4(px,0.5 * py,px,0.5 * py) * offset_bias); // East North East
blur_ori += (2 * ori); // Probably not needed. Only serves to lessen the effect.
blur_ori /= 6; //Divide by the number of texture fetches
#endif
// -- Calculate the sharpening --
half sharp = ori - blur_ori;
// -- Adjust strength of the sharpening --
sharp = dot(sharp, sharp_strength_luma);
// -- Clamping the maximum amount of sharpening to prevent halo artifacts --
sharp = clamp(sharp, -sharp_clamp, sharp_clamp);
// -- Combining the values to get the final sharpened pixel --
half4 done = ori + sharp;
return done;
}
else
{
return ori;
}
}
#endif
///////////////////////
// TECHNIQUES //
///////////////////////
technique PostProcess
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessGaussianH();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess2
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessGaussianV();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess3
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessSoftLight();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess4
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessGaussianH();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess5
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessGaussianV();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess6
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessGaussBloom();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
#ifdef SharpMethod
technique PostProcess7
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_ProcessLumaSharpen();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
#endif