Still works at least
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
/*------------------.
|
||||
| :: Description :: |
|
||||
'-------------------/
|
||||
|
||||
Filmic Anamorph Sharpen PS (version 1.5.0)
|
||||
|
||||
Copyright:
|
||||
This code © 2018-2023 Jakub Maximilian Fober
|
||||
Some changes by ccritchfield https://github.com/ccritchfield
|
||||
|
||||
License:
|
||||
This work is licensed under the Creative Commons
|
||||
Attribution-ShareAlike 4.0 International License.
|
||||
To view a copy of this license, visit
|
||||
http://creativecommons.org/licenses/by-sa/4.0/
|
||||
*/
|
||||
|
||||
/*--------------.
|
||||
| :: Commons :: |
|
||||
'--------------*/
|
||||
|
||||
#include "ReShade.fxh"
|
||||
#include "ReShadeUI.fxh"
|
||||
#include "ColorConversion.fxh"
|
||||
#include "LinearGammaWorkflow.fxh"
|
||||
|
||||
/*-----------.
|
||||
| :: Menu :: |
|
||||
'-----------*/
|
||||
|
||||
uniform float Strength
|
||||
< __UNIFORM_SLIDER_FLOAT1
|
||||
ui_label = "Strength";
|
||||
ui_min = 0.0; ui_max = 100.0; ui_step = 0.01;
|
||||
> = 60.0;
|
||||
|
||||
uniform float Offset
|
||||
< __UNIFORM_SLIDER_FLOAT1
|
||||
ui_units = " pixel";
|
||||
ui_label = "Radius";
|
||||
ui_tooltip = "High-pass cross offset in pixels";
|
||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
||||
> = 0.1;
|
||||
|
||||
uniform float Clamp
|
||||
< __UNIFORM_SLIDER_FLOAT1
|
||||
ui_label = "Clamping";
|
||||
ui_min = 0.5; ui_max = 1.0; ui_step = 0.001;
|
||||
> = 0.65;
|
||||
|
||||
uniform bool UseMask
|
||||
< __UNIFORM_INPUT_BOOL1
|
||||
ui_label = "Sharpen only center";
|
||||
ui_tooltip = "Sharpen only in center of the image";
|
||||
> = false;
|
||||
|
||||
uniform bool DepthMask
|
||||
< __UNIFORM_INPUT_BOOL1
|
||||
ui_label = "Enable depth rim masking";
|
||||
ui_tooltip = "Depth high-pass mask switch";
|
||||
ui_category = "Depth mask";
|
||||
ui_category_closed = true;
|
||||
> = false;
|
||||
|
||||
uniform int DepthMaskContrast
|
||||
< __UNIFORM_DRAG_INT1
|
||||
ui_label = "Edges mask strength";
|
||||
ui_tooltip = "Depth high-pass mask amount";
|
||||
ui_category = "Depth mask";
|
||||
ui_min = 0; ui_max = 2000; ui_step = 1;
|
||||
> = 128;
|
||||
|
||||
uniform bool Preview
|
||||
< __UNIFORM_INPUT_BOOL1
|
||||
ui_label = "Preview sharpen layer";
|
||||
ui_tooltip = "Preview sharpen layer and mask for adjustment.\n"
|
||||
"If you don't see red strokes,\n"
|
||||
"try changing Preprocessor Definitions in the Settings tab.";
|
||||
ui_category = "Debug View";
|
||||
ui_category_closed = true;
|
||||
> = false;
|
||||
|
||||
/*---------------.
|
||||
| :: Textures :: |
|
||||
'---------------*/
|
||||
|
||||
// Define screen texture with mirror tiles
|
||||
sampler BackBuffer
|
||||
{
|
||||
Texture = ReShade::BackBufferTex;
|
||||
AddressU = MIRROR;
|
||||
AddressV = MIRROR;
|
||||
};
|
||||
|
||||
/*----------------.
|
||||
| :: Functions :: |
|
||||
'----------------*/
|
||||
|
||||
// Overlay blending mode
|
||||
float Overlay(float LayerA, float LayerB)
|
||||
{
|
||||
float MinA = min(LayerA, 0.5);
|
||||
float MinB = min(LayerB, 0.5);
|
||||
float MaxA = max(LayerA, 0.5);
|
||||
float MaxB = max(LayerB, 0.5);
|
||||
return 2f*(MinA*MinB+MaxA+MaxB-MaxA*MaxB)-1.5;
|
||||
}
|
||||
|
||||
// Overlay blending mode for one input
|
||||
float Overlay(float LayerAB)
|
||||
{
|
||||
float MinAB = min(LayerAB, 0.5);
|
||||
float MaxAB = max(LayerAB, 0.5);
|
||||
return 2f*(MinAB*MinAB+MaxAB+MaxAB-MaxAB*MaxAB)-1.5;
|
||||
}
|
||||
|
||||
/*--------------.
|
||||
| :: Shaders :: |
|
||||
'--------------*/
|
||||
|
||||
// Sharpen pass
|
||||
float3 FilmicAnamorphSharpenPS(
|
||||
float4 pos : SV_Position,
|
||||
float2 UvCoord : TEXCOORD
|
||||
) : SV_Target
|
||||
{
|
||||
// Sample display image
|
||||
float3 Source = GammaConvert::to_linear(tex2D(BackBuffer, UvCoord).rgb);
|
||||
|
||||
// Generate radial mask
|
||||
float Mask;
|
||||
if (UseMask)
|
||||
{
|
||||
// Generate radial mask
|
||||
Mask = 1f-length(UvCoord*2f-1f);
|
||||
Mask = Overlay(Mask) * Strength;
|
||||
// Bypass
|
||||
if (Mask<=0) return GammaConvert::to_display(Source);
|
||||
}
|
||||
else Mask = Strength;
|
||||
|
||||
// Get pixel size
|
||||
float2 Pixel = BUFFER_PIXEL_SIZE;
|
||||
|
||||
if (DepthMask)
|
||||
{
|
||||
/*
|
||||
// original
|
||||
float2 DepthPixel = Pixel*Offset+Pixel;
|
||||
Pixel *= Offset;
|
||||
*/
|
||||
|
||||
// !!! calc pixel*offset once, use twice
|
||||
float2 PixelOffset = Pixel * Offset;
|
||||
float2 DepthPixel = PixelOffset + Pixel;
|
||||
Pixel = PixelOffset;
|
||||
|
||||
// Sample display depth image
|
||||
float SourceDepth = ReShade::GetLinearizedDepth(UvCoord);
|
||||
|
||||
float2 NorSouWesEst[4] = {
|
||||
float2(UvCoord.x, UvCoord.y + Pixel.y),
|
||||
float2(UvCoord.x, UvCoord.y - Pixel.y),
|
||||
float2(UvCoord.x + Pixel.x, UvCoord.y),
|
||||
float2(UvCoord.x - Pixel.x, UvCoord.y)
|
||||
};
|
||||
|
||||
float2 DepthNorSouWesEst[4] = {
|
||||
float2(UvCoord.x, UvCoord.y + DepthPixel.y),
|
||||
float2(UvCoord.x, UvCoord.y - DepthPixel.y),
|
||||
float2(UvCoord.x + DepthPixel.x, UvCoord.y),
|
||||
float2(UvCoord.x - DepthPixel.x, UvCoord.y)
|
||||
};
|
||||
|
||||
// Luma high-pass color
|
||||
// Luma high-pass depth
|
||||
float HighPassColor = 0f, DepthMask = 0f;
|
||||
|
||||
[unroll]for(int s=0; s<4; s++)
|
||||
{
|
||||
HighPassColor +=
|
||||
ColorConvert::RGB_to_Luma(
|
||||
GammaConvert::to_linear(
|
||||
tex2D(BackBuffer, NorSouWesEst[s]).rgb
|
||||
));
|
||||
DepthMask +=
|
||||
ReShade::GetLinearizedDepth(NorSouWesEst[s])
|
||||
+ReShade::GetLinearizedDepth(DepthNorSouWesEst[s]);
|
||||
}
|
||||
|
||||
HighPassColor = 0.5-0.5*(HighPassColor*0.25-ColorConvert::RGB_to_Luma(Source));
|
||||
|
||||
DepthMask = 1f-DepthMask*0.125+SourceDepth;
|
||||
DepthMask = min(1f, DepthMask)+1f-max(1f, DepthMask);
|
||||
DepthMask = saturate(DepthMaskContrast*DepthMask+1f-DepthMaskContrast);
|
||||
|
||||
// Sharpen strength
|
||||
HighPassColor = lerp(0.5, HighPassColor, Mask*DepthMask);
|
||||
|
||||
// Clamping sharpen
|
||||
/*
|
||||
// original
|
||||
HighPassColor = Clamp!=1f ? max(min(HighPassColor, Clamp), 1f-Clamp) : HighPassColor;
|
||||
*/
|
||||
|
||||
// !!! Clamp in settings above is restricted to 0.5 to 1.0
|
||||
// !!! 1.0 - Clamp is the low value, while Clamp is the high value
|
||||
// !!! so we can literally just use the clamp() func instead of min/max.
|
||||
// !!! not sure if author was trying to take advantage of some kind of
|
||||
// !!! compiler "cheat" using min/max instead of clamp to improve
|
||||
// !!! performance. doesn't make sense to min/max otherwise.
|
||||
HighPassColor = Clamp!=1f ? clamp(HighPassColor, 1f-Clamp, Clamp ) : HighPassColor;
|
||||
|
||||
float3 Sharpen = float3(
|
||||
Overlay(Source.r, HighPassColor),
|
||||
Overlay(Source.g, HighPassColor),
|
||||
Overlay(Source.b, HighPassColor)
|
||||
);
|
||||
|
||||
if(Preview) // Preview mode ON
|
||||
{
|
||||
float PreviewChannel = lerp(HighPassColor, HighPassColor*DepthMask, 0.5);
|
||||
return
|
||||
GammaConvert::to_display(float3(
|
||||
1f-DepthMask * (1f-HighPassColor),
|
||||
PreviewChannel,
|
||||
PreviewChannel
|
||||
));
|
||||
}
|
||||
|
||||
return GammaConvert::to_display(Sharpen);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pixel *= Offset;
|
||||
|
||||
float2 NorSouWesEst[4] = {
|
||||
float2(UvCoord.x, UvCoord.y + Pixel.y),
|
||||
float2(UvCoord.x, UvCoord.y - Pixel.y),
|
||||
float2(UvCoord.x + Pixel.x, UvCoord.y),
|
||||
float2(UvCoord.x - Pixel.x, UvCoord.y)
|
||||
};
|
||||
|
||||
// Luma high-pass color
|
||||
float HighPassColor = 0f;
|
||||
[unroll] for(uint s=0u; s<4u; s++)
|
||||
HighPassColor +=
|
||||
ColorConvert::RGB_to_Luma(
|
||||
GammaConvert::to_linear(
|
||||
tex2D(BackBuffer, NorSouWesEst[s]).rgb
|
||||
));
|
||||
|
||||
// !!! added space above to make it more obvious
|
||||
// !!! that loop is now a one-liner in this else branch
|
||||
// !!! where-as loop in branch above was multi-part
|
||||
HighPassColor = 0.5-0.5*(HighPassColor*0.25-ColorConvert::RGB_to_Luma(Source));
|
||||
|
||||
// Sharpen strength
|
||||
HighPassColor = lerp(0.5, HighPassColor, Mask);
|
||||
|
||||
// Clamping sharpen
|
||||
/*
|
||||
// original
|
||||
HighPassColor = Clamp!=1f ? max(min(HighPassColor, Clamp), 1f-Clamp) : HighPassColor;
|
||||
*/
|
||||
|
||||
// !!! Clamp in settings above is restricted to 0.5 to 1.0
|
||||
// !!! 1.0 - Clamp is the low value, while Clamp is the high value
|
||||
// !!! so we can literally just use the clamp() func instead of min/max.
|
||||
// !!! not sure if author was trying to take advantage of some kind of
|
||||
// !!! compiler "cheat" using min/max instead of clamp to improve
|
||||
// !!! performance. doesn't make sense to min/max otherwise.
|
||||
HighPassColor = Clamp!=1f ? clamp(HighPassColor, 1f-Clamp, Clamp) : HighPassColor;
|
||||
|
||||
float3 Sharpen = float3(
|
||||
Overlay(Source.r, HighPassColor),
|
||||
Overlay(Source.g, HighPassColor),
|
||||
Overlay(Source.b, HighPassColor)
|
||||
);
|
||||
|
||||
return GammaConvert::to_display(
|
||||
Preview // preview mode ON
|
||||
? HighPassColor
|
||||
: Sharpen
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------.
|
||||
| :: Output :: |
|
||||
'-------------*/
|
||||
|
||||
technique FilmicAnamorphSharpen
|
||||
<
|
||||
ui_label = "Filmic Anamorphic Sharpen";
|
||||
ui_tooltip =
|
||||
"This effect © 2018-2023 Jakub Maksymilian Fober\n"
|
||||
"Licensed under CC BY-SA 4.0";
|
||||
>
|
||||
{
|
||||
pass
|
||||
{
|
||||
VertexShader = PostProcessVS;
|
||||
PixelShader = FilmicAnamorphSharpenPS;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user