2023-09-23 14:39:09 +06:00

790 lines
30 KiB
HLSL

////---------//
///**Flair**///
//---------////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* Lens Flares are based on Blooming HDR Original Code
//* For Reshade 3.0+
//* ---------------------------------
//* Flair
//* Let's add some ------ to your images.
//* Flares
//* Due Diligence
//* Eye Adaptation
//* https://knarkowicz.wordpress.com/2016/01/09/automatic-exposure/ Search Ref. Temporal Adaptation
//* If I miss any please tell me.
//*
//* LICENSE
//* ============
//* Flare is licenses under: Attribution-NoDerivatives 4.0 International
//*
//* You are free to:
//* Share - copy and redistribute the material in any medium or format
//* for any purpose, even commercially.
//* The licensor cannot revoke these freedoms as long as you follow the license terms.
//* Under the following terms:
//* Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made.
//* You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
//*
//* NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material.
//*
//* No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
//*
//* https://creativecommons.org/licenses/by-nd/4.0/
//*
//* Have fun,
//* Jose Negrete AKA BlueSkyDefender
//*
//* https://github.com/BlueSkyDefender/Depth3D
//* Special thanks to NVIDIA on compatibility with GeForce GPUs and feedback on shader development
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Shared Texture for Blooming HDR or any other shader that want's to use it.
texture TexFlareShared { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; };
//You can also make a text file named "DisableFlare.txt" to dissable this shader output and
//only use the Share Texture above in your your shader.
uniform int Flare_Type <
ui_type = "combo";
ui_items = "Star Full\0Star Half\0Cross +\0Cross x\0Flare +Skew\0Flare -Skew\0Flare Horizontal\0Flare Vertical\0";
ui_label = "Flare Type";
ui_category = "Flare Type";
> = 0;
uniform bool Auto_Flare_Intensity <
ui_label = "Auto Flare Intensity";
ui_tooltip = "This will enable the shader to adjust Flare Intensity automatically.\n"
"Auto Bloom Intensity will set Bloom Intensity below.";
ui_category = "Flare Adjustments";
> = false;
uniform float Flare_Clamp_A <
ui_type = "slider";
ui_min = 0.0; ui_max = 1.0;
ui_label = "Flare Brightness Threshold";
ui_tooltip = "Use this to set the color based brightness threshold for what is and what isn't allowed.\n"
"Number 1.0 is default.";
ui_category = "Flare Adjustments";
> = 1.0;
uniform float Flare_Clamp_B <
ui_type = "slider";
ui_min = 0.0; ui_max = 1.0;
ui_label = "Flare Max Brightness Cutoff";
ui_tooltip = "Use this to set the max cutoff point of the brightness things in the image.\n"
"Number 1.0 is default.";
ui_category = "Flare Adjustments";
> = 1.0;
uniform float Flare_Spread <
ui_type = "slider";
ui_min = -1.0; ui_max = 1.0; ui_step = 0.01;
ui_label = "Flare Spread";
ui_tooltip = "Use this to adjust Flare size & you can override this.\n"
"Number 0.5 is default.";
ui_category = "Flare Adjustments";
> = 0.5;
uniform float Flare_Power <
ui_type = "slider";
ui_min = 0.0; ui_max = 12.5; ui_step = 0.125;
ui_label = "Flare Intensity";
ui_tooltip = "Use this to set Flare Intensity for your content.\n"
"Number 1.0 is default.";
ui_category = "Flare Adjustments";
> = 1.0;
uniform float Flare_Saturation <
ui_type = "slider";
ui_min = 0.0; ui_max = 10.0; ui_step = 0.1;
ui_label = "Flare Saturation";
ui_tooltip = "Adjustment The amount to adjust the saturation of the flare color.\n"
"Number 1.0 is default.";
ui_category = "Flare Adjustments";
> = 5.0;
//User_Flare_Color needs Flare_Color_Map to be set to -1 and the rest uncommented.
uniform int Flare_Color_Map <
ui_type = "slider";
ui_min = -1; ui_max = 8;
ui_label = "Flare Color Map";
ui_tooltip = "Use this to set MIP levels for the color map used to se Flare Color.\n"
"This samples color in the general area to achieve this effect.\n"
"Number 4 is default & Zero is Off.";
ui_category = "Flare Adjustments";
> = 4;
uniform float3 User_Flare_Color <
ui_type = "color";
ui_min = 0.0; ui_max = 1.0;
ui_label = "Flare Color Adjust";
ui_tooltip = "Use this to set your own color settings.";
ui_category = "Flare Adjustments";
> = float3(1.0,1.0,1.0);
uniform float Flare_Localization <
ui_type = "slider";
ui_min = -1.0; ui_max = 1.0; ui_step = 0.1;
ui_label = "Flare Localization";
ui_tooltip = "This localizes flare to a user selected area.\n"
"Number Zero is default.";
ui_category = "Flare Adjustments";
> = 0.0;
uniform int CA_Type <
ui_type = "combo";
ui_items = "Off\0Type BD\0Type Box\0Type Hozi\0Type Verti\0";
ui_label = "Flare CA Type";
ui_category = "Flare Chromatic Aberration";
> = 1;
uniform float3 Flare_PBD <
ui_type = "slider";
ui_min = 0.0; ui_max = 1.0;
ui_label = "Flare CA Adjust";
ui_tooltip = "Use this to set chromatic aberration for your content.";
ui_category = "Flare Chromatic Aberration";
> = float3(1.0,0.5,0.0);
//Depth Map//
uniform int Depth_Map <
ui_type = "combo";
ui_items = "Normal\0Reversed\0";
ui_label = "Depth Map Adjustment";
ui_tooltip = "Linearization for the zBuffer also known as Depth Map.\n"
"DM0 is Z-Normal and DM1 is Z-Reversed.\n";
ui_category = "Depth Map Masking";
> = 0;
uniform float Depth_Map_Adjust <
ui_type = "drag";
ui_min = 0.25; ui_max = 250.0; ui_step = 0.25;
ui_label = "Depth Map Adjustment";
ui_tooltip = "This allows for you to adjust the DM precision.\n"
"Adjust this to keep it as low as possible.\n"
"Default is 1.5";
ui_category = "Depth Map Masking";
> = 1.5;
uniform bool Depth_Map_Flip <
ui_label = "Depth Map Flip";
ui_tooltip = "Flip the depth map if it is upside down.";
ui_category = "Depth Map Masking";
> = false;
uniform bool Mask_Sky <
ui_label = "Sky Mask";
ui_tooltip = "Mask Sky using depth";
ui_category = "Depth Map Masking";
> = false;
uniform bool Flair_Falloff <
ui_label = "Falloff";
ui_tooltip = "A depth mask is use to add a fall off distance";
ui_category = "Depth Map Masking";
> = false;
#if __RENDERER__ >= 0x20000 //Vulkan
#define Rend 1
#else
#define Rend 0
#endif
/////////////////////////////////////////////////////D3D Starts Here/////////////////////////////////////////////////////////////////
#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT)
uniform float timer < source = "timer"; >;
//Total amount of frames since the game started.
uniform uint framecount < source = "framecount"; >;
uniform float frametime < source = "frametime";>;
//Made Up Values that look nice not correct.
static const float OffsetA[25] = { 0.0, 1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0, 21.0, 23.0, 25.0, 27.0, 29.0, 31.0, 33.0, 35.0, 37.0, 39.0, 41.0, 43.0, 45.0, 47.0 };
static const float OffsetB[25] = { 0.0, 2.0, 4.0, 6.0, 8.0,10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 22.0, 24.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0, 42.0, 44.0, 46.0, 48.0 };
static const float OffsetC[25] = { 0.5, 1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5, 15.5, 17.5, 19.5, 21.5, 23.5, 25.5, 27.5, 29.5, 31.5, 33.5, 35.5, 37.5, 39.5, 41.5, 43.5, 45.5, 47.5 };
static const float OffsetD[25] = { 0.5, 2.5, 4.5, 6.5, 8.5,10.5, 12.5, 14.5, 16.5, 18.5, 20.5, 22.5, 24.5, 26.5, 28.5, 30.5, 32.5, 34.5, 36.5, 38.5, 40.5, 42.5, 44.5, 46.5, 48.5 };
static const float Weight[25] = { 0.10761,0.10306,0.09750, 0.09110,0.08409,0.07666,0.06903,0.06139,0.05394,0.04680,0.0401,0.0339,0.0284,0.0234,0.0191,0.0154,0.0122,0.0096,0.0074,0.0057,0.0043,0.0032,0.0024,0.0017,0.0012 };
#define FS Flare_Spread < 0 ? Flare_Spread * 4.0 : Flare_Spread * 2.2
#define Flare_Softness 0 //saturate(abs(Flare_Spread)) //Removed because of Opti
#define Alternate framecount % 2 == 0
//Eye Adaptation Set from 0 to 1
static const float Adapt_Seek = 0.5;//Use this to Adjust Eye Adaptation Speed
static const float Adapt_Adjust = 0.5;//Use this to Adjust Eye Seeking Radius for Average Brightness.
float lum(float3 RGB){ return dot(RGB, float3(0.2126, 0.7152, 0.0722) );}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
texture TexDepthBuffer : DEPTH;
texture TexBackBuffer : COLOR;
sampler DepthBufferF
{
Texture = TexDepthBuffer;
};
sampler BackBufferF
{
Texture = TexBackBuffer;
};
texture texFlare { Width = BUFFER_WIDTH * 0.25; Height = BUFFER_HEIGHT * 0.25; Format = RGBA16f; };
sampler SamplerGlammor
{
Texture = texFlare;
};
texture TexBC { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = RGBA8; };
sampler SamplerBC
{
Texture = TexBC;
};
texture TexMBB { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT ; Format = RGBA8; MipLevels = 8; };
sampler SamplerMBB
{
Texture = TexMBB;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
texture TexFlarePast { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; };
sampler SamplerPastFlare
{
Texture = TexFlarePast;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
void A0(float2 texcoord,float PosX,float PosY,inout float D, inout float E, inout float P, inout float T, inout float H, inout float III, inout float DD )
{
float PosXD = -0.035+PosX, offsetD = 0.001;D = all( abs(float2( texcoord.x -PosXD, texcoord.y-PosY)) < float2(0.0025,0.009));D -= all( abs(float2( texcoord.x -PosXD-offsetD, texcoord.y-PosY)) < float2(0.0025,0.007));
float PosXE = -0.028+PosX, offsetE = 0.0005;E = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.009));E -= all( abs(float2( texcoord.x -PosXE-offsetE, texcoord.y-PosY)) < float2(0.0025,0.007));E += all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.001));
float PosXP = -0.0215+PosX, PosYP = -0.0025+PosY, offsetP = 0.001, offsetP1 = 0.002;P = all( abs(float2( texcoord.x -PosXP, texcoord.y-PosYP)) < float2(0.0025,0.009*0.775));P -= all( abs(float2( texcoord.x -PosXP-offsetP, texcoord.y-PosYP)) < float2(0.0025,0.007*0.680));P += all( abs(float2( texcoord.x -PosXP+offsetP1, texcoord.y-PosY)) < float2(0.0005,0.009));
float PosXT = -0.014+PosX, PosYT = -0.008+PosY;T = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosYT)) < float2(0.003,0.001));T += all( abs(float2( texcoord.x -PosXT, texcoord.y-PosY)) < float2(0.000625,0.009));
float PosXH = -0.0072+PosX;H = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.001));H -= all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.009));H += all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.00325,0.009));
float offsetFive = 0.001, PosX3 = -0.001+PosX;III = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.009));III -= all( abs(float2( texcoord.x -PosX3 - offsetFive, texcoord.y-PosY)) < float2(0.003,0.007));III += all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.001));
float PosXDD = 0.006+PosX, offsetDD = 0.001;DD = all( abs(float2( texcoord.x -PosXDD, texcoord.y-PosY)) < float2(0.0025,0.009));DD -= all( abs(float2( texcoord.x -PosXDD-offsetDD, texcoord.y-PosY)) < float2(0.0025,0.007));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
texture texLumF {Width = 256; Height = 256; Format = R16F; MipLevels = 9;}; //Sample at 256x256 map only has nine mip levels; 0-1-2-3-4-5-6-7-8 : 256,128,64,32,16,8,4,2, and 1 (1x1).
sampler SamplerLumG
{
Texture = texLumF;
};
float LuminanceG(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
float2 texXY = texcoord;
float2 midHV = (Adapt_Seek-1) * float2(BUFFER_WIDTH * 0.5,BUFFER_HEIGHT * 0.5) * pix;
texcoord = float2((texXY.x*Adapt_Seek)-midHV.x,(texXY.y*Adapt_Seek)-midHV.y);
return lum(tex2D(BackBufferF,texcoord).rgb);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
texture texAvgLumF { Width = 256; Height = 256; Format = R16F; };
sampler SamplerAvgLumG
{
Texture = texAvgLumF;
};
texture TexAvgLumaLastF { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16F; };
sampler SamplerAvgLumaLastG
{
Texture = TexAvgLumaLastF;
};
float Average_LuminanceF(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
float AA = (1-Adapt_Adjust) * 1000, L = tex2Dlod(SamplerLumG,float4(texcoord,0,11)).x, PL = tex2D(SamplerAvgLumaLastG, texcoord).x;
//Temporal Adaptation
return PL + (L - PL) * (1.0 - exp(-frametime/AA));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float2 DepthMap(float2 texcoord : TEXCOORD0)
{
if (Depth_Map_Flip)
texcoord.y = 1 - texcoord.y;
float zBuffer = tex2Dlod(DepthBufferF, float4(texcoord,0,0)).x,Raw; //Depth Buffer
//Conversions to linear space.....
//Near & Far Adjustment
float Far = 1.0, Near = 0.125/Depth_Map_Adjust,DA = Depth_Map_Adjust*2; //Division Depth Map Adjust - Near
float2 Z = float2( zBuffer, 1-zBuffer );
if (Depth_Map == 0)//DM0. Normal
{
zBuffer = Far * Near / (Far + Z.x * (Near - Far));
Raw = pow(abs(Z.x),DA);
}
else if (Depth_Map == 1)//DM1. Reverse
{
zBuffer = Far * Near / (Far + Z.y * (Near - Far));
Raw = pow(abs(Z.y),DA);
}
return saturate(float2(zBuffer,Raw));
}
float4 BB( float2 texcoord )
{
return tex2Dlod(BackBufferF, float4(texcoord,0,0)).rgba;
}
void ColorBB(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 MBB : SV_Target)
{
MBB = BB( texcoord ).rgb;
}
float4 GBightColors( float2 texcoord )
{ float DM = smoothstep(0,1,DepthMap(texcoord).x);
//Forced Depth Masking
if(DM == 1)
DM = 1;
else
DM = 0;
if(!Mask_Sky)
DM = 0;
float4 CM = lerp(tex2Dlod(SamplerMBB,float4(texcoord,0,clamp(Flare_Color_Map,0,8))).rgba,0,DM);
float4 BC = lerp(BB(texcoord),0,DM);
// Check whether fragment output is higher than threshold,if so output as brightness color.
float I_A = lum(BC.rgb), I_B = 1-I_A;
I_A *= I_B >= 1-Flare_Clamp_B;//Trim from Top
BC.a = I_A > lerp(0.9,0.999,Flare_Clamp_A);// ? 1 : 0;
BC.rgb *= BC.a ;
if(Flare_Color_Map > 0)
BC.rgb = CM.rgb * BC.a;
else if(Flare_Color_Map == -1)
BC.rgb *= User_Flare_Color;
if(Flair_Falloff)
BC.rgb = lerp(BC.rgb,0.0,DepthMap(texcoord).y);
//Bloom Saturation
BC.rgb = lerp(lum(BC.rgb),BC.rgb,Flare_Saturation);
float2 Stored_TC = texcoord, FL;
if (Flare_Localization != 0)
{
Stored_TC *= 1.0 - Stored_TC;
float vignette = Stored_TC.x*Stored_TC.y*12.5;
if (Flare_Localization < 0)
FL = float2(0,abs(Flare_Localization));
else
FL = float2(abs(Flare_Localization),1);
vignette = 1-smoothstep(FL.x,FL.y,vignette);
if (Flare_Localization < 0)
vignette = 1-vignette;
BC.rgb = lerp(BC.rgb,0.0,vignette);
}
return float4(saturate(BC.rgb),BC.a);
}
void StoredBB(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 BC : SV_Target)
{
BC = GBightColors( texcoord ).rgb;
}
#if !Rend
//Done this way to reduce TempRegisters for DX9 compatablity.
float3 Glammor(sampler2D Sample, float2 texcoord, float N, int Switch, float BBS)
{
float3 GBloom = Switch ? tex2D(Sample,texcoord).rgb : GBightColors(texcoord).rgb;
GBloom *= Weight[0];
[loop]
for(int i = 1; i < N; ++i)
{ float4 offset = float4(OffsetA[i] * pix.xy,OffsetB[i] * pix.xy);
if (Alternate)
offset = float4(OffsetC[i] * pix.xy,OffsetD[i] * pix.xy);
//+ & X
if(Flare_Type == 4 || Flare_Type == 5 || Flare_Type == 6 || Flare_Type == 7)
{
float4 XXZZ = float4( offset.x,-offset.x, offset.z,-offset.z);
float4 YYWW = float4( offset.y,-offset.y, offset.w,-offset.w);
if(Flare_Type == 5 || Flare_Type == 7)
XXZZ = Switch ? 0 : float4(-offset.x, offset.x,-offset.z, offset.z);
if(Flare_Type == 6)
YYWW = Switch ? 0 : float4( offset.y,-offset.y, offset.w,-offset.w);
GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.x, YYWW.x) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.y, YYWW.y) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.z, YYWW.z) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.w, YYWW.w) * BBS,0,0) ).rgb * Weight[i];
}
else
{
float4 YYXX = Switch ? 0 : float4( offset.y,-offset.y,-offset.x, offset.x);
GBloom += tex2Dlod(Sample, float4(texcoord + float2( offset.x, YYXX.x) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2(-offset.x, YYXX.y) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2( YYXX.z, offset.y) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2( YYXX.w,-offset.y) * BBS,0,0) ).rgb * Weight[i];
float4 WWZZ = Switch ? 0 : float4( offset.w,-offset.w,-offset.z, offset.z);
GBloom += tex2Dlod(Sample, float4(texcoord + float2( offset.z, WWZZ.x) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2(-offset.z, WWZZ.y) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2( WWZZ.z, offset.w) * BBS,0,0) ).rgb * Weight[i];
GBloom += tex2Dlod(Sample, float4(texcoord + float2( WWZZ.w,-offset.w) * BBS,0,0) ).rgb * Weight[i];
}
}
GBloom *= 0.5;
return GBloom;
}
float3 GlammorA(float2 texcoord )
{
float N, BBS = FS;
if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7)
N = int(lerp(5,25,abs(Flare_Spread)));
else if(Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 )
N = 1;
return Glammor(SamplerBC, texcoord, N, 1, BBS);
}
float3 GlammorB(float2 texcoord )
{
float N, BBS = FS;
if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 )
N = int(lerp(5,25,abs(Flare_Spread)));
else if(Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7 )
N = 1;
if(Flare_Type == 1)
BBS *= 0.5;
return Glammor(SamplerBC, texcoord, N, 0, BBS);
}
#else
float3 GlammorA(float2 texcoord )
{ float3 GBloom = tex2D(SamplerBC,texcoord).rgb;
float N, BBS = FS;
GBloom *= Weight[0];
if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7)
N = 25;
else if(Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 )
N = 1;
[unroll]
for(int i = 1; i < N; ++i)
{ float4 offset = float4(OffsetA[i] * pix.xy,OffsetB[i] * pix.xy);
if (Alternate)
offset = float4(OffsetC[i] * pix.xy,OffsetD[i] * pix.xy);
//+
if(Flare_Type == 6)
{
GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, 0) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, 0) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, 0) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, 0) * BBS ).rgb * Weight[i];
}
else if(Flare_Type == 7)
{
GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.w) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.w) * BBS ).rgb * Weight[i];
}
else
{
GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, 0) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, 0) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, 0) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, 0) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.w) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.w) * BBS ).rgb * Weight[i];
}
}
GBloom *= 0.5;
return GBloom;
}
float3 GlammorB(float2 texcoord )
{ float3 GBloom = GBightColors(texcoord).rgb;
float N, BBS = FS;
GBloom *= Weight[0];
if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 )
N = 25;
else if(Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7 )
N = 1;
if(Flare_Type == 1)
BBS *= 0.5;
[unroll]
for(int i = 1; i < N; ++i)
{ float4 offset = float4(OffsetA[i] * pix.xy,OffsetB[i] * pix.xy);
if (Alternate)
offset = float4(OffsetC[i] * pix.xy,OffsetD[i] * pix.xy);
//X
if(Flare_Type == 4)
{
GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x,-offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, offset.w) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z,-offset.w) * BBS ).rgb * Weight[i];
}
else if(Flare_Type == 5)
{
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.x,-offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, offset.w) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.z,-offset.w) * BBS ).rgb * Weight[i];
}
else
{
GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x,-offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.x,-offset.y) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, offset.w) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z,-offset.w) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, offset.w) * BBS ).rgb * Weight[i];
GBloom += tex2D(SamplerBC, texcoord + float2( offset.z,-offset.w) * BBS ).rgb * Weight[i];
}
}
GBloom *= 0.5;
return GBloom;
}
#endif
// Spread the blur a bit more.
void Glammor(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 GBloom : SV_Target)
{ GBloom = 0;
float GI = Flare_Power, AL = smoothstep(0,1,1. - tex2D(SamplerAvgLumG,0.0).x);
if(Auto_Flare_Intensity)
GI *= AL;
GBloom = ( GlammorA(texcoord) + GlammorB(texcoord) ) * GI;
}
float2 BD(float2 p, float k1) //Polynomial Lens
{
if(!CA_Type == 1)
discard;
p *= 0.5 + 0.5;//Center
// Normalize the u,v coordinates in the range [-1;+1]
p = (2.0f * p - 1.0f) / 1.0f;
// Calculate l2 norm
float r2 = p.x*p.x + p.y*p.y;
float r4 = pow(r2,2);
// Forward transform
float x2 = p.x * (1.0 + k1 * r2);
float y2 = p.y * (1.0 + k1 * r2);
// De-normalize to the original range
p.x = (x2 + 1.0) * 1.0 / 2.0;
p.y = (y2 + 1.0) * 1.0 / 2.0;
return p;
}
float2 HVP(float2 texcoord, float k1)
{
if(!CA_Type == 2)
discard;
float X = k1;
float Y = k1;
float midW = (X - 1)*(BUFFER_WIDTH*0.5)*pix.x;
float midH = (Y - 1)*(BUFFER_HEIGHT*0.5)*pix.y;
return float2((texcoord.x*X)-midW,(texcoord.y*Y)-midH);
}
float2 HP(float2 texcoord, float k1)
{
if(!CA_Type == 3)
discard;
float X = k1;
float Y = 1;
float midW = (X - 1)*(BUFFER_WIDTH*0.5)*pix.x;
float midH = (Y - 1)*(BUFFER_HEIGHT*0.5)*pix.y;
return float2((texcoord.x*X)-midW,(texcoord.y*Y)-midH);
}
float2 VP(float2 texcoord, float k1)
{
if(!CA_Type == 4)
discard;
float X = 1;
float Y = k1;
float midW = (X - 1)*(BUFFER_WIDTH*0.5)*pix.x;
float midH = (Y - 1)*(BUFFER_HEIGHT*0.5)*pix.y;
return float2((texcoord.x*X)-midW,(texcoord.y*Y)-midH);
}
float3 CAFlare(float2 texcoord)
{
float2 uv_red, uv_green, uv_blue;
float DM, color_red, color_green, color_blue, K1_Red = Flare_PBD.x , K1_Green = Flare_PBD.y , K1_Blue = Flare_PBD.z ;
if(CA_Type == 1)
{
uv_red = BD(texcoord.xy,K1_Red * 0.03);
uv_green = BD(texcoord.xy,K1_Green * 0.03);
uv_blue = BD(texcoord.xy,K1_Blue * 0.03);
}
else if(CA_Type == 2)
{
uv_red = HVP(texcoord.xy,1-K1_Red * 0.025);
uv_green = HVP(texcoord.xy,1-K1_Green * 0.025);
uv_blue = HVP(texcoord.xy,1-K1_Blue * 0.025);
}
else if(CA_Type == 3)
{
uv_red = HP(texcoord.xy,1-K1_Red * 0.025);
uv_green = HP(texcoord.xy,1-K1_Green * 0.025);
uv_blue = HP(texcoord.xy,1-K1_Blue * 0.025);
}
else if(CA_Type == 4)
{
uv_red = VP(texcoord.xy,1-K1_Red * 0.025);
uv_green = VP(texcoord.xy,1-K1_Green * 0.025);
uv_blue = VP(texcoord.xy,1-K1_Blue * 0.025);
}
if(CA_Type > 0)
{
color_red = tex2Dlod(SamplerGlammor,float4(uv_red,0,Flare_Softness)).r;
color_green = tex2Dlod(SamplerGlammor,float4(uv_green,0,Flare_Softness)).g;
color_blue = tex2Dlod(SamplerGlammor,float4(uv_blue,0,Flare_Softness)).b;
}
else
{
color_red = tex2Dlod(SamplerGlammor,float4(texcoord,0,Flare_Softness)).r;
color_green = tex2Dlod(SamplerGlammor,float4(texcoord,0,Flare_Softness)).g;
color_blue = tex2Dlod(SamplerGlammor,float4(texcoord,0,Flare_Softness)).b;
}
return float3(color_red,color_green,color_blue);
}
void PS_StoreAvgLumaF(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float Stored : SV_Target0, out float3 Shared : SV_Target1)
{
Stored = tex2D(SamplerAvgLumG,texcoord).x;
Shared = (CAFlare(texcoord) + tex2D(SamplerPastFlare,texcoord).rgb) ;
}
float3 ShaderGlammor(float2 texcoord)
{ float DM;
float3 Color = BB(texcoord).rgb, FBloom = (CAFlare(texcoord) + tex2D(SamplerPastFlare,texcoord).rgb) ;
//Gamma Correction
Color = pow(abs(Color),2.2);
//Bloom
Color = Color + FBloom;
Color = pow(abs(Color),rcp(2.2));
return Color;
}
void Past_Flare(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 Stored : SV_Target)
{
Stored = CAFlare(texcoord);
}
void A1(float2 texcoord,float PosX,float PosY,inout float I, inout float N, inout float F, inout float O)
{
float PosXI = 0.0155+PosX, PosYI = 0.004+PosY, PosYII = 0.008+PosY;I = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosY)) < float2(0.003,0.001));I += all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYI)) < float2(0.000625,0.005));I += all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYII)) < float2(0.003,0.001));
float PosXN = 0.0225+PosX, PosYN = 0.005+PosY,offsetN = -0.001;N = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN)) < float2(0.002,0.004));N -= all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN - offsetN)) < float2(0.003,0.005));
float PosXF = 0.029+PosX, PosYF = 0.004+PosY, offsetF = 0.0005, offsetF1 = 0.001;F = all( abs(float2( texcoord.x -PosXF-offsetF, texcoord.y-PosYF-offsetF1)) < float2(0.002,0.004));F -= all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0025,0.005));F += all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0015,0.00075));
float PosXO = 0.035+PosX, PosYO = 0.004+PosY;O = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.003,0.005));O -= all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.002,0.003));
}
////////////////////////////////////////////////////////Watermark/////////////////////////////////////////////////////////////////////////
float4 OutF(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
float3 Color = ShaderGlammor(texcoord).rgb;
float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y,A,B,C,D,E,F,G,H,I,J,K,L,PosXDot = 0.011+PosX, PosYDot = 0.008+PosY;L = all( abs(float2( texcoord.x -PosXDot, texcoord.y-PosYDot)) < float2(0.00075,0.0015));A0(texcoord,PosX,PosY,A,B,C,D,E,F,G );A1(texcoord,PosX,PosY,H,I,J,K);
return timer <= 12500 ? A+B+C+D+E+F+G+H+I+J+K+L ? 0.02 : float4(Color,1.) : float4(Color,1.);
}
///////////////////////////////////////////////////////////////////ReShade.fxh//////////////////////////////////////////////////////////////////////
void PostProcessVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD)
{// Vertex shader generating a triangle covering the entire screen
texcoord.x = (id == 2) ? 2.0 : 0.0;
texcoord.y = (id == 1) ? 2.0 : 0.0;
position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
}//Using this to make it portable
//*Rendering passes*//
technique Flair
{
pass ColorMap
{
VertexShader = PostProcessVS;
PixelShader = ColorBB;
RenderTarget = TexMBB;
}
pass Past
{
VertexShader = PostProcessVS;
PixelShader = Past_Flare;
RenderTarget = TexFlarePast;
}
pass BrigthColors
{
VertexShader = PostProcessVS;
PixelShader = StoredBB;
RenderTarget = TexBC;
}
pass Star
{
VertexShader = PostProcessVS;
PixelShader = Glammor;
RenderTarget = texFlare;
}
pass Lum
{
VertexShader = PostProcessVS;
PixelShader = LuminanceG;
RenderTarget = texLumF;
}
pass Avg_Lum
{
VertexShader = PostProcessVS;
PixelShader = Average_LuminanceF;
RenderTarget = texAvgLumF;
}
pass StoreAvgLuma
{
VertexShader = PostProcessVS;
PixelShader = PS_StoreAvgLumaF;
RenderTarget0 = TexAvgLumaLastF;
RenderTarget1 = TexFlareShared;
}
#if !exists "DisableFlare.txt"
pass FlareOut
{
VertexShader = PostProcessVS;
PixelShader = OutF;
}
#endif
}