mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +00:00
Fix crt-cyclon and update others (#3240)
* Fix crt-cyclon and update others - Fix some crt-cyclon parameters; - Update bicubic and lanczos3. * Update crt-geom.fx and geom.fx - Added image center X and Y to crt-geom.fx and geom.fx.
This commit is contained in:
parent
b9155ec5ac
commit
91962508fe
|
@ -32,11 +32,8 @@ uniform float SCANLINE <
|
||||||
ui_label = "Scanline Weight";
|
ui_label = "Scanline Weight";
|
||||||
> = 0.3;
|
> = 0.3;
|
||||||
|
|
||||||
uniform float INTERLACE <
|
uniform bool INTERLACE <
|
||||||
ui_type = "drag";
|
ui_type = "radio";
|
||||||
ui_min = 0.0;
|
|
||||||
ui_max = 1.0;
|
|
||||||
ui_step = 1.0;
|
|
||||||
ui_label = "Interlacing On/Off";
|
ui_label = "Interlacing On/Off";
|
||||||
> = 1.0;
|
> = 1.0;
|
||||||
|
|
||||||
|
@ -64,11 +61,8 @@ uniform float MSIZE <
|
||||||
ui_label = "Mask Size";
|
ui_label = "Mask Size";
|
||||||
> = 1.0;
|
> = 1.0;
|
||||||
|
|
||||||
uniform float SLOT <
|
uniform bool SLOT <
|
||||||
ui_type = "drag";
|
ui_type = "radio";
|
||||||
ui_min = 0.0;
|
|
||||||
ui_max = 1.0;
|
|
||||||
ui_step = 1.0;
|
|
||||||
ui_label = "Slot Mask On/Off";
|
ui_label = "Slot Mask On/Off";
|
||||||
> = 1.0;
|
> = 1.0;
|
||||||
|
|
||||||
|
@ -112,11 +106,8 @@ uniform float bogus_geom <
|
||||||
ui_label = " [ GEOMETRY SETTINGS ] ";
|
ui_label = " [ GEOMETRY SETTINGS ] ";
|
||||||
> = 0.0;
|
> = 0.0;
|
||||||
|
|
||||||
uniform float bzl <
|
uniform bool bzl <
|
||||||
ui_type = "drag";
|
ui_type = "radio";
|
||||||
ui_min = 0.0;
|
|
||||||
ui_max = 1.0;
|
|
||||||
ui_step = 1.0;
|
|
||||||
ui_label = "Bezel On/Off";
|
ui_label = "Bezel On/Off";
|
||||||
> = 1.0;
|
> = 1.0;
|
||||||
|
|
||||||
|
@ -148,7 +139,7 @@ uniform float centerx <
|
||||||
ui_type = "drag";
|
ui_type = "drag";
|
||||||
ui_min = -5.0;
|
ui_min = -5.0;
|
||||||
ui_max = 5.0;
|
ui_max = 5.0;
|
||||||
ui_step = 0.0;
|
ui_step = 0.05;
|
||||||
ui_label = "Image Center X";
|
ui_label = "Image Center X";
|
||||||
> = 0.0;
|
> = 0.0;
|
||||||
|
|
||||||
|
@ -176,11 +167,8 @@ uniform float WARPY <
|
||||||
ui_label = "Curvature Vertical";
|
ui_label = "Curvature Vertical";
|
||||||
> = 0.01;
|
> = 0.01;
|
||||||
|
|
||||||
uniform float vig <
|
uniform bool vig <
|
||||||
ui_type = "drag";
|
ui_type = "radio";
|
||||||
ui_min = 0.0;
|
|
||||||
ui_max = 1.0;
|
|
||||||
ui_step = 1.0;
|
|
||||||
ui_label = "Vignette On/Off";
|
ui_label = "Vignette On/Off";
|
||||||
> = 1.0;
|
> = 1.0;
|
||||||
|
|
||||||
|
@ -236,7 +224,7 @@ uniform float BLACK <
|
||||||
ui_type = "drag";
|
ui_type = "drag";
|
||||||
ui_min = -0.20;
|
ui_min = -0.20;
|
||||||
ui_max = 0.20;
|
ui_max = 0.20;
|
||||||
ui_step = 0.0;
|
ui_step = 0.01;
|
||||||
ui_label = "Black Level";
|
ui_label = "Black Level";
|
||||||
> = 0.0;
|
> = 0.0;
|
||||||
|
|
||||||
|
@ -250,9 +238,9 @@ uniform float RG <
|
||||||
|
|
||||||
uniform float RB <
|
uniform float RB <
|
||||||
ui_type = "drag";
|
ui_type = "drag";
|
||||||
ui_min = 0.0;
|
ui_min = -0.25;
|
||||||
ui_max = -0.25;
|
ui_max = 0.25;
|
||||||
ui_step = 0.2;
|
ui_step = 0.01;
|
||||||
ui_label = "Blue <-to-> Red Hue";
|
ui_label = "Blue <-to-> Red Hue";
|
||||||
> = 0.0;
|
> = 0.0;
|
||||||
|
|
||||||
|
@ -323,9 +311,10 @@ uniform float2 NormalizedInternalPixelSize < source = "normalized_internal_pixel
|
||||||
uniform float2 NormalizedNativePixelSize < source = "normalized_native_pixel_size"; >;
|
uniform float2 NormalizedNativePixelSize < source = "normalized_native_pixel_size"; >;
|
||||||
uniform float UpscaleMultiplier < source = "upscale_multiplier"; >;
|
uniform float UpscaleMultiplier < source = "upscale_multiplier"; >;
|
||||||
uniform float2 ViewportSize < source = "viewportsize"; >;
|
uniform float2 ViewportSize < source = "viewportsize"; >;
|
||||||
|
|
||||||
|
|
||||||
uniform int FrameCount < source = "framecount"; >;
|
uniform int FrameCount < source = "framecount"; >;
|
||||||
|
|
||||||
|
sampler2D sBackBuffer{Texture=ReShade::BackBufferTex;AddressU=BORDER;AddressV=BORDER;AddressW=BORDER;MagFilter=LINEAR;MinFilter=LINEAR;MipFilter=LINEAR;};
|
||||||
|
|
||||||
texture tBezel < source = "crt-cyclon/bezel.png"; >
|
texture tBezel < source = "crt-cyclon/bezel.png"; >
|
||||||
{
|
{
|
||||||
Width = BUFFER_WIDTH;
|
Width = BUFFER_WIDTH;
|
||||||
|
@ -442,8 +431,9 @@ uniform float2 BufferHeight < source = "bufferheight"; >;
|
||||||
|
|
||||||
float4 CRT_CYCLON_PS(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD0) : SV_Target
|
float4 CRT_CYCLON_PS(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD0) : SV_Target
|
||||||
{
|
{
|
||||||
float4 SourceSize = float4(1.0 / (NormalizedInternalPixelSize * UpscaleMultiplier), NormalizedInternalPixelSize * UpscaleMultiplier);
|
float4 SourceSize = float4(1.0 / NormalizedNativePixelSize, NormalizedNativePixelSize);
|
||||||
float2 OutputSize = ViewportSize;
|
float2 OutputSize = ViewportSize;
|
||||||
|
|
||||||
float2 scale = BufferViewportRatio.xy;
|
float2 scale = BufferViewportRatio.xy;
|
||||||
float2 warpcoords = (vTexCoord-float2(0.5,0.5)) * BufferViewportRatio + float2(0.5,0.5);
|
float2 warpcoords = (vTexCoord-float2(0.5,0.5)) * BufferViewportRatio + float2(0.5,0.5);
|
||||||
|
|
||||||
|
@ -458,7 +448,7 @@ float3x3 hue = float3x3(
|
||||||
float4 bez = float4(0.0,0.0,0.0,0.0);
|
float4 bez = float4(0.0,0.0,0.0,0.0);
|
||||||
// if (bzl == 1.0) bez = tex2D(sBezel,vTexCoord*SourceSize.xy/OriginalSize.xy*0.97+float2(0.015,0.015));
|
// if (bzl == 1.0) bez = tex2D(sBezel,vTexCoord*SourceSize.xy/OriginalSize.xy*0.97+float2(0.015,0.015));
|
||||||
// if (bzl == 1.0) bez = tex2D(sBezel,vTexCoord*scale*0.97+float2(0.015,0.015));
|
// if (bzl == 1.0) bez = tex2D(sBezel,vTexCoord*scale*0.97+float2(0.015,0.015));
|
||||||
if (bzl == 1.0) bez = tex2D(sBezel,warpcoords*0.97+float2(0.015,0.015)); // This fix Bezel to adjust to Game's aspect ratio.
|
if (bzl == true) bez = tex2D(sBezel,warpcoords*0.97+float2(0.015,0.015)); // This fix Bezel to adjust to Game's aspect ratio.
|
||||||
|
|
||||||
bez.rgb = lerp(bez.rgb, float3(ambient,ambient,ambient),0.5);
|
bez.rgb = lerp(bez.rgb, float3(ambient,ambient,ambient),0.5);
|
||||||
|
|
||||||
|
@ -473,10 +463,10 @@ float3x3 hue = float3x3(
|
||||||
pos.x = lerp(pos.x, i.x*ps.x, 0.2);
|
pos.x = lerp(pos.x, i.x*ps.x, 0.2);
|
||||||
|
|
||||||
// Convergence
|
// Convergence
|
||||||
float3 res0 = tex2D(ReShade::BackBuffer,pos).rgb;
|
float3 res0 = tex2D(sBackBuffer,pos).rgb;
|
||||||
float resr = tex2D(ReShade::BackBuffer,pos + dx*CONV_R).r;
|
float resr = tex2D(sBackBuffer,pos + dx*CONV_R).r;
|
||||||
float resb = tex2D(ReShade::BackBuffer,pos + dx*CONV_B).b;
|
float resb = tex2D(sBackBuffer,pos + dx*CONV_B).b;
|
||||||
float resg = tex2D(ReShade::BackBuffer,pos + dx*CONV_G).g;
|
float resg = tex2D(sBackBuffer,pos + dx*CONV_G).g;
|
||||||
|
|
||||||
float3 res = float3( res0.r*(1.0-C_STR) + resr*C_STR,
|
float3 res = float3( res0.r*(1.0-C_STR) + resr*C_STR,
|
||||||
res0.g*(1.0-C_STR) + resg*C_STR,
|
res0.g*(1.0-C_STR) + resg*C_STR,
|
||||||
|
@ -484,7 +474,7 @@ float3x3 hue = float3x3(
|
||||||
);
|
);
|
||||||
// Vignette
|
// Vignette
|
||||||
float x = 0.0;
|
float x = 0.0;
|
||||||
if (vig == 1.0){
|
if (vig == true){
|
||||||
x = vTexCoord.x*scale.x-0.5;
|
x = vTexCoord.x*scale.x-0.5;
|
||||||
// x = vTexCoord.x-0.5;
|
// x = vTexCoord.x-0.5;
|
||||||
x = x*x;}
|
x = x*x;}
|
||||||
|
@ -508,7 +498,7 @@ float3x3 hue = float3x3(
|
||||||
{
|
{
|
||||||
s = frac(bpos.y*SourceSize.y/2.0-0.5);
|
s = frac(bpos.y*SourceSize.y/2.0-0.5);
|
||||||
// if (INTERLACE == 1.0) s = mod(float(FrameCount),2.0) < 1.0 ? s: s+0.5;
|
// if (INTERLACE == 1.0) s = mod(float(FrameCount),2.0) < 1.0 ? s: s+0.5;
|
||||||
if (INTERLACE == 1.0) s = (float(FrameCount) % 2.0) < 1.0 ? s: s+0.5;
|
if (INTERLACE == true) s = (float(FrameCount) % 2.0) < 1.0 ? s: s+0.5;
|
||||||
}
|
}
|
||||||
// Calculate CRT-Geom scanlines weight and apply
|
// Calculate CRT-Geom scanlines weight and apply
|
||||||
float weight = scanlineWeights(s, res, x);
|
float weight = scanlineWeights(s, res, x);
|
||||||
|
@ -521,7 +511,7 @@ float3x3 hue = float3x3(
|
||||||
float CGWG = lerp(Maskl, Maskh, l);
|
float CGWG = lerp(Maskl, Maskh, l);
|
||||||
res *= Mask(xy, CGWG);
|
res *= Mask(xy, CGWG);
|
||||||
// Apply slot mask on top of Trinitron-like mask
|
// Apply slot mask on top of Trinitron-like mask
|
||||||
if (SLOT == 1.0) res *= lerp(slot(xy/2.0),float3(1.0,1.0,1.0),CGWG);
|
if (SLOT == true) res *= lerp(slot(xy/2.0),float3(1.0,1.0,1.0),CGWG);
|
||||||
|
|
||||||
if (POTATO == 0.0) res = inv_gamma(res,pwr);
|
if (POTATO == 0.0) res = inv_gamma(res,pwr);
|
||||||
else {res = sqrt(res); res *= lerp(1.3,1.1,l);}
|
else {res = sqrt(res); res *= lerp(1.3,1.1,l);}
|
||||||
|
@ -536,7 +526,7 @@ float3x3 hue = float3x3(
|
||||||
res -= float3(BLACK,BLACK,BLACK);
|
res -= float3(BLACK,BLACK,BLACK);
|
||||||
res *= blck;
|
res *= blck;
|
||||||
// Apply bezel code, adapted from New-Pixie
|
// Apply bezel code, adapted from New-Pixie
|
||||||
if (bzl >0.0)
|
if (bzl == true)
|
||||||
res.rgb = lerp(res.rgb, lerp(max(res.rgb, 0.0), pow( abs(bez.rgb), float3( 1.4,1.4,1.4 ) ), bez.w * bez.w), float3( 1.0,1.0,1.0 ) );
|
res.rgb = lerp(res.rgb, lerp(max(res.rgb, 0.0), pow( abs(bez.rgb), float3( 1.4,1.4,1.4 ) ), bez.w * bez.w), float3( 1.0,1.0,1.0 ) );
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,22 @@ uniform float overscan_y <
|
||||||
ui_label = "CRTGeom Vert. Overscan %";
|
ui_label = "CRTGeom Vert. Overscan %";
|
||||||
> = 100.0;
|
> = 100.0;
|
||||||
|
|
||||||
|
uniform float centerx <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = -9.99;
|
||||||
|
ui_max = 9.99;
|
||||||
|
ui_step = 0.01;
|
||||||
|
ui_label = "Image Center X";
|
||||||
|
> = 0.00;
|
||||||
|
|
||||||
|
uniform float centery <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = -9.99;
|
||||||
|
ui_max = 9.99;
|
||||||
|
ui_step = 0.01;
|
||||||
|
ui_label = "Image Center Y";
|
||||||
|
> = 0.00;
|
||||||
|
|
||||||
uniform float DOTMASK <
|
uniform float DOTMASK <
|
||||||
ui_type = "drag";
|
ui_type = "drag";
|
||||||
ui_min = 0.0;
|
ui_min = 0.0;
|
||||||
|
@ -273,6 +289,15 @@ float3 vs_maxscale(float2 sinangle, float2 cosangle)
|
||||||
return float3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
|
return float3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Code snippet borrowed from crt-cyclon. (credits to DariusG)
|
||||||
|
float2 Warp(float2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0 - 1.0;
|
||||||
|
pos *= float2(1.0 + pos.y*pos.y*0, 1.0 + pos.x*pos.x*0);
|
||||||
|
pos = pos*0.5 + 0.5;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Vertex shader generating a triangle covering the entire screen
|
// Vertex shader generating a triangle covering the entire screen
|
||||||
|
@ -282,6 +307,9 @@ void VS_CRT_Geom(in uint id : SV_VertexID, out float4 position : SV_Position, ou
|
||||||
texcoord.y = (id == 1) ? 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);
|
position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||||
|
|
||||||
|
// center screen
|
||||||
|
texcoord = Warp(texcoord - float2(centerx,centery)/100.0);
|
||||||
|
|
||||||
float2 SourceSize = 1.0/NormalizedNativePixelSize;
|
float2 SourceSize = 1.0/NormalizedNativePixelSize;
|
||||||
float2 OutputSize = ViewportSize*BufferViewportRatio;
|
float2 OutputSize = ViewportSize*BufferViewportRatio;
|
||||||
|
|
||||||
|
@ -453,6 +481,7 @@ float fwidth(float value){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float4 PS_CRT_Geom(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD, in ST_VertexOut vVARS) : SV_Target
|
float4 PS_CRT_Geom(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD, in ST_VertexOut vVARS) : SV_Target
|
||||||
{
|
{
|
||||||
// Here's a helpful diagram to keep in mind while trying to
|
// Here's a helpful diagram to keep in mind while trying to
|
||||||
|
@ -478,6 +507,7 @@ float4 PS_CRT_Geom(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD, in ST_
|
||||||
|
|
||||||
// Texture coordinates of the texel containing the active pixel.
|
// Texture coordinates of the texel containing the active pixel.
|
||||||
float2 xy;
|
float2 xy;
|
||||||
|
|
||||||
if (CURVATURE > 0.5)
|
if (CURVATURE > 0.5)
|
||||||
xy = transform(vTexCoord, vVARS.sinangle, vVARS.cosangle, vVARS.stretch);
|
xy = transform(vTexCoord, vVARS.sinangle, vVARS.cosangle, vVARS.stretch);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../ReShade.fxh"
|
#include "ReShade.fxh"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bicubic multipass Shader
|
Bicubic multipass Shader
|
||||||
|
@ -86,19 +86,18 @@ float3 bicubic_ar(float fp, float3 C0, float3 C1, float3 C2, float3 C3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float4 PS_Bicubic_X(float4 pos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
float4 PS_Bicubic_X(float4 vpos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
||||||
{
|
{
|
||||||
// Both dimensions are unfiltered, so it looks for lores pixels.
|
// Both dimensions are unfiltered, so it looks for lores pixels.
|
||||||
float2 ps = NormalizedNativePixelSize;
|
float2 ps = NormalizedNativePixelSize;
|
||||||
float2 posi = uv_tx.xy + ps * float2(0.5, 0.0);
|
float2 pos = uv_tx.xy/ps - float2(0.5, 0.0);
|
||||||
float2 fp = frac(posi / ps);
|
float2 tc = (floor(pos) + float2(0.5, 0.5)) * ps;
|
||||||
|
float2 fp = frac(pos);
|
||||||
|
|
||||||
float2 tc = posi - (fp + 0.5) * ps;
|
float3 C0 = tex2D(ReShade::BackBuffer, tc + ps*float2(-1.0, 0.0)).rgb;
|
||||||
|
float3 C1 = tex2D(ReShade::BackBuffer, tc + ps*float2( 0.0, 0.0)).rgb;
|
||||||
float3 C0 = tex2D(ReShade::BackBuffer, tc + ps*float2(-1.0, 1.0)).rgb;
|
float3 C2 = tex2D(ReShade::BackBuffer, tc + ps*float2( 1.0, 0.0)).rgb;
|
||||||
float3 C1 = tex2D(ReShade::BackBuffer, tc + ps*float2( 0.0, 1.0)).rgb;
|
float3 C3 = tex2D(ReShade::BackBuffer, tc + ps*float2( 2.0, 0.0)).rgb;
|
||||||
float3 C2 = tex2D(ReShade::BackBuffer, tc + ps*float2( 1.0, 1.0)).rgb;
|
|
||||||
float3 C3 = tex2D(ReShade::BackBuffer, tc + ps*float2( 2.0, 1.0)).rgb;
|
|
||||||
|
|
||||||
float3 color = bicubic_ar(fp.x, C0, C1, C2, C3);
|
float3 color = bicubic_ar(fp.x, C0, C1, C2, C3);
|
||||||
|
|
||||||
|
@ -106,28 +105,27 @@ float4 PS_Bicubic_X(float4 pos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Targe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float4 PS_Bicubic_Y(float4 pos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
float4 PS_Bicubic_Y(float4 vpos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
||||||
{
|
{
|
||||||
// One must be careful here. Horizontal dimension is already filtered, so it looks for x in hires.
|
// One must be careful here. Horizontal dimension is already filtered, so it looks for x in hires.
|
||||||
float2 ps = float2(1.0/(ViewportSize.x*BufferToViewportRatio.x), NormalizedNativePixelSize.y);
|
float2 ps = float2(1.0/(ViewportSize.x*BufferToViewportRatio.x), NormalizedNativePixelSize.y);
|
||||||
float2 posi = uv_tx.xy + ps * float2(0.5, 0.5);
|
float2 pos = uv_tx.xy/ps - float2(0.0, 0.5);
|
||||||
float2 fp = frac(posi / ps);
|
float2 tc = (floor(pos) + float2(0.5, 0.5)) * ps;
|
||||||
|
float2 fp = frac(pos);
|
||||||
|
|
||||||
float2 tc = posi - (fp + 0.5) * ps;
|
float3 C0 = tex2D(sBicubic_P0, tc + ps*float2(0.0, -1.0)).rgb;
|
||||||
|
float3 C1 = tex2D(sBicubic_P0, tc + ps*float2(0.0, 0.0)).rgb;
|
||||||
float3 C0 = tex2D(sBicubic_P0, tc + ps*float2(1.0, -1.0)).rgb;
|
float3 C2 = tex2D(sBicubic_P0, tc + ps*float2(0.0, 1.0)).rgb;
|
||||||
float3 C1 = tex2D(sBicubic_P0, tc + ps*float2(1.0, 0.0)).rgb;
|
float3 C3 = tex2D(sBicubic_P0, tc + ps*float2(0.0, 2.0)).rgb;
|
||||||
float3 C2 = tex2D(sBicubic_P0, tc + ps*float2(1.0, 1.0)).rgb;
|
|
||||||
float3 C3 = tex2D(sBicubic_P0, tc + ps*float2(1.0, 2.0)).rgb;
|
|
||||||
|
|
||||||
float3 color = bicubic_ar(fp.y, C0, C1, C2, C3);
|
float3 color = bicubic_ar(fp.y, C0, C1, C2, C3);
|
||||||
|
|
||||||
return float4(color, 1.0);
|
return float4(color, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
technique Bicubic
|
technique Bicubic
|
||||||
{
|
{
|
||||||
|
|
||||||
pass
|
pass
|
||||||
{
|
{
|
||||||
VertexShader = PostProcessVS;
|
VertexShader = PostProcessVS;
|
||||||
|
@ -139,5 +137,4 @@ technique Bicubic
|
||||||
VertexShader = PostProcessVS;
|
VertexShader = PostProcessVS;
|
||||||
PixelShader = PS_Bicubic_Y;
|
PixelShader = PS_Bicubic_Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
http://www.gnu.org/copyleft/gpl.html
|
http://www.gnu.org/copyleft/gpl.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
uniform bool LANCZOS3_ANTI_RINGING <
|
uniform bool LANCZOS3_ANTI_RINGING <
|
||||||
ui_type = "radio";
|
ui_type = "radio";
|
||||||
ui_label = "Lanczos3 Anti-Ringing";
|
ui_label = "Lanczos3 Anti-Ringing";
|
||||||
|
@ -41,6 +40,7 @@ uniform float2 ViewportSize < source = "viewportsize"; >;
|
||||||
texture2D tLanczos3_P0{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA8;};
|
texture2D tLanczos3_P0{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA8;};
|
||||||
sampler2D sLanczos3_P0{Texture=tLanczos3_P0;AddressU=CLAMP;AddressV=CLAMP;AddressW=CLAMP;MagFilter=POINT;MinFilter=POINT;};
|
sampler2D sLanczos3_P0{Texture=tLanczos3_P0;AddressU=CLAMP;AddressV=CLAMP;AddressW=CLAMP;MagFilter=POINT;MinFilter=POINT;};
|
||||||
|
|
||||||
|
|
||||||
#define AR_STRENGTH 1.0
|
#define AR_STRENGTH 1.0
|
||||||
#define FIX(c) (max(abs(c),1e-5))
|
#define FIX(c) (max(abs(c),1e-5))
|
||||||
#define PI 3.1415926535897932384626433832795
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
@ -48,10 +48,10 @@ sampler2D sLanczos3_P0{Texture=tLanczos3_P0;AddressU=CLAMP;AddressV=CLAMP;Addres
|
||||||
|
|
||||||
float3 weight3(float x)
|
float3 weight3(float x)
|
||||||
{
|
{
|
||||||
float3 Sample = FIX(2.0 * PI * float3(x - 1.5, x - 0.5, x + 0.5));
|
float3 Sampling = FIX(2.0 * PI * float3(x - 1.5, x - 0.5, x + 0.5));
|
||||||
|
|
||||||
// Lanczos3. Note: we normalize outside this function, so no point in multiplying by radius.
|
// Lanczos3. Note: we normalize outside this function, so no point in multiplying by radius.
|
||||||
return sin(Sample) * sin(Sample / radius) / (Sample * Sample);
|
return sin(Sampling) * sin(Sampling / radius) / (Sampling * Sampling);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 lanczos3ar(float fp, float3 C0, float3 C1, float3 C2, float3 C3, float3 C4, float3 C5)
|
float3 lanczos3ar(float fp, float3 C0, float3 C1, float3 C2, float3 C3, float3 C4, float3 C5)
|
||||||
|
@ -79,23 +79,21 @@ float3 lanczos3ar(float fp, float3 C0, float3 C1, float3 C2, float3 C3, float3 C
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float4 PS_Lanczos3_X(float4 pos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
|
||||||
|
float4 PS_Lanczos3_X(float4 vpos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
||||||
{
|
{
|
||||||
// Both dimensions are unfiltered, so it looks for lores pixels.
|
// Both dimensions are unfiltered, so it looks for lores pixels.
|
||||||
float2 ps = NormalizedNativePixelSize;
|
float2 ps = NormalizedNativePixelSize;
|
||||||
float2 posi = uv_tx.xy + ps * float2(0.5, 0.0);
|
float2 pos = uv_tx.xy/ps - float2(0.5, 0.0);
|
||||||
float2 fp = frac(posi / ps);
|
float2 tc = (floor(pos) + float2(0.5, 0.5)) * ps;
|
||||||
|
float2 fp = frac(pos);
|
||||||
|
|
||||||
float2 xystart = posi - (fp + 0.5) * ps;
|
float3 C0 = tex2D(ReShade::BackBuffer, tc + ps*float2(-2.0, 0.0)).rgb;
|
||||||
|
float3 C1 = tex2D(ReShade::BackBuffer, tc + ps*float2(-1.0, 0.0)).rgb;
|
||||||
float ypos = xystart.y + ps.y;
|
float3 C2 = tex2D(ReShade::BackBuffer, tc + ps*float2( 0.0, 0.0)).rgb;
|
||||||
|
float3 C3 = tex2D(ReShade::BackBuffer, tc + ps*float2( 1.0, 0.0)).rgb;
|
||||||
float3 C0 = tex2D(ReShade::BackBuffer, float2(xystart.x - ps.x * 2.0, ypos)).rgb;
|
float3 C4 = tex2D(ReShade::BackBuffer, tc + ps*float2( 2.0, 0.0)).rgb;
|
||||||
float3 C1 = tex2D(ReShade::BackBuffer, float2(xystart.x - ps.x * 1.0, ypos)).rgb;
|
float3 C5 = tex2D(ReShade::BackBuffer, tc + ps*float2( 3.0, 0.0)).rgb;
|
||||||
float3 C2 = tex2D(ReShade::BackBuffer, float2(xystart.x , ypos)).rgb;
|
|
||||||
float3 C3 = tex2D(ReShade::BackBuffer, float2(xystart.x + ps.x * 1.0, ypos)).rgb;
|
|
||||||
float3 C4 = tex2D(ReShade::BackBuffer, float2(xystart.x + ps.x * 2.0, ypos)).rgb;
|
|
||||||
float3 C5 = tex2D(ReShade::BackBuffer, float2(xystart.x + ps.x * 3.0, ypos)).rgb;
|
|
||||||
|
|
||||||
float3 color = lanczos3ar(fp.x, C0, C1, C2, C3, C4, C5);
|
float3 color = lanczos3ar(fp.x, C0, C1, C2, C3, C4, C5);
|
||||||
|
|
||||||
|
@ -103,32 +101,29 @@ float4 PS_Lanczos3_X(float4 pos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Targ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float4 PS_Lanczos3_Y(float4 pos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
float4 PS_Lanczos3_Y(float4 vpos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
|
||||||
{
|
{
|
||||||
// One must be careful here. Horizontal dimension is already filtered, so it looks for x in hires.
|
// One must be careful here. Horizontal dimension is already filtered, so it looks for x in hires.
|
||||||
float2 ps = float2(1.0/(ViewportSize.x*BufferToViewportRatio.x), NormalizedNativePixelSize.y);
|
float2 ps = float2(1.0/(ViewportSize.x*BufferToViewportRatio.x), NormalizedNativePixelSize.y);
|
||||||
float2 posi = uv_tx.xy + ps * float2(0.5, 0.5);
|
float2 pos = uv_tx.xy/ps - float2(0.0, 0.5);
|
||||||
float2 fp = frac(posi / ps);
|
float2 tc = (floor(pos) + float2(0.5, 0.5)) * ps;
|
||||||
|
float2 fp = frac(pos);
|
||||||
|
|
||||||
float2 xystart = posi - (fp + 0.5) * ps;
|
float3 C0 = tex2D(sLanczos3_P0, tc + ps*float2(0.0, -2.0)).rgb;
|
||||||
|
float3 C1 = tex2D(sLanczos3_P0, tc + ps*float2(0.0, -1.0)).rgb;
|
||||||
float xpos = xystart.x + ps.x;
|
float3 C2 = tex2D(sLanczos3_P0, tc + ps*float2(0.0, 0.0)).rgb;
|
||||||
|
float3 C3 = tex2D(sLanczos3_P0, tc + ps*float2(0.0, 1.0)).rgb;
|
||||||
float3 C0 = tex2D(sLanczos3_P0, float2(xpos, xystart.y - ps.y * 2.0)).rgb;
|
float3 C4 = tex2D(sLanczos3_P0, tc + ps*float2(0.0, 2.0)).rgb;
|
||||||
float3 C1 = tex2D(sLanczos3_P0, float2(xpos, xystart.y - ps.y * 1.0)).rgb;
|
float3 C5 = tex2D(sLanczos3_P0, tc + ps*float2(0.0, 3.0)).rgb;
|
||||||
float3 C2 = tex2D(sLanczos3_P0, float2(xpos, xystart.y )).rgb;
|
|
||||||
float3 C3 = tex2D(sLanczos3_P0, float2(xpos, xystart.y + ps.y * 1.0)).rgb;
|
|
||||||
float3 C4 = tex2D(sLanczos3_P0, float2(xpos, xystart.y + ps.y * 2.0)).rgb;
|
|
||||||
float3 C5 = tex2D(sLanczos3_P0, float2(xpos, xystart.y + ps.y * 3.0)).rgb;
|
|
||||||
|
|
||||||
float3 color = lanczos3ar(fp.y, C0, C1, C2, C3, C4, C5);
|
float3 color = lanczos3ar(fp.y, C0, C1, C2, C3, C4, C5);
|
||||||
|
|
||||||
return float4(color, 1.0);
|
return float4(color, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
technique Lanczos3
|
technique Lanczos3
|
||||||
{
|
{
|
||||||
|
|
||||||
pass
|
pass
|
||||||
{
|
{
|
||||||
VertexShader = PostProcessVS;
|
VertexShader = PostProcessVS;
|
||||||
|
@ -140,5 +135,4 @@ technique Lanczos3
|
||||||
VertexShader = PostProcessVS;
|
VertexShader = PostProcessVS;
|
||||||
PixelShader = PS_Lanczos3_Y;
|
PixelShader = PS_Lanczos3_Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uniform float geom_curvature <
|
uniform bool geom_curvature <
|
||||||
ui_type = "drag";
|
ui_type = "radio";
|
||||||
ui_min = 0.0;
|
|
||||||
ui_max = 1.0;
|
|
||||||
ui_step = 1.0;
|
|
||||||
ui_label = "Geom Curvature Toggle";
|
ui_label = "Geom Curvature Toggle";
|
||||||
> = 1.0;
|
> = 1.0;
|
||||||
|
|
||||||
|
@ -56,11 +53,8 @@ uniform float geom_d <
|
||||||
ui_label = "Geom Distance";
|
ui_label = "Geom Distance";
|
||||||
> = 1.5;
|
> = 1.5;
|
||||||
|
|
||||||
uniform float geom_invert_aspect <
|
uniform bool geom_invert_aspect <
|
||||||
ui_type = "drag";
|
ui_type = "radio";
|
||||||
ui_min = 0.0;
|
|
||||||
ui_max = 1.0;
|
|
||||||
ui_step = 1.0;
|
|
||||||
ui_label = "Geom Curvature Aspect Inversion";
|
ui_label = "Geom Curvature Aspect Inversion";
|
||||||
> = 0.0;
|
> = 0.0;
|
||||||
|
|
||||||
|
@ -112,6 +106,22 @@ uniform float geom_overscan_y <
|
||||||
ui_label = "Geom Vert. Overscan %";
|
ui_label = "Geom Vert. Overscan %";
|
||||||
> = 100.0;
|
> = 100.0;
|
||||||
|
|
||||||
|
uniform float centerx <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = -9.99;
|
||||||
|
ui_max = 9.99;
|
||||||
|
ui_step = 0.01;
|
||||||
|
ui_label = "Image Center X";
|
||||||
|
> = 0.00;
|
||||||
|
|
||||||
|
uniform float centery <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = -9.99;
|
||||||
|
ui_max = 9.99;
|
||||||
|
ui_step = 0.01;
|
||||||
|
ui_label = "Image Center Y";
|
||||||
|
> = 0.00;
|
||||||
|
|
||||||
uniform float geom_lum <
|
uniform float geom_lum <
|
||||||
ui_type = "drag";
|
ui_type = "drag";
|
||||||
ui_min = 0.5;
|
ui_min = 0.5;
|
||||||
|
@ -164,7 +174,7 @@ sampler2D sBackBuffer{Texture=ReShade::BackBufferTex;AddressU=BORDER;AddressV=BO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// aspect ratio
|
// aspect ratio
|
||||||
#define aspect (geom_invert_aspect>0.5?float2(0.75,1.0):float2(1.0,0.75))
|
#define aspect (geom_invert_aspect==true?float2(0.75,1.0):float2(1.0,0.75))
|
||||||
#define overscan (float2(1.01,1.01));
|
#define overscan (float2(1.01,1.01));
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,6 +238,15 @@ float3 vs_maxscale(float2 sinangle, float2 cosangle)
|
||||||
return float3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
|
return float3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Code snippet borrowed from crt-cyclon. (credits to DariusG)
|
||||||
|
float2 Warp(float2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0 - 1.0;
|
||||||
|
pos *= float2(1.0 + pos.y*pos.y*0, 1.0 + pos.x*pos.x*0);
|
||||||
|
pos = pos*0.5 + 0.5;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Vertex shader generating a triangle covering the entire screen
|
// Vertex shader generating a triangle covering the entire screen
|
||||||
|
@ -237,7 +256,10 @@ void VS_CRT_Geom(in uint id : SV_VertexID, out float4 position : SV_Position, ou
|
||||||
texcoord.y = (id == 1) ? 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);
|
position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
||||||
|
|
||||||
// float2 SourceSize = 1.0/NormalizedNativePixelSize;
|
// center screen
|
||||||
|
texcoord = Warp(texcoord - float2(centerx,centery)/100.0);
|
||||||
|
|
||||||
|
// float2 SourceSize = 1.0/NormalizedNativePixelSize;
|
||||||
float2 SourceSize = ViewportSize*BufferViewportRatio;
|
float2 SourceSize = ViewportSize*BufferViewportRatio;
|
||||||
|
|
||||||
// Precalculate a bunch of useful values we'll need in the fragment
|
// Precalculate a bunch of useful values we'll need in the fragment
|
||||||
|
@ -333,7 +355,7 @@ float4 PS_CRT_Geom(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD, in ST_
|
||||||
// Texture coordinates of the texel containing the active pixel.
|
// Texture coordinates of the texel containing the active pixel.
|
||||||
float2 xy;
|
float2 xy;
|
||||||
|
|
||||||
if (geom_curvature > 0.5)
|
if (geom_curvature == true)
|
||||||
xy = transform(vTexCoord, vVARS.sinangle, vVARS.cosangle, vVARS.stretch);
|
xy = transform(vTexCoord, vVARS.sinangle, vVARS.cosangle, vVARS.stretch);
|
||||||
else
|
else
|
||||||
xy = vTexCoord;
|
xy = vTexCoord;
|
||||||
|
|
Loading…
Reference in a new issue