From 54f25d709aa7e209bf4203dfa557ad5e54430275 Mon Sep 17 00:00:00 2001 From: hunterk Date: Sun, 4 Jun 2023 17:02:27 -0500 Subject: [PATCH] update crt-guest --- crt/crt-guest-advanced-hd.slangp | 43 ++-- .../crt-guest-advanced-ntsc-pass1.slang | 8 +- .../crt-guest-advanced-ntsc-pass2.slang | 52 ++--- .../guest/advanced/crt-guest-advanced.slang | 54 ++--- .../guest/advanced/deconvergence-ntsc.slang | 183 +++++++++++------ .../guest/advanced/deconvergence.slang | 175 ++++++++++------ .../guest/advanced/gaussian_horizontal.slang | 19 +- .../guest/advanced/linearize-ntsc.slang | 8 +- crt/shaders/guest/advanced/linearize.slang | 8 +- .../guest/advanced/ntsc/ntsc-pass1.slang | 7 +- .../guest/advanced/ntsc/ntsc-pass2.slang | 10 +- .../advanced/pre-shaders-afterglow.slang | 2 +- .../guest/fast/crt-guest-advanced-pass1.slang | 5 +- .../guest/fast/crt-guest-advanced-pass2.slang | 42 +--- .../fast/crt-guest-advanced-pass2f.slang | 116 ++++++----- crt/shaders/guest/fast/deconvergence-f.slang | 152 ++++++++------ crt/shaders/guest/fast/linearize.slang | 8 +- crt/shaders/guest/fast/linearizef.slang | 7 +- crt/shaders/guest/fast/pre-shaders.slang | 2 +- crt/shaders/guest/fast/pre-shadersf.slang | 2 +- crt/shaders/guest/hd/bloom_horizontal.slang | 8 +- crt/shaders/guest/hd/bloom_vertical.slang | 6 +- .../hd/crt-guest-advanced-hd-pass1.slang | 12 +- .../hd/crt-guest-advanced-hd-pass2.slang | 58 ++---- crt/shaders/guest/hd/deconvergence-hd.slang | 188 ++++++++++++------ .../guest/hd/gaussian_horizontal.slang | 133 +++++++++++++ crt/shaders/guest/hd/gaussian_vertical.slang | 98 +++++++++ crt/shaders/guest/hd/linearize-hd.slang | 6 +- .../guest/hd/pre-shaders-afterglow.slang | 4 +- 29 files changed, 903 insertions(+), 513 deletions(-) create mode 100644 crt/shaders/guest/hd/gaussian_horizontal.slang create mode 100644 crt/shaders/guest/hd/gaussian_vertical.slang diff --git a/crt/crt-guest-advanced-hd.slangp b/crt/crt-guest-advanced-hd.slangp index 13812ca..3f6e98b 100644 --- a/crt/crt-guest-advanced-hd.slangp +++ b/crt/crt-guest-advanced-hd.slangp @@ -1,4 +1,4 @@ -shaders = 10 +shaders = 12 textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png @@ -50,7 +50,7 @@ scale_y5 = 1.0 float_framebuffer5 = true alias5 = Pass1 -shader6 = shaders/guest/hd/bloom_horizontal.slang +shader6 = shaders/guest/hd/gaussian_horizontal.slang filter_linear6 = true scale_type_x6 = absolute scale_x6 = 800.0 @@ -58,24 +58,41 @@ scale_type_y6 = source scale_y6 = 1.0 float_framebuffer6 = true -shader7 = shaders/guest/hd/bloom_vertical.slang +shader7 = shaders/guest/hd/gaussian_vertical.slang filter_linear7 = true -scale_type_x7 = source -scale_x7 = 1.0 +scale_type_x7 = absolute +scale_x7 = 800.0 scale_type_y7 = absolute scale_y7 = 600.0 float_framebuffer7 = true -alias7 = BloomPass +alias7 = GlowPass -shader8 = shaders/guest/hd/crt-guest-advanced-hd-pass2.slang +shader8 = shaders/guest/hd/bloom_horizontal.slang filter_linear8 = true +scale_type_x8 = absolute +scale_x8 = 800.0 +scale_type_y8 = source +scale_y8 = 1.0 float_framebuffer8 = true -scale_type8 = viewport -scale_x8 = 1.0 -scale_y8 = 1.0 -shader9 = shaders/guest/hd/deconvergence-hd.slang +shader9 = shaders/guest/hd/bloom_vertical.slang filter_linear9 = true -scale_type9 = viewport +scale_type_x9 = source scale_x9 = 1.0 -scale_y9 = 1.0 +scale_type_y9 = absolute +scale_y9 = 600.0 +float_framebuffer9 = true +alias9 = BloomPass + +shader10 = shaders/guest/hd/crt-guest-advanced-hd-pass2.slang +filter_linear10 = true +float_framebuffer10 = true +scale_type10 = viewport +scale_x10 = 1.0 +scale_y10 = 1.0 + +shader11 = shaders/guest/hd/deconvergence-hd.slang +filter_linear11 = true +scale_type11 = viewport +scale_x11 = 1.0 +scale_y11 = 1.0 diff --git a/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass1.slang b/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass1.slang index 0706cdc..ba2ea5c 100644 --- a/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass1.slang +++ b/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass1.slang @@ -3,7 +3,7 @@ /* CRT - Guest - NTSC - Pass1 - Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com + Copyright (C) 2018-2023 guest(r) - guest.r@gmail.com Incorporates many good ideas and suggestions from Dr. Venom. I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader. @@ -37,6 +37,7 @@ layout(push_constant) uniform Push float HSHARP; float spike; float internal_res; + float MAXS; } params; layout(std140, set = 0, binding = 0) uniform UBO @@ -59,6 +60,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter HSHARP " Sharpness Definition" 1.2 0.0 2.0 0.10 #define HSHARP params.HSHARP +#pragma parameter MAXS " Maximum Sharpness" 0.15 0.0 0.30 0.01 +#define MAXS params.MAXS + #pragma parameter HARNG " Substractive Sharpness Ringing" 0.4 0.0 4.0 0.10 #define HARNG params.HARNG @@ -116,7 +120,7 @@ void main() vec3 cmax = 0.0.xxx; vec3 cmin = 1.0.xxx; float sharp = gaussian(hsharpness) * S_SHARP; - float maxsharp = 0.20; + float maxsharp = MAXS; float FPR = hsharpness; float fpx = 0.0; float sp = 0.0; diff --git a/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass2.slang b/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass2.slang index 97b8013..e9b61a0 100644 --- a/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass2.slang +++ b/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass2.slang @@ -3,7 +3,7 @@ /* CRT - Guest - Advanced - NTSC - Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com + Copyright (C) 2018-2023 guest(r) - guest.r@gmail.com Incorporates many good ideas and suggestions from Dr. Venom. I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader. @@ -27,7 +27,7 @@ layout(push_constant) uniform Push { float IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, - h_sharp, s_sharp, warpX, warpY, glow, shadowMask, masksize, vertmask, ring, no_scanlines; + h_sharp, s_sharp, warpX, warpY, glow, shadowMask, masksize, ring, no_scanlines; } params; layout(std140, set = 0, binding = 0) uniform UBO @@ -58,7 +58,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 -#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 +#pragma parameter glow " (Magic) Glow Strength" 0.08 -2.0 2.0 0.01 #define glow params.glow // Glow Strength #pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05 @@ -87,7 +87,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0 #define gsl params.gsl // Alternate scanlines -#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5 +#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 40.0 0.5 #define scanline1 params.scanline1 // scanline param, vertical sharpness #pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 70.0 1.0 @@ -96,19 +96,16 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 10.0 0.05 #define beam_min params.beam_min // dark area beam min - narrow -#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025 +#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.2 3.5 0.025 #define beam_max params.beam_max // bright area beam max - wide #pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05 #define beam_size params.beam_size // increased max. beam size -#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1 -#define vertmask params.vertmask // Scanline deconvergence colors - #pragma parameter scans " Scanline Saturation / Mask Falloff" 0.50 -5.0 5.0 0.10 #define scans global.scans // scanline saturation -#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.20 2.0 0.05 +#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.10 2.0 0.05 #define scan_falloff global.scan_falloff // scanline falloff #pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05 @@ -117,7 +114,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter rolling_scan " Rolling Scanlines" 0.0 -1.0 1.0 0.01 #define rolling_scan global.rolling_scan // rolling scanlines -#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.0 1.0 +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 #define no_scanlines params.no_scanlines #pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0 @@ -243,7 +240,7 @@ void main() float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = ((intera < 0.5) || (no_scanlines > 0.025)); float SourceY = SourceSize.y; float sy = 1.0; @@ -285,11 +282,12 @@ void main() float f = fp.y; vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps; - pC4.x = pos.x; - if (interb) pC4.y = pos.y; + pC4.x = pos.x; if (global.intres == 0.5 && prescalex < 1.5) pC4.y = floor(pC4.y * global.OriginalSize.y)*global.OriginalSize.w + 0.5*global.OriginalSize.w; + if (interb && no_scanlines < 0.025) pC4.y = pos.y; else if (interb) pC4.y = pC4.y + smoothstep(0.40-0.5*no_scanlines, 0.60 + 0.5*no_scanlines, f)*SourceSize.w; + vec3 color1 = COMPAT_TEXTURE(Pass1, pC4 ).rgb; vec3 scolor1 = COMPAT_TEXTURE(Pass1, pC4 ).aaa; @@ -358,33 +356,7 @@ if (!interb) w1 = pow(w1, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref1, scanpow1))); w2 = pow(w2, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref2, scanpow2))); - // Scanline Deconvergence - - vec3 cd1 = one; vec3 cd2 = one; - -if (abs(vertmask) > 0.025) -{ - float vm = sqrt(abs(vertmask)); - float v_high1 = 1.0 + 0.3*vm; - float v_high2 = 1.0 + 0.6*vm; - float v_low = 1.0 - vm; - - float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0); - float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0); - - if (vertmask < 0.0) - { - cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1); - cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2); - } - else - { - cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1); - cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2); - } -} - - color = (gc(color1)*w1*cd1 + gc(color2)*w2*cd2)/mix(1.0.xxx, w1+w2, no_scanlines); + color = (gc(color1)*w1 + gc(color2)*w2); if (abs(rolling_scan) > 0.005) { diff --git a/crt/shaders/guest/advanced/crt-guest-advanced.slang b/crt/shaders/guest/advanced/crt-guest-advanced.slang index 84e64c0..9bacab6 100644 --- a/crt/shaders/guest/advanced/crt-guest-advanced.slang +++ b/crt/shaders/guest/advanced/crt-guest-advanced.slang @@ -3,7 +3,7 @@ /* CRT - Guest - Advanced - Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com + Copyright (C) 2018-2023 guest(r) - guest.r@gmail.com Incorporates many good ideas and suggestions from Dr. Venom. I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader. @@ -27,7 +27,7 @@ layout(push_constant) uniform Push { float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, - h_sharp, s_sharp, csize, bsize1, warpX, warpY, glow, vertmask, spike, ring, no_scanlines; + h_sharp, s_sharp, csize, bsize1, warpX, warpY, glow, spike, ring, no_scanlines; } params; layout(std140, set = 0, binding = 0) uniform UBO @@ -58,7 +58,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 -#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 +#pragma parameter glow " (Magic) Glow Strength" 0.08 -2.0 2.0 0.01 #define glow params.glow // Glow Strength #pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05 @@ -87,7 +87,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0 #define gsl params.gsl // Alternate scanlines -#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5 +#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 40.0 0.5 #define scanline1 params.scanline1 // scanline param, vertical sharpness #pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 70.0 1.0 @@ -96,19 +96,16 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 10.0 0.05 #define beam_min params.beam_min // dark area beam min - narrow -#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025 +#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.2 3.5 0.025 #define beam_max params.beam_max // bright area beam max - wide #pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05 #define beam_size params.beam_size // increased max. beam size -#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1 -#define vertmask params.vertmask // Scanline deconvergence colors - #pragma parameter scans " Scanline Saturation / Mask Falloff" 0.5 -5.0 5.0 0.10 #define scans global.scans // scanline saturation -#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.20 2.0 0.05 +#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.15 2.0 0.05 #define scan_falloff global.scan_falloff // scanline falloff #pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10 @@ -120,7 +117,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05 #define scangamma global.scangamma -#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.0 1.0 +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 #define no_scanlines params.no_scanlines #pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0 @@ -268,7 +265,7 @@ void main() float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = ((intera < 0.5) || (no_scanlines > 0.025)); bool notate = (TATE < 0.5); float SourceY = mix(SourceSize.y, SourceSize.x, TATE); @@ -330,12 +327,13 @@ void main() if (global.intres == 0.5 && notate && prescalex.y < 1.5) pC4.y = floor(pC4.y * global.OriginalSize.y)*global.OriginalSize.w + 0.5*global.OriginalSize.w; if (global.intres == 0.5 && !notate && prescalex.x < 1.5) pC4.x = floor(pC4.x * global.OriginalSize.x)*global.OriginalSize.z + 0.5*global.OriginalSize.z; - if (interb) pC4.y = pos.y; + if (interb && no_scanlines < 0.025) pC4.y = pos.y; else if (interb) pC4.y = pC4.y + smoothstep(0.40-0.5*no_scanlines, 0.60 + 0.5*no_scanlines, f)*mix(SourceSize.w, SourceSize.z, TATE); float zero = exp2(-h_sharp); float sharp1 = s_sharp * zero; - float fdivider = max(min(mix(prescalex.x, prescalex.y,TATE), 2.0), 1.5*float(interb)); + float idiv = clamp(mix(SourceSize.x, SourceSize.y, TATE) / 400.0, 1.0, 2.0); + float fdivider = max(min(mix(prescalex.x, prescalex.y,TATE), 2.0), idiv*float(interb)); float wl3 = (2.0 + fpx)/fdivider; float wl2 = (1.0 + fpx)/fdivider; @@ -373,7 +371,7 @@ void main() c2 = max(c2 - sth, 0.0); } - vec3 l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, colmin, colmax; + vec3 l3, l2, l1, r1, r2, r3, color1, color2, colmin, colmax; l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb; l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb; @@ -518,33 +516,7 @@ if (!interb) w1 = pow(w1, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref1, scanpow1))); w2 = pow(w2, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref2, scanpow2))); - // Scanline Deconvergence - - vec3 cd1 = one; vec3 cd2 = one; - -if (abs(vertmask) > 0.025) -{ - float vm = sqrt(abs(vertmask)); - float v_high1 = 1.0 + 0.3*vm; - float v_high2 = 1.0 + 0.6*vm; - float v_low = 1.0 - vm; - - float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0); - float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0); - - if (vertmask < 0.0) - { - cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1); - cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2); - } - else - { - cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1); - cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2); - } -} - - color = (gc(color1)*w1*cd1 + gc(color2)*w2*cd2)/mix(1.0.xxx, w1+w2, no_scanlines); + color = (gc(color1)*w1 + gc(color2)*w2); if (abs(rolling_scan) > 0.005) { diff --git a/crt/shaders/guest/advanced/deconvergence-ntsc.slang b/crt/shaders/guest/advanced/deconvergence-ntsc.slang index 41269eb..0099eeb 100644 --- a/crt/shaders/guest/advanced/deconvergence-ntsc.slang +++ b/crt/shaders/guest/advanced/deconvergence-ntsc.slang @@ -3,7 +3,7 @@ /* CRT - Guest - Advanced - Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com + Copyright (C) 2018-2023 guest(r) - guest.r@gmail.com Incorporates many good ideas and suggestions from Dr. Venom. I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader. @@ -69,15 +69,32 @@ layout(std140, set = 0, binding = 0) uniform UBO float maskboost; float smoothmask; float gamma_c; - float m_glow; + float m_glow; + float m_glow_low; + float m_glow_high; + float m_glow_dist; + float m_glow_mask; + float smask_mit; + float mask_zoom; + float no_scanlines; } global; +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 + #pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 #pragma parameter m_glow " Ordinary Glow / Magic Glow" 0.0 0.0 1.0 1.0 -#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 +#pragma parameter m_glow_low " Magic Glow Low Strength" 0.35 0.0 7.0 0.05 + +#pragma parameter m_glow_high " Magic Glow High Strength" 5.0 0.0 7.0 0.10 + +#pragma parameter m_glow_dist " Magic Glow Distribution" 1.0 0.20 4.0 0.05 + +#pragma parameter m_glow_mask " Magic Glow Mask Strength" 1.0 0.0 2.0 0.025 + +#pragma parameter glow " (Magic) Glow Strength" 0.08 -2.0 2.0 0.01 #define glow params.glow // Glow Strength #pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05 @@ -159,6 +176,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0 #define masksize params.masksize // Mask Size +#pragma parameter mask_zoom " CRT Mask Zoom (+ mask width)" 0.0 -4.0 4.0 1.0 +#define mask_zoom global.mask_zoom // Mask Size + #pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 #define maskDark params.maskDark // Dark "Phosphor" @@ -180,14 +200,14 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05 #define slotmask1 params.slotmask1 -#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0 +#pragma parameter slotwidth " Slot Mask Width (0:Auto)" 0.0 0.0 16.0 1.0 #define slotwidth params.slotwidth // Slot Mask Width -#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0 +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 2.0 1.0 4.0 1.0 #define double_slot params.double_slot // Slot Mask Height -#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0 -#define slotms global.slotms // Slot Mask Size +#pragma parameter slotms " Slot Mask Thickness" 1.0 1.0 4.0 1.0 +#define slotms global.slotms // Slot Mask Thickness #pragma parameter mclip " Keep Mask effect with clipping" 0.0 0.0 1.0 0.05 #define mclip global.mclip // @@ -195,6 +215,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter smoothmask " Smooth Masks in bright scanlines" 0.0 0.0 1.0 1.0 #define smoothmask global.smoothmask +#pragma parameter smask_mit " Mitigate Slotmask Interaction" 0.0 0.0 1.0 0.05 +#define smask_mit global.smask_mit + #pragma parameter gamma_out " Gamma out" 1.95 1.0 5.0 0.05 #define gamma_out global.gamma_out // output gamma @@ -261,31 +284,19 @@ layout(set = 0, binding = 7) uniform sampler2D Source; vec3 Mask(vec2 pos, float mx, float mb) { - vec2 pos0 = pos; - pos.y = floor(pos.y/masksize); - float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; - float next_line = float(fract((pos.y/stagg_lvl)*0.5) > 0.25); - pos0.x = (mshift > -0.25) ? (pos0.x + next_line * floor(mshift)) : (pos0.x + floor(pos.y / stagg_lvl) * floor(abs(mshift))); - pos = floor(pos0/masksize); - vec3 mask = vec3(maskDark, maskDark, maskDark); vec3 one = vec3(1.0); - // brightness correcture masks 5-12 - float sm = 0.45; if(shadowMask == 8.0 || shadowMask == 11.0 || shadowMask == 13.0) sm = 0.7; - float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - sm, 0.0) + 1.0, 1.0, mx); - - float mc = 1.0 - max(maskstr, 0.0); - // No mask if (shadowMask == -1.0) { - mask = vec3(1.0); + mask = one; } // Phosphor. else if (shadowMask == 0.0) { + float mc = 1.0 - max(maskstr, 0.0); pos.x = fract(pos.x*0.5); if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } else { mask.r = mc; mask.g = 1.0; mask.b = mc; } @@ -302,23 +313,23 @@ vec3 Mask(vec2 pos, float mx, float mb) if (fract((pos.y + odd)/2.0) < 0.49) line = maskDark; - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; - mask*=line; + mask*=line; } // Aperture-grille. else if (shadowMask == 2.0) { - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; } // Stretched VGA style shadow mask (same as prior shaders). @@ -329,7 +340,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // VGA style shadow mask. @@ -341,7 +352,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // Trinitron mask 5 @@ -354,18 +365,18 @@ vec3 Mask(vec2 pos, float mx, float mb) mask.b = 1.0; } else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Trinitron mask 6 else if (shadowMask == 6.0) { mask = vec3(0.0); - pos.x = fract(pos.x/3.0); - if (pos.x < 0.3) mask.r = 1.0; - else if (pos.x < 0.6) mask.g = 1.0; + pos.x = floor(mod(pos.x,3.0)); + if (pos.x < 0.5) mask.r = 1.0; + else if (pos.x < 1.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 7 @@ -377,7 +388,7 @@ vec3 Mask(vec2 pos, float mx, float mb) { mask = 0.0.xxx; } else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 8 @@ -388,7 +399,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask = 1.0.xxx; else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Magenta - Green - Black mask @@ -399,7 +410,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask.rb = 1.0.xx; else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RGBX @@ -411,7 +422,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.r = 1.0; else if (pos.x < 0.7) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -423,7 +434,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.rg = 1.0.xx; else if (pos.x < 0.7) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RRGGBBX mask @@ -435,7 +446,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 2.5) mask.r = 1.0; else if (pos.x < 4.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -449,27 +460,28 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 3.5) mask.rgb = 1.0.xxx; else if (pos.x < 4.5) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } + if (mask_layout > 0.5) mask = mask.rbg; float maskmin = min(min(mask.r,mask.g),mask.b); return (mask - maskmin) * (1.0 + (maskboost-1.0)*mb) + maskmin; } -float SlotMask(vec2 pos, float m) + +float SlotMask(vec2 pos, float m, float swidth) { if ((slotmask + slotmask1) == 0.0) return 1.0; else { - if (shadowMask == 2.0 || shadowMask == 6.0) pos.x = pos.x + slotms; - pos = floor(pos/slotms); - float mlen = slotwidth*2.0; - float px = fract(pos.x/mlen); + pos.y = floor(pos.y/slotms); + float mlen = swidth*2.0; + float px = floor(mod(pos.x, 0.99999*mlen)); float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot); float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m); float slot = 1.0; - if (py == 0.0 && px < 0.5) slot = slot_dark; else - if (py == double_slot && px >= 0.5) slot = slot_dark; + if (py == 0.0 && px < swidth) slot = slot_dark; else + if (py == double_slot && px >= swidth) slot = slot_dark; return slot; } @@ -607,7 +619,7 @@ void main() float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = (intera < 0.5 || global.no_scanlines > 0.025); // Calculating texel coordinates @@ -662,12 +674,50 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob vec3 orig1 = color; vec3 cmask = one; - vec2 maskcoord = gl_FragCoord.xy * 1.000001; + vec2 maskcoord = gl_FragCoord.xy * 1.00001; - float smask = SlotMask(maskcoord, mx); + vec2 scoord = maskcoord; + + // mask widths and mask dark compensate (fractional part) values + + float mwidths[14] = float[14] (2.0, 3.0, 3.0, 3.0, 6.0, 2.4, 3.5, 2.4, 3.25, 3.5, 4.5, 4.25, 7.5, 6.25); + + float mwidth = mwidths[int(shadowMask)]; + float mask_compensate = fract(mwidth); + mwidth = floor(mwidth) * masksize; + float swidth = mwidth; + bool zoomed = (abs(mask_zoom) > 0.75); + float mscale = 1.0; + vec2 maskcoord0 = maskcoord; + maskcoord.y = floor(maskcoord.y/masksize); + +if ( abs(mshift) > 0.75 ) +{ + float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; + float next_line = float(fract((maskcoord.y/stagg_lvl)*0.5) > 0.25); + maskcoord0.x = (mshift > -0.25) ? (maskcoord0.x + next_line * floor(mshift)) : (maskcoord0.x + floor(maskcoord.y / stagg_lvl) * floor(abs(mshift))); +} + maskcoord = maskcoord0/masksize; if (mask_zoom >= 0.0) maskcoord = floor(maskcoord); + +if ( !zoomed ) cmask*= Mask(maskcoord, mx, mb); +else{ + float mwidth1 = max(mwidth + mask_zoom, 2.0); + mscale = mwidth1/mwidth; + float mlerp = fract(maskcoord.x/mscale); + float mcoord = floor(maskcoord.x/mscale); if (shadowMask == 12.0 && mask_zoom == -2.0) mcoord = ceil(maskcoord.x/mscale); + cmask*=mix(Mask(vec2(mcoord,maskcoord.y), mx, mb), Mask(vec2(mcoord + 1.0, maskcoord.y), mx, mb), mlerp); +} + + if (slotwidth > 0.5) swidth = slotwidth; float smask = 1.0; + + float sm_offset = 0.0; bool bsm_offset = (shadowMask == 0.0 || shadowMask == 2.0 || shadowMask == 5.0 || shadowMask == 6.0 || shadowMask == 8.0 || shadowMask == 11.0); + if( zoomed ) { if (mask_layout < 0.5 && bsm_offset) sm_offset = 1.0; else if (bsm_offset) sm_offset = -1.0; } - if (mask_layout > 0.5) cmask = cmask.rbg; + swidth = round(swidth*mscale); + smask = SlotMask(scoord + vec2(sm_offset,0.0), mx, swidth); + + smask = clamp(smask + mix(smask_mit, 0.0, min(w3, pow(w3*max(max(orig1.r,orig1.g),orig1.b), 0.33333))), 0.0, 1.0); cmask*=smask; vec3 cmask1 = cmask; @@ -687,8 +737,8 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob cmask = min(cmask, 1.0); cmask1 = min(cmask1, 1.0); - float bb = mix(brightboost, brightboost1, mx); - if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 1.0 + mask_compensate, 0.0) + 1.0, 1.0, mx); + float bb = mix(brightboost, brightboost1, mx) * dark_compensate; color*=bb; vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb; @@ -715,24 +765,29 @@ if (abs(bloom) > 0.025) Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx); color = color + 2.0*max((2.0*mix(maxb*maxb, maxb, colmx)-0.5*max(max(Ref.r,Ref.g),Ref.b)),0.25)*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.6)*Bloom*halation; } else - if (halation < 0.01) { + if (halation < -0.01) { float mbl = max(max(Bloom.r,Bloom.g),Bloom.b); Bloom = plant(Bloom + Ref + orig1 + Bloom*Bloom*Bloom, min(mbl*mbl,0.75)); color = color + 2.0*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.5)*Bloom*(-halation); } - + + float w = 0.25 + 0.60*mix(w3, 1.0, sqrt(colmx)); if (smoothmask > 0.5) { w3 = mix(1.0, w3, smoothstep(0.3, 0.6, mx1)); color = max(min(color/w3, 1.0)*w3, min(color,color*(1.0-w3))); } if (global.m_glow < 0.5) Glow = mix(Glow, 0.25*color, 0.7*colmx); else { - vec3 gb = plant(orig1, 1.0); maxb = max(max(Glow.r,Glow.g),Glow.b); - gb = mix(maxb*vec3(0.0, 0.0, 1.0), Glow, clamp(gb.r + gb.g - 0.375*gb.b,0.0,1.0)); - Glow = mix(0.75*Glow,5.0*plant(mix(gb,orig1, 0.5*sqrt(colmx)*abs(plant(Glow,1.0)-plant(orig1,1.0))), maxb), pow(colmx, 0.50/gamma_in)); - Glow = mix(Glow, 0.4*Glow, 1.0-colmx*colmx); + orig1 = plant(orig1 + 0.001*Ref, 1.0); + Bloom = plant(Glow, 1.0); + Ref = abs(orig1-Bloom); + mx0 = max(max(orig1.g,orig1.g),orig1.b)-min(min(orig1.g,orig1.g),orig1.b); + mx2 = max(max(Bloom.g,Bloom.g),Bloom.b)-min(min(Bloom.g,Bloom.g),Bloom.b); + Bloom = mix(maxb*min(Bloom,orig1), w*mix(mix(Glow, max(max(Ref.g,Ref.g),Ref.b)*Glow, max(mx,mx0)), mix(color, Glow, mx2), max(mx0,mx2)*Ref), min(sqrt((1.10-mx0)*(0.10+mx2)),1.0)); + Glow = mix(global.m_glow_low*Glow, global.m_glow_high*Bloom, pow(colmx, global.m_glow_dist/gamma_in)); } - if (glow >= 0.0 && global.m_glow < 0.5) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + abs(glow)*cmask*Glow; } + if (glow >= 0.0 && global.m_glow < 0.5) color = color + 0.5*Glow*glow; + else { if(global.m_glow > 0.5) cmask1 = max(mix(one, cmask1, global.m_glow_mask),0.0); color = color + abs(glow)*cmask1*Glow; } color = min(color, 1.0); diff --git a/crt/shaders/guest/advanced/deconvergence.slang b/crt/shaders/guest/advanced/deconvergence.slang index 592e636..50a8d82 100644 --- a/crt/shaders/guest/advanced/deconvergence.slang +++ b/crt/shaders/guest/advanced/deconvergence.slang @@ -3,7 +3,7 @@ /* CRT - Guest - Advanced - Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com + Copyright (C) 2018-2023 guest(r) - guest.r@gmail.com Incorporates many good ideas and suggestions from Dr. Venom. I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader. @@ -70,14 +70,30 @@ layout(std140, set = 0, binding = 0) uniform UBO float smoothmask; float gamma_c; float m_glow; + float m_glow_low; + float m_glow_high; + float m_glow_dist; + float m_glow_mask; + float smask_mit; + float mask_zoom; + float no_scanlines; } global; +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 #pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 #pragma parameter m_glow " Ordinary Glow / Magic Glow" 0.0 0.0 1.0 1.0 -#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 +#pragma parameter m_glow_low " Magic Glow Low Strength" 0.35 0.0 7.0 0.05 + +#pragma parameter m_glow_high " Magic Glow High Strength" 5.0 0.0 7.0 0.10 + +#pragma parameter m_glow_dist " Magic Glow Distribution" 1.0 0.20 4.0 0.05 + +#pragma parameter m_glow_mask " Magic Glow Mask Strength" 1.0 0.0 2.0 0.025 + +#pragma parameter glow " (Magic) Glow Strength" 0.08 -2.0 2.0 0.01 #define glow params.glow // Glow Strength #pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05 @@ -162,6 +178,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0 #define masksize params.masksize // Mask Size +#pragma parameter mask_zoom " CRT Mask Zoom (+ mask width)" 0.0 -4.0 4.0 1.0 +#define mask_zoom global.mask_zoom // Mask Size + #pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 #define maskDark params.maskDark // Dark "Phosphor" @@ -183,14 +202,14 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05 #define slotmask1 params.slotmask1 -#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0 +#pragma parameter slotwidth " Slot Mask Width (0:Auto)" 0.0 0.0 16.0 1.0 #define slotwidth params.slotwidth // Slot Mask Width -#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0 +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 2.0 1.0 4.0 1.0 #define double_slot params.double_slot // Slot Mask Height -#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0 -#define slotms global.slotms // Slot Mask Size +#pragma parameter slotms " Slot Mask Thickness" 1.0 1.0 4.0 1.0 +#define slotms global.slotms // Slot Mask Thickness #pragma parameter mclip " Keep Mask effect with clipping" 0.0 0.0 1.0 0.05 #define mclip global.mclip // @@ -198,6 +217,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter smoothmask " Smooth Masks in bright scanlines" 0.0 0.0 1.0 1.0 #define smoothmask global.smoothmask +#pragma parameter smask_mit " Mitigate Slotmask Interaction" 0.0 0.0 1.0 0.05 +#define smask_mit global.smask_mit + #pragma parameter gamma_out " Gamma out" 2.4 1.0 5.0 0.05 #define gamma_out global.gamma_out // output gamma @@ -264,31 +286,19 @@ layout(set = 0, binding = 7) uniform sampler2D Source; vec3 Mask(vec2 pos, float mx, float mb) { - vec2 pos0 = pos; - pos.y = floor(pos.y/masksize); - float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; - float next_line = float(fract((pos.y/stagg_lvl)*0.5) > 0.25); - pos0.x = (mshift > -0.25) ? (pos0.x + next_line * floor(mshift)) : (pos0.x + floor(pos.y / stagg_lvl) * floor(abs(mshift))); - pos = floor(pos0/masksize); - vec3 mask = vec3(maskDark, maskDark, maskDark); vec3 one = vec3(1.0); - // brightness correcture masks 5-12 - float sm = 0.45; if(shadowMask == 8.0 || shadowMask == 11.0 || shadowMask == 13.0) sm = 0.7; - float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - sm, 0.0) + 1.0, 1.0, mx); - - float mc = 1.0 - max(maskstr, 0.0); - // No mask if (shadowMask == -1.0) { - mask = vec3(1.0); + mask = one; } // Phosphor. else if (shadowMask == 0.0) { + float mc = 1.0 - max(maskstr, 0.0); pos.x = fract(pos.x*0.5); if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } else { mask.r = mc; mask.g = 1.0; mask.b = mc; } @@ -305,23 +315,23 @@ vec3 Mask(vec2 pos, float mx, float mb) if (fract((pos.y + odd)/2.0) < 0.49) line = maskDark; - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; - mask*=line; + mask*=line; } // Aperture-grille. else if (shadowMask == 2.0) { - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; } // Stretched VGA style shadow mask (same as prior shaders). @@ -332,7 +342,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // VGA style shadow mask. @@ -344,7 +354,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // Trinitron mask 5 @@ -357,18 +367,18 @@ vec3 Mask(vec2 pos, float mx, float mb) mask.b = 1.0; } else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Trinitron mask 6 else if (shadowMask == 6.0) { mask = vec3(0.0); - pos.x = fract(pos.x/3.0); - if (pos.x < 0.3) mask.r = 1.0; - else if (pos.x < 0.6) mask.g = 1.0; + pos.x = floor(mod(pos.x,3.0)); + if (pos.x < 0.5) mask.r = 1.0; + else if (pos.x < 1.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 7 @@ -380,7 +390,7 @@ vec3 Mask(vec2 pos, float mx, float mb) { mask = 0.0.xxx; } else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 8 @@ -391,7 +401,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask = 1.0.xxx; else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Magenta - Green - Black mask @@ -402,7 +412,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask.rb = 1.0.xx; else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RGBX @@ -414,7 +424,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.r = 1.0; else if (pos.x < 0.7) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -426,7 +436,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.rg = 1.0.xx; else if (pos.x < 0.7) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RRGGBBX mask @@ -438,7 +448,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 2.5) mask.r = 1.0; else if (pos.x < 4.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -452,27 +462,28 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 3.5) mask.rgb = 1.0.xxx; else if (pos.x < 4.5) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } + if (mask_layout > 0.5) mask = mask.rbg; float maskmin = min(min(mask.r,mask.g),mask.b); return (mask - maskmin) * (1.0 + (maskboost-1.0)*mb) + maskmin; } -float SlotMask(vec2 pos, float m) + +float SlotMask(vec2 pos, float m, float swidth) { if ((slotmask + slotmask1) == 0.0) return 1.0; else { - if (shadowMask == 2.0 || shadowMask == 6.0) pos.x = pos.x + slotms; - pos = floor(pos/slotms); - float mlen = slotwidth*2.0; - float px = fract(pos.x/mlen); + pos.y = floor(pos.y/slotms); + float mlen = swidth*2.0; + float px = floor(mod(pos.x, 0.99999*mlen)); float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot); float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m); float slot = 1.0; - if (py == 0.0 && px < 0.5) slot = slot_dark; else - if (py == double_slot && px >= 0.5) slot = slot_dark; + if (py == 0.0 && px < swidth) slot = slot_dark; else + if (py == double_slot && px >= swidth) slot = slot_dark; return slot; } @@ -610,7 +621,7 @@ void main() float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = (intera < 0.5 || global.no_scanlines > 0.025); bool notate = (TATE < 0.5); // Calculating texel coordinates @@ -666,14 +677,51 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob vec3 orig1 = color; vec3 cmask = one; - vec2 maskcoord = gl_FragCoord.yx * 1.000001; + vec2 maskcoord = gl_FragCoord.yx * 1.00001; if (notate) maskcoord = maskcoord.yx; + vec2 scoord = maskcoord; - float smask = SlotMask(maskcoord, mx); + // mask widths and mask dark compensate (fractional part) values + + float mwidths[14] = float[14] (2.0, 3.0, 3.0, 3.0, 6.0, 2.4, 3.5, 2.4, 3.25, 3.5, 4.5, 4.25, 7.5, 6.25); + + float mwidth = mwidths[int(shadowMask)]; + float mask_compensate = fract(mwidth); + mwidth = floor(mwidth) * masksize; + float swidth = mwidth; + bool zoomed = (abs(mask_zoom) > 0.75); + float mscale = 1.0; + vec2 maskcoord0 = maskcoord; + maskcoord.y = floor(maskcoord.y/masksize); + +if ( abs(mshift) > 0.75 ) +{ + float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; + float next_line = float(fract((maskcoord.y/stagg_lvl)*0.5) > 0.25); + maskcoord0.x = (mshift > -0.25) ? (maskcoord0.x + next_line * floor(mshift)) : (maskcoord0.x + floor(maskcoord.y / stagg_lvl) * floor(abs(mshift))); +} + maskcoord = maskcoord0/masksize; if (mask_zoom >= 0.0) maskcoord = floor(maskcoord); + +if ( !zoomed ) cmask*= Mask(maskcoord, mx, mb); +else{ + float mwidth1 = max(mwidth + mask_zoom, 2.0); + mscale = mwidth1/mwidth; + float mlerp = fract(maskcoord.x/mscale); + float mcoord = floor(maskcoord.x/mscale); if (shadowMask == 12.0 && mask_zoom == -2.0) mcoord = ceil(maskcoord.x/mscale); + cmask*=mix(Mask(vec2(mcoord,maskcoord.y), mx, mb), Mask(vec2(mcoord + 1.0, maskcoord.y), mx, mb), mlerp); +} - if (mask_layout > 0.5) cmask = cmask.rbg; + if (slotwidth > 0.5) swidth = slotwidth; float smask = 1.0; + float sm_offset = 0.0; bool bsm_offset = (shadowMask == 0.0 || shadowMask == 2.0 || shadowMask == 5.0 || shadowMask == 6.0 || shadowMask == 8.0 || shadowMask == 11.0); + if( zoomed ) { if (mask_layout < 0.5 && bsm_offset) sm_offset = 1.0; else if (bsm_offset) sm_offset = -1.0; } + + swidth = round(swidth*mscale); + smask = SlotMask(scoord + vec2(sm_offset,0.0), mx, swidth); + + smask = clamp(smask + mix(smask_mit, 0.0, min(w3, pow(w3*max(max(orig1.r,orig1.g),orig1.b), 0.33333))), 0.0, 1.0); + cmask*=smask; vec3 cmask1 = cmask; @@ -692,8 +740,8 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob cmask = min(cmask, 1.0); cmask1 = min(cmask1, 1.0); - float bb = mix(brightboost, brightboost1, mx); - if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 1.0 + mask_compensate, 0.0) + 1.0, 1.0, mx); + float bb = mix(brightboost, brightboost1, mx) * dark_compensate; color*=bb; vec3 Ref = COMPAT_TEXTURE(LinearizePass, pos).rgb; @@ -725,19 +773,24 @@ if (abs(bloom) > 0.025) Bloom = plant(Bloom + Ref + orig1 + Bloom*Bloom*Bloom, min(mbl*mbl,0.75)); color = color + 2.0*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.5)*Bloom*(-halation); } + float w = 0.25 + 0.60*mix(w3, 1.0, sqrt(colmx)); if (smoothmask > 0.5) { w3 = mix(1.0, w3, smoothstep(0.3, 0.6, mx1)); color = max(min(color/w3, 1.0)*w3, min(color,color*(1.0-w3))); } if (global.m_glow < 0.5) Glow = mix(Glow, 0.25*color, 0.7*colmx); else { - vec3 gb = plant(orig1, 1.0); maxb = max(max(Glow.r,Glow.g),Glow.b); - gb = mix(maxb*vec3(0.0, 0.0, 1.0), Glow, clamp(gb.r + gb.g - 0.375*gb.b,0.0,1.0)); - Glow = mix(0.75*Glow,5.0*plant(mix(gb,orig1, 0.5*sqrt(colmx)*abs(plant(Glow,1.0)-plant(orig1,1.0))), maxb), pow(colmx, 0.50/gamma_in)); - Glow = mix(Glow, 0.4*Glow, 1.0-colmx*colmx); + orig1 = plant(orig1 + 0.001*Ref, 1.0); + Bloom = plant(Glow, 1.0); + Ref = abs(orig1-Bloom); + mx0 = max(max(orig1.g,orig1.g),orig1.b)-min(min(orig1.g,orig1.g),orig1.b); + mx2 = max(max(Bloom.g,Bloom.g),Bloom.b)-min(min(Bloom.g,Bloom.g),Bloom.b); + Bloom = mix(maxb*min(Bloom,orig1), w*mix(mix(Glow, max(max(Ref.g,Ref.g),Ref.b)*Glow, max(mx,mx0)), mix(color, Glow, mx2), max(mx0,mx2)*Ref), min(sqrt((1.10-mx0)*(0.10+mx2)),1.0)); + Glow = mix(global.m_glow_low*Glow, global.m_glow_high*Bloom, pow(colmx, global.m_glow_dist/gamma_in)); } - if (glow >= 0.0 && global.m_glow < 0.5) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + abs(glow)*cmask*Glow; } + if (glow >= 0.0 && global.m_glow < 0.5) color = color + 0.5*Glow*glow; + else { if(global.m_glow > 0.5) cmask1 = max(mix(one, cmask1, global.m_glow_mask),0.0); color = color + abs(glow)*cmask1*Glow; } color = min(color, 1.0); diff --git a/crt/shaders/guest/advanced/gaussian_horizontal.slang b/crt/shaders/guest/advanced/gaussian_horizontal.slang index 47afc46..3388ff3 100644 --- a/crt/shaders/guest/advanced/gaussian_horizontal.slang +++ b/crt/shaders/guest/advanced/gaussian_horizontal.slang @@ -3,7 +3,7 @@ /* Gaussian blur - horizontal pass, dynamic range, resizable - Copyright (C) 2020-2022 guest(r) - guest.r@gmail.com + Copyright (C) 2020-2023 guest(r) - guest.r@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -31,9 +31,13 @@ layout(push_constant) uniform Push float SIGMA_H; float m_glow; float m_glow_cutoff; + float m_glow_low; + float m_glow_high; + float m_glow_dist; + float m_glow_mask; } params; -#pragma parameter bogus_glow "[ GLOW PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 +#pragma parameter bogus_mglow "[ MAGIC GLOW SETTINGS ]:" 0.0 0.0 1.0 1.0 #pragma parameter m_glow " Ordinary Glow / Magic Glow" 0.0 0.0 1.0 1.0 #define m_glow params.m_glow @@ -41,12 +45,23 @@ layout(push_constant) uniform Push #pragma parameter m_glow_cutoff " Magic Glow Cutoff" 0.12 0.0 0.4 0.01 #define m_glow_cutoff params.m_glow_cutoff +#pragma parameter m_glow_low " Magic Glow Low Strength" 0.35 0.0 7.0 0.05 + +#pragma parameter m_glow_high " Magic Glow High Strength" 5.0 0.0 7.0 0.10 + +#pragma parameter m_glow_dist " Magic Glow Distribution" 1.0 0.20 4.0 0.05 + +#pragma parameter m_glow_mask " Magic Glow Mask Strength" 1.0 0.0 2.0 0.025 + +#pragma parameter bogus_glow "[ GLOW PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 + #pragma parameter SIZEH " Horizontal Glow Radius" 6.0 1.0 50.0 1.0 #define SIZEH params.SIZEH #pragma parameter SIGMA_H " Horizontal Glow Sigma" 1.20 0.20 15.0 0.10 #define SIGMA_H params.SIGMA_H + layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; diff --git a/crt/shaders/guest/advanced/linearize-ntsc.slang b/crt/shaders/guest/advanced/linearize-ntsc.slang index a8daf6e..e757e98 100644 --- a/crt/shaders/guest/advanced/linearize-ntsc.slang +++ b/crt/shaders/guest/advanced/linearize-ntsc.slang @@ -3,7 +3,7 @@ /* Interlacing - Copyright (C) 2020 - 2022 guest(r) - guest.r@gmail.com + Copyright (C) 2020 - 2023 guest(r) - guest.r@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -60,7 +60,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4-5" 1.0 0.0 5.0 1.0 #define interm params.interm // interlace mode -#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05 +#pragma parameter iscan " Interlacing Scanline Effect ('Laced brightness)" 0.20 0.0 1.0 0.05 #define iscan params.iscan // interlacing effect scanlining #pragma parameter intres " Internal Resolution Y: 0.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match @@ -165,8 +165,8 @@ void main() c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r); if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii); } - if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; } - if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; } + if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)) * (1.0-0.5*iscan); } + if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)) * (1.0-0.5*iscan); } } c = pow(c, vec3(gamma_in)); diff --git a/crt/shaders/guest/advanced/linearize.slang b/crt/shaders/guest/advanced/linearize.slang index d59bc8c..eb3190b 100644 --- a/crt/shaders/guest/advanced/linearize.slang +++ b/crt/shaders/guest/advanced/linearize.slang @@ -3,7 +3,7 @@ /* Interlacing - Copyright (C) 2020 - 2022 guest(r) - guest.r@gmail.com + Copyright (C) 2020 - 2023 guest(r) - guest.r@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -61,7 +61,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4-5" 1.0 0.0 5.0 1.0 #define interm params.interm // interlace mode -#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05 +#pragma parameter iscan " Interlacing Scanline Effect ('Laced brightness)" 0.20 0.0 1.0 0.05 #define iscan params.iscan // interlacing effect scanlining #pragma parameter intres " Internal Resolution Y: 0.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match @@ -166,8 +166,8 @@ void main() c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r); if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii); } - if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; } - if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; } + if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)) * (1.0-0.5*iscan); } + if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)) * (1.0-0.5*iscan); } } c = pow(c, vec3(gamma_in)); diff --git a/crt/shaders/guest/advanced/ntsc/ntsc-pass1.slang b/crt/shaders/guest/advanced/ntsc/ntsc-pass1.slang index d305447..15e4e90 100644 --- a/crt/shaders/guest/advanced/ntsc/ntsc-pass1.slang +++ b/crt/shaders/guest/advanced/ntsc/ntsc-pass1.slang @@ -11,13 +11,14 @@ layout(std140, set = 0, binding = 0) uniform UBO vec4 OriginalSize; vec4 SourceSize; uint FrameCount; - float quality, ntsc_sat, cust_fringing, cust_artifacting, ntsc_bright, ntsc_scale, ntsc_fields, ntsc_phase; + float quality, ntsc_sat, cust_fringing, cust_artifacting, ntsc_bright, ntsc_scale, ntsc_fields, ntsc_phase, ntsc_cscale; } global; #pragma parameter quality "NTSC Preset (Svideo=0 Composite=1 RF=2 Custom=-1)" 1.0 -1.0 2.0 1.0 #pragma parameter ntsc_fields "NTSC Merge Fields" 0.0 0.0 1.0 1.0 #pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0 -#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 2.5 0.01 +#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 2.5 0.025 +#pragma parameter ntsc_cscale "NTSC Chroma Scaling / Bleeding" 1.0 0.20 2.25 0.05 #pragma parameter ntsc_sat "NTSC Color Saturation" 1.0 0.0 2.0 0.01 #pragma parameter ntsc_bright "NTSC Brightness" 1.0 0.0 1.5 0.01 #pragma parameter cust_fringing "NTSC Custom Fringing Value" 0.0 0.0 5.0 0.1 @@ -138,7 +139,7 @@ if (MERGE > 0.5) yiq *= mix_mat; // Cross-talk. yiq.yz *= vec2(i_mod, q_mod); // Demodulate. - if (res > 1.025) + if (res > 1.025) { mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ * res; i_mod = cos(mod_phase); diff --git a/crt/shaders/guest/advanced/ntsc/ntsc-pass2.slang b/crt/shaders/guest/advanced/ntsc/ntsc-pass2.slang index 8b5d0bc..d7e4336 100644 --- a/crt/shaders/guest/advanced/ntsc/ntsc-pass2.slang +++ b/crt/shaders/guest/advanced/ntsc/ntsc-pass2.slang @@ -14,11 +14,13 @@ layout(std140, set = 0, binding = 0) uniform UBO float ntsc_phase; float auto_res; float ntsc_ring; + float ntsc_cscale; } global; -#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 2.5 0.01 -#pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0 -#pragma parameter ntsc_ring "NTSC Anti-Ringing" 0.0 0.0 1.0 1.0 +#pragma parameter ntsc_cscale "NTSC Chroma Scaling / Bleeding" 1.0 0.20 2.25 0.05 +#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 2.5 0.025 +#pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0 +#pragma parameter ntsc_ring "NTSC Anti-Ringing" 0.0 0.0 1.0 1.0 #pragma stage vertex layout(location = 0) in vec4 Position; @@ -38,7 +40,7 @@ layout(set = 0, binding = 2) uniform sampler2D Source; vec3 fetch_offset(float offset, float one_x) { - return texture(Source, vTexCoord + vec2((offset) * (one_x), 0.0)).xyz; + return vec3(texture(Source, vTexCoord + vec2((offset) * (one_x), 0.0)).x, texture(Source, vTexCoord + vec2((offset) * (one_x/global.ntsc_cscale), 0.0)).yz); } const mat3 yiq2rgb_mat = mat3( diff --git a/crt/shaders/guest/advanced/pre-shaders-afterglow.slang b/crt/shaders/guest/advanced/pre-shaders-afterglow.slang index 4bd30ac..a2a140a 100644 --- a/crt/shaders/guest/advanced/pre-shaders-afterglow.slang +++ b/crt/shaders/guest/advanced/pre-shaders-afterglow.slang @@ -60,7 +60,7 @@ layout(push_constant) uniform Push #pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0 #define TNTC params.TNTC -#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0 +#pragma parameter LS " LUT Size" 32.0 16.0 64.0 16.0 #define LS params.LS #define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons diff --git a/crt/shaders/guest/fast/crt-guest-advanced-pass1.slang b/crt/shaders/guest/fast/crt-guest-advanced-pass1.slang index e5c8deb..52ebd6c 100644 --- a/crt/shaders/guest/fast/crt-guest-advanced-pass1.slang +++ b/crt/shaders/guest/fast/crt-guest-advanced-pass1.slang @@ -107,8 +107,9 @@ void main() float zero = exp2(-h_sharp); float sharp1 = s_sharp * zero; - - float fdivider = max(min(prescalex.x, 2.0), 1.5*float(interb)); + + float idiv = clamp(SourceSize.x / 400.0, 1.0, 2.0); + float fdivider = max(min(prescalex.x, 2.0), idiv*float(interb)); float wl3 = (2.0 + fpx)/fdivider; float wl2 = (1.0 + fpx)/fdivider; diff --git a/crt/shaders/guest/fast/crt-guest-advanced-pass2.slang b/crt/shaders/guest/fast/crt-guest-advanced-pass2.slang index 7cd3b7b..1bd5147 100644 --- a/crt/shaders/guest/fast/crt-guest-advanced-pass2.slang +++ b/crt/shaders/guest/fast/crt-guest-advanced-pass2.slang @@ -122,7 +122,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0 #define gsl params.gsl // Alternate scanlines -#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5 +#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 40.0 0.5 #define scanline1 params.scanline1 // scanline param, vertical sharpness #pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 70.0 1.0 @@ -131,7 +131,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 10.0 0.05 #define beam_min params.beam_min // dark area beam min - narrow -#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025 +#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.2 3.5 0.025 #define beam_max params.beam_max // bright area beam max - wide #pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05 @@ -143,10 +143,10 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter scans " Scanline Saturation / Mask Falloff" 0.50 -5.0 5.0 0.10 #define scans params.scans // scanline saturation -#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.20 2.0 0.05 +#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.10 2.0 0.05 #define scan_falloff global.scan_falloff // scanline falloff -#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.0 1.0 +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 #define no_scanlines params.no_scanlines #define COMPAT_TEXTURE(c,d) texture(c,d) @@ -234,7 +234,7 @@ void main() vec4 SourceSize = vec4(global.SourceSize.x, global.OriginalSize.y, global.SourceSize.z, global.OriginalSize.w); float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = ((intera < 0.5) || (no_scanlines > 0.025)); float SourceY = SourceSize.y; float sy = 1.0; @@ -274,10 +274,10 @@ void main() pC4.y = floor(OGL2Pos) * ps.y + 0.5*ps.y; pC4.x = pos.x; - - if (interb) pC4.y = pos.y; if (global.intres == 0.5 && prescalex.y < 1.5) pC4.y = floor(pC4.y * global.OriginalSize.y)*global.OriginalSize.w + 0.5*global.OriginalSize.w; + + if (interb && no_scanlines < 0.025) pC4.y = pos.y; else if (interb) pC4.y = pC4.y + smoothstep(0.40-0.5*no_scanlines, 0.60 + 0.5*no_scanlines, f)*SourceSize.w; vec3 color1 = COMPAT_TEXTURE(Pass1, pC4 ).rgb; vec3 scolor1 = COMPAT_TEXTURE(Pass1, pC4 ).aaa; @@ -338,33 +338,7 @@ if (!interb) w1 = pow(w1, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref1, scanpow1))); w2 = pow(w2, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref2, scanpow2))); - // Scanline Deconvergence - - vec3 cd1 = one; vec3 cd2 = one; - -if (abs(vertmask) > 0.025) -{ - float vm = sqrt(abs(vertmask)); - float v_high1 = 1.0 + 0.3*vm; - float v_high2 = 1.0 + 0.6*vm; - float v_low = 1.0 - vm; - - float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0); - float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0); - - if (vertmask < 0.0) - { - cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1); - cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2); - } - else - { - cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1); - cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2); - } -} - - color = (gc(color1)*w1*cd1 + gc(color2)*w2*cd2)/mix(1.0.xxx, w1+w2, no_scanlines); + color = (gc(color1)*w1 + gc(color2)*w2); color = min(color, 1.0); } diff --git a/crt/shaders/guest/fast/crt-guest-advanced-pass2f.slang b/crt/shaders/guest/fast/crt-guest-advanced-pass2f.slang index deaa260..bc50661 100644 --- a/crt/shaders/guest/fast/crt-guest-advanced-pass2f.slang +++ b/crt/shaders/guest/fast/crt-guest-advanced-pass2f.slang @@ -52,6 +52,7 @@ layout(std140, set = 0, binding = 0) uniform UBO float no_scanlines; float intres; float fcompat; + float smask_mit; } global; #pragma parameter fcompat " Compatibility Mode (slower, use if glitchy)" 0.0 0.0 1.0 1.0 @@ -106,7 +107,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0 #define gsl params.gsl // Alternate scanlines -#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5 +#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 40.0 0.5 #define scanline1 params.scanline1 // scanline param, vertical sharpness #pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 70.0 1.0 @@ -115,7 +116,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 10.0 0.05 #define beam_min params.beam_min // dark area beam min - narrow -#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025 +#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.2 3.5 0.025 #define beam_max params.beam_max // bright area beam max - wide #pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05 @@ -127,10 +128,10 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter scans " Scanline Saturation / Mask Falloff" 0.50 -5.0 5.0 0.10 #define scans params.scans // scanline saturation -#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.20 2.0 0.05 +#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.10 2.0 0.05 #define scan_falloff global.scan_falloff // scanline falloff -#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.0 1.0 +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 #define no_scanlines global.no_scanlines #pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0 @@ -168,18 +169,21 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05 #define slotmask1 global.slotmask1 -#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0 +#pragma parameter slotwidth " Slot Mask Width (0:Auto)" 0.0 0.0 16.0 1.0 #define slotwidth params.slotwidth // Slot Mask Width -#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0 +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 2.0 1.0 4.0 1.0 #define double_slot params.double_slot // Slot Mask Height -#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0 -#define slotms params.slotms // Slot Mask Size +#pragma parameter slotms " Slot Mask Thickness" 1.0 1.0 4.0 1.0 +#define slotms params.slotms // Slot Mask Thickness #pragma parameter mclip " Keep Mask effect with clipping" 0.0 0.0 1.0 0.05 #define mclip params.mclip // Slot Mask Size +#pragma parameter smask_mit " Mitigate Slotmask Interaction" 0.0 0.0 1.0 0.05 +#define smask_mit global.smask_mit + #pragma parameter bogus_deconvergence22 "[ HORIZONTAL DECONVERGENCE ]:" 0.0 0.0 1.0 1.0 #pragma parameter DER " Deconvergence Red offset" 0.0 -15.0 15.0 0.5 @@ -255,7 +259,7 @@ float sw2(float x, float color, float scanline) // Shadow mask (1-4 from PD CRT Lottes shader). -vec3 Mask(vec2 pos, float mx) +vec3 Mask(vec2 pos, float mx, inout float swidth) { vec2 pos0 = pos; pos.y = floor(pos.y/masksize); @@ -268,10 +272,10 @@ vec3 Mask(vec2 pos, float mx) vec3 one = vec3(1.0); // brightness correcture masks 5-12 - float sm = 0.45; if(shadowMask == 8.0 || shadowMask == 11.0) sm = 0.7; + float sm = 0.45; if(shadowMask == 8.0 || shadowMask == 11.0 || shadowMask == 13.0) sm = 0.7; float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - sm, 0.0) + 1.0, 1.0, mx); - float mc = 1.0 - max(maskstr, 0.0); + float mc = 1.0 - max(maskstr, 0.0); // No mask if (shadowMask == -1.0) @@ -285,6 +289,7 @@ vec3 Mask(vec2 pos, float mx) pos.x = fract(pos.x*0.5); if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } else { mask.r = mc; mask.g = 1.0; mask.b = mc; } + swidth = 2.0; } // Very compressed TV style shadow mask. @@ -298,23 +303,23 @@ vec3 Mask(vec2 pos, float mx) if (fract((pos.y + odd)/2.0) < 0.49) line = maskDark; - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; - mask*=line; + mask*=line; } // Aperture-grille. else if (shadowMask == 2.0) { - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; } // Stretched VGA style shadow mask (same as prior shaders). @@ -325,7 +330,7 @@ vec3 Mask(vec2 pos, float mx) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // VGA style shadow mask. @@ -337,7 +342,8 @@ vec3 Mask(vec2 pos, float mx) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; + swidth = 6.0; } // Trinitron mask 5 @@ -351,15 +357,16 @@ vec3 Mask(vec2 pos, float mx) } else mask.g = 1.0; mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + swidth = 2.0; } // Trinitron mask 6 else if (shadowMask == 6.0) { mask = vec3(0.0); - pos.x = fract(pos.x/3.0); - if (pos.x < 0.3) mask.r = 1.0; - else if (pos.x < 0.6) mask.g = 1.0; + pos.x = floor(mod(pos.x,3.0)); + if (pos.x < 0.5) mask.r = 1.0; + else if (pos.x < 1.5) mask.g = 1.0; else mask.b = 1.0; mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; } @@ -374,6 +381,7 @@ vec3 Mask(vec2 pos, float mx) } else mask = 1.0.xxx; mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + swidth = 2.0; } // BW Trinitron mask 8 @@ -407,27 +415,21 @@ vec3 Mask(vec2 pos, float mx) else if (pos.x < 0.4) mask.r = 1.0; else if (pos.x < 0.7) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + swidth = 4.0; } // 4k mask else if (shadowMask == 11.0) { - mask = vec3(mc); + mask = vec3(0.0); pos.x = fract(pos.x * 0.25); if (pos.x < 0.2) mask.r = 1.0; else if (pos.x < 0.4) mask.rg = 1.0.xx; else if (pos.x < 0.7) mask.gb = 1.0.xx; - else mask.b = 1.0; - } - else if (shadowMask == 12.0) - { - mask = vec3(mc); - pos.x = fract(pos.x * 0.25); - if (pos.x < 0.2) mask.r = 1.0; - else if (pos.x < 0.4) mask.rb = 1.0.xx; - else if (pos.x < 0.7) mask.gb = 1.0.xx; - else mask.g = 1.0; + else mask.b = 1.0; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + swidth = 4.0; } // RRGGBBX mask @@ -440,6 +442,7 @@ vec3 Mask(vec2 pos, float mx) else if (pos.x < 4.5) mask.g = 1.0; else mask.b = 1.0; mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + swidth = 7.0; } // 4k mask @@ -454,26 +457,26 @@ vec3 Mask(vec2 pos, float mx) else if (pos.x < 4.5) mask.gb = 1.0.xx; else mask.b = 1.0; mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + swidth = 6.0; } - - float maskmin = min(min(mask.r,mask.g),mask.b); - return (mask - maskmin) * maskboost + maskmin; + + swidth*=masksize; + return mask; } -float SlotMask(vec2 pos, float m) +float SlotMask(vec2 pos, float m, float swidth) { if ((slotmask + slotmask1) == 0.0) return 1.0; else { - if (shadowMask == 2.0 || shadowMask == 6.0) pos.x = pos.x + slotms; - pos = floor(pos/slotms); - float mlen = slotwidth*2.0; - float px = fract(pos.x/mlen); + pos.y = floor(pos.y/slotms); + float mlen = swidth*2.0; + float px = floor(mod(pos.x, 0.99999*mlen)); float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot); float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m); float slot = 1.0; - if (py == 0.0 && px < 0.5) slot = slot_dark; else - if (py == double_slot && px >= 0.5) slot = slot_dark; + if (py == 0.0 && px < swidth) slot = slot_dark; else + if (py == double_slot && px >= swidth) slot = slot_dark; return slot; } @@ -540,7 +543,8 @@ vec3 calculate_bloom (vec2 pos, vec2 x, vec2 y) void main() { float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.75); + bool interb = ((intera < 0.75) || (no_scanlines > 0.025)); + vec4 result = COMPAT_TEXTURE(Pass2Feedback, vTexCoord); vec2 texcoord = TEX0.xy; @@ -572,7 +576,7 @@ void main() bool frames = (floor(mod(float(global.FrameCount), refresh1)) == refresh2); bool not_same = (same2 + same3 + same4 + same5) > 0.25; -if ( not_same || frames || interb || global.fcompat > 0.5) +if ( not_same || frames || (interb && (no_scanlines < 0.025)) || global.fcompat > 0.5) { @@ -609,7 +613,7 @@ if ( not_same || frames || interb || global.fcompat > 0.5) if (global.intres == 0.5) pC4.y = floor(pC4.y * global.OriginalSize.y)*global.OriginalSize.w + 0.5*global.OriginalSize.w; - if (interb) pC4.y = pos.y - inters * SourceSize.w; + if (interb && no_scanlines < 0.025) pC4.y = pos.y - inters * SourceSize.w; else if (interb) pC4.y = pC4.y + smoothstep(0.40-0.5*no_scanlines, 0.60 + 0.5*no_scanlines, f)*SourceSize.w; vec3 color1 = COMPAT_TEXTURE(Source, pC4 ).rgb; vec3 dcolor1 = color1; @@ -620,7 +624,7 @@ if ( not_same || frames || interb || global.fcompat > 0.5) vec3 scolor1 = COMPAT_TEXTURE(Source, pC4 ).aaa; - if (interb) pC4.y = pos.y + inters * SourceSize.w; else + if (interb && no_scanlines < 0.025) pC4.y = pos.y + inters * SourceSize.w; else pC4+=dy; if (global.intres == 0.5) pC4.y = floor((pos.y + 0.33*dy.y) * global.OriginalSize.y)*global.OriginalSize.w + 0.5*global.OriginalSize.w; @@ -710,7 +714,7 @@ if (abs(vertmask) > 0.025) } } - color = (gc(color1)*w1*cd1 + gc(color2)*w2*cd2)/mix(1.0.xxx, w1+w2, no_scanlines); + color = (gc(color1)*w1*cd1 + gc(color2)*w2*cd2); color = min(color, 1.0); } @@ -728,8 +732,11 @@ if (abs(vertmask) > 0.025) vec3 orig1 = color; vec3 cmask = one; - float smask = SlotMask(gl_FragCoord.xy * 1.000001, mx); - cmask*= Mask(gl_FragCoord.xy * 1.000001, mx); + float swidth = 3.0; + cmask*= Mask(gl_FragCoord.xy * 1.000001, mx, swidth); + if (slotwidth > 0.5) swidth = slotwidth; + float smask = SlotMask(gl_FragCoord.xy * 1.000001, mx, swidth); + smask = clamp(smask + mix(smask_mit, 0.0, min(w3, pow(w3*max(max(orig1.r,orig1.g),orig1.b), 0.33333))), 0.0, 1.0); if (mask_layout > 0.5) cmask = cmask.rbg; @@ -742,7 +749,6 @@ if (abs(vertmask) > 0.025) if (interb) ctmp = color; float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out); float bb = mix(brightboost, brightboost1, colmx); - if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.60); color*=bb; vec3 Glow = calculate_bloom (pos, xx, 0.75*yy); diff --git a/crt/shaders/guest/fast/deconvergence-f.slang b/crt/shaders/guest/fast/deconvergence-f.slang index 0d0dfc8..06726a1 100644 --- a/crt/shaders/guest/fast/deconvergence-f.slang +++ b/crt/shaders/guest/fast/deconvergence-f.slang @@ -67,9 +67,14 @@ layout(std140, set = 0, binding = 0) uniform UBO float maskboost; float smoothmask; float gamma_c; + float smask_mit; + float mask_zoom; + float no_scanlines; } global; +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 + #pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 #pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 @@ -148,6 +153,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0 #define masksize params.masksize // Mask Size +#pragma parameter mask_zoom " CRT Mask Zoom (+ mask width)" 0.0 -4.0 4.0 1.0 +#define mask_zoom global.mask_zoom // Mask Size + #pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 #define maskDark params.maskDark // Dark "Phosphor" @@ -169,14 +177,14 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05 #define slotmask1 params.slotmask1 -#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0 +#pragma parameter slotwidth " Slot Mask Width (0:Auto)" 0.0 0.0 16.0 1.0 #define slotwidth params.slotwidth // Slot Mask Width -#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0 +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 2.0 1.0 4.0 1.0 #define double_slot params.double_slot // Slot Mask Height -#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0 -#define slotms global.slotms // Slot Mask Size +#pragma parameter slotms " Slot Mask Thickness" 1.0 1.0 4.0 1.0 +#define slotms global.slotms // Slot Mask Thickness #pragma parameter mclip " Keep Mask effect with clipping" 0.0 0.0 1.0 0.05 #define mclip global.mclip // @@ -184,6 +192,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter smoothmask " Smooth Masks in bright scanlines" 0.0 0.0 1.0 1.0 #define smoothmask global.smoothmask +#pragma parameter smask_mit " Mitigate Slotmask Interaction" 0.0 0.0 1.0 0.05 +#define smask_mit global.smask_mit + #pragma parameter gamma_out " Gamma out" 2.4 1.0 5.0 0.05 #define gamma_out global.gamma_out // output gamma @@ -248,31 +259,19 @@ layout(set = 0, binding = 5) uniform sampler2D Source; vec3 Mask(vec2 pos, float mx, float mb) { - vec2 pos0 = pos; - pos.y = floor(pos.y/masksize); - float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; - float next_line = float(fract((pos.y/stagg_lvl)*0.5) > 0.25); - pos0.x = (mshift > -0.25) ? (pos0.x + next_line * floor(mshift)) : (pos0.x + floor(pos.y / stagg_lvl) * floor(abs(mshift))); - pos = floor(pos0/masksize); - vec3 mask = vec3(maskDark, maskDark, maskDark); vec3 one = vec3(1.0); - // brightness correcture masks 5-12 - float sm = 0.45; if(shadowMask == 8.0 || shadowMask == 11.0 || shadowMask == 13.0) sm = 0.7; - float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - sm, 0.0) + 1.0, 1.0, mx); - - float mc = 1.0 - max(maskstr, 0.0); - // No mask if (shadowMask == -1.0) { - mask = vec3(1.0); + mask = one; } // Phosphor. else if (shadowMask == 0.0) { + float mc = 1.0 - max(maskstr, 0.0); pos.x = fract(pos.x*0.5); if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } else { mask.r = mc; mask.g = 1.0; mask.b = mc; } @@ -289,23 +288,23 @@ vec3 Mask(vec2 pos, float mx, float mb) if (fract((pos.y + odd)/2.0) < 0.49) line = maskDark; - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; - mask*=line; + mask*=line; } // Aperture-grille. else if (shadowMask == 2.0) { - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; } // Stretched VGA style shadow mask (same as prior shaders). @@ -316,7 +315,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // VGA style shadow mask. @@ -328,7 +327,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // Trinitron mask 5 @@ -341,18 +340,18 @@ vec3 Mask(vec2 pos, float mx, float mb) mask.b = 1.0; } else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Trinitron mask 6 else if (shadowMask == 6.0) { mask = vec3(0.0); - pos.x = fract(pos.x/3.0); - if (pos.x < 0.3) mask.r = 1.0; - else if (pos.x < 0.6) mask.g = 1.0; + pos.x = floor(mod(pos.x,3.0)); + if (pos.x < 0.5) mask.r = 1.0; + else if (pos.x < 1.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 7 @@ -364,7 +363,7 @@ vec3 Mask(vec2 pos, float mx, float mb) { mask = 0.0.xxx; } else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 8 @@ -375,7 +374,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask = 1.0.xxx; else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Magenta - Green - Black mask @@ -386,7 +385,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask.rb = 1.0.xx; else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RGBX @@ -398,7 +397,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.r = 1.0; else if (pos.x < 0.7) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -410,7 +409,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.rg = 1.0.xx; else if (pos.x < 0.7) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RRGGBBX mask @@ -422,7 +421,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 2.5) mask.r = 1.0; else if (pos.x < 4.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -436,32 +435,33 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 3.5) mask.rgb = 1.0.xxx; else if (pos.x < 4.5) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } + if (mask_layout > 0.5) mask = mask.rbg; float maskmin = min(min(mask.r,mask.g),mask.b); return (mask - maskmin) * (1.0 + (maskboost-1.0)*mb) + maskmin; } -float SlotMask(vec2 pos, float m) + +float SlotMask(vec2 pos, float m, float swidth) { if ((slotmask + slotmask1) == 0.0) return 1.0; else { - if (shadowMask == 2.0 || shadowMask == 6.0) pos.x = pos.x + slotms; - pos = floor(pos/slotms); - float mlen = slotwidth*2.0; - float px = fract(pos.x/mlen); + pos.y = floor(pos.y/slotms); + float mlen = swidth*2.0; + float px = floor(mod(pos.x, 0.99999*mlen)); float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot); float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m); float slot = 1.0; - if (py == 0.0 && px < 0.5) slot = slot_dark; else - if (py == double_slot && px >= 0.5) slot = slot_dark; + if (py == 0.0 && px < swidth) slot = slot_dark; else + if (py == double_slot && px >= swidth) slot = slot_dark; return slot; } } - + vec2 Warp(vec2 pos) { pos = pos*2.0-1.0; @@ -591,7 +591,7 @@ void main() float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = (intera < 0.5 || global.no_scanlines > 0.025); // Calculating texel coordinates @@ -644,12 +644,50 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob vec3 orig1 = color; vec3 cmask = one; - vec2 maskcoord = gl_FragCoord.xy * 1.000001; + vec2 maskcoord = gl_FragCoord.xy * 1.00001; - float smask = SlotMask(maskcoord, mx); - cmask*= Mask(maskcoord, mx, mb); + vec2 scoord = maskcoord; + + // mask widths and mask dark compensate (fractional part) values + + float mwidths[14] = float[14] (2.0, 3.0, 3.0, 3.0, 6.0, 2.4, 3.5, 2.4, 3.25, 3.5, 4.5, 4.25, 7.5, 6.25); + + float mwidth = mwidths[int(shadowMask)]; + float mask_compensate = fract(mwidth); + mwidth = floor(mwidth) * masksize; + float swidth = mwidth; + bool zoomed = (abs(mask_zoom) > 0.75); + float mscale = 1.0; + vec2 maskcoord0 = maskcoord; + maskcoord.y = floor(maskcoord.y/masksize); - if (mask_layout > 0.5) cmask = cmask.rbg; +if ( abs(mshift) > 0.75 ) +{ + float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; + float next_line = float(fract((maskcoord.y/stagg_lvl)*0.5) > 0.25); + maskcoord0.x = (mshift > -0.25) ? (maskcoord0.x + next_line * floor(mshift)) : (maskcoord0.x + floor(maskcoord.y / stagg_lvl) * floor(abs(mshift))); +} + maskcoord = maskcoord0/masksize; if (mask_zoom >= 0.0) maskcoord = floor(maskcoord); + +if ( !zoomed ) + cmask*= Mask(maskcoord, mx, mb); +else{ + float mwidth1 = max(mwidth + mask_zoom, 2.0); + mscale = mwidth1/mwidth; + float mlerp = fract(maskcoord.x/mscale); + float mcoord = floor(maskcoord.x/mscale); if (shadowMask == 12.0 && mask_zoom == -2.0) mcoord = ceil(maskcoord.x/mscale); + cmask*=mix(Mask(vec2(mcoord,maskcoord.y), mx, mb), Mask(vec2(mcoord + 1.0, maskcoord.y), mx, mb), mlerp); +} + + if (slotwidth > 0.5) swidth = slotwidth; float smask = 1.0; + + float sm_offset = 0.0; bool bsm_offset = (shadowMask == 0.0 || shadowMask == 2.0 || shadowMask == 5.0 || shadowMask == 6.0 || shadowMask == 8.0 || shadowMask == 11.0); + if( zoomed ) { if (mask_layout < 0.5 && bsm_offset) sm_offset = 1.0; else if (bsm_offset) sm_offset = -1.0; } + + swidth = round(swidth*mscale); + smask = SlotMask(scoord + vec2(sm_offset,0.0), mx, swidth); + + smask = clamp(smask + mix(smask_mit, 0.0, min(w3, pow(w3*max(max(orig1.r,orig1.g),orig1.b), 0.33333))), 0.0, 1.0); cmask*=smask; vec3 cmask1 = cmask; @@ -669,8 +707,8 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob cmask = min(cmask, 1.0); cmask1 = min(cmask1, 1.0); - float bb = mix(brightboost, brightboost1, mx); - if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 1.0 + mask_compensate, 0.0) + 1.0, 1.0, mx); + float bb = mix(brightboost, brightboost1, mx) * dark_compensate; color*=bb; vec3 Glow = COMPAT_TEXTURE(BloomPass, pos).rgb; @@ -697,7 +735,7 @@ if (abs(bloom) > 0.025) Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx); color = color + 2.0*max((2.0*mix(maxb*maxb, maxb, colmx)-0.5*max(max(Ref.r,Ref.g),Ref.b)),0.25)*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.6)*Bloom*halation; } else - if (halation < 0.01) { + if (halation < -0.01) { float mbl = max(max(Bloom.r,Bloom.g),Bloom.b); Bloom = plant(Bloom + Ref + orig1 + Bloom*Bloom*Bloom, min(mbl*mbl,0.75)); color = color + 2.0*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.5)*Bloom*(-halation); } diff --git a/crt/shaders/guest/fast/linearize.slang b/crt/shaders/guest/fast/linearize.slang index a440586..05fc86d 100644 --- a/crt/shaders/guest/fast/linearize.slang +++ b/crt/shaders/guest/fast/linearize.slang @@ -3,7 +3,7 @@ /* Interlacing - Copyright (C) 2020 guest(r) - guest.r@gmail.com + Copyright (C) 2020 - 2023 guest(r) - guest.r@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -61,7 +61,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4-5" 1.0 0.0 5.0 1.0 #define interm params.interm // interlace mode -#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05 +#pragma parameter iscan " Interlacing Scanline Effect ('Laced brightness)" 0.20 0.0 1.0 0.05 #define iscan params.iscan // interlacing effect scanlining #pragma parameter intres " Internal Resolution Y: 0.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match @@ -166,8 +166,8 @@ void main() c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r); if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii); } - if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; } - if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; } + if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)) * (1.0-0.5*iscan); } + if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)) * (1.0-0.5*iscan); } } c = pow(c, vec3(gamma_in)); diff --git a/crt/shaders/guest/fast/linearizef.slang b/crt/shaders/guest/fast/linearizef.slang index 53e4b55..2faee41 100644 --- a/crt/shaders/guest/fast/linearizef.slang +++ b/crt/shaders/guest/fast/linearizef.slang @@ -3,7 +3,7 @@ /* Interlacing - Copyright (C) 2020 - 2022 guest(r) - guest.r@gmail.com + Copyright (C) 2020 - 2023 guest(r) - guest.r@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -65,7 +65,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // // Joint parameter with main pass, values must match #define inters params.inters // interlacing effect smoothing -#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05 +#pragma parameter iscan " Interlacing Scanline Effect ('Laced brightness)" 0.20 0.0 1.0 0.05 #define iscan params.iscan // interlacing effect scanlining @@ -129,7 +129,8 @@ void main() c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r); if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii); } - if (interm == 5.0) { c = mix(c2, c1, 0.5); intera = 0.45; } + if (interm == 4.0) { c = c * (1.0-0.5*iscan); } + if (interm == 5.0) { c = mix(c2, c1, 0.5) * (1.0-0.5*iscan); } } c = pow(c, vec3(gamma_in)); diff --git a/crt/shaders/guest/fast/pre-shaders.slang b/crt/shaders/guest/fast/pre-shaders.slang index 891c0ac..3c0d5ff 100644 --- a/crt/shaders/guest/fast/pre-shaders.slang +++ b/crt/shaders/guest/fast/pre-shaders.slang @@ -53,7 +53,7 @@ layout(push_constant) uniform Push #pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0 #define TNTC params.TNTC -#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0 +#pragma parameter LS " LUT Size" 32.0 16.0 64.0 16.0 #define LS params.LS #define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons diff --git a/crt/shaders/guest/fast/pre-shadersf.slang b/crt/shaders/guest/fast/pre-shadersf.slang index 1b49448..4da7ca8 100644 --- a/crt/shaders/guest/fast/pre-shadersf.slang +++ b/crt/shaders/guest/fast/pre-shadersf.slang @@ -50,7 +50,7 @@ layout(push_constant) uniform Push #pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0 #define TNTC params.TNTC -#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0 +#pragma parameter LS " LUT Size" 32.0 16.0 64.0 16.0 #define LS params.LS #define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons diff --git a/crt/shaders/guest/hd/bloom_horizontal.slang b/crt/shaders/guest/hd/bloom_horizontal.slang index 019af4c..331702e 100644 --- a/crt/shaders/guest/hd/bloom_horizontal.slang +++ b/crt/shaders/guest/hd/bloom_horizontal.slang @@ -32,15 +32,15 @@ layout(push_constant) uniform Push float BLOOMCUT_H; } params; -#pragma parameter bogus_glow "[ GLOW/BLOOM PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 +#pragma parameter bogus_glow2 "[ BLOOM PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 -#pragma parameter SIZEHB " H. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0 +#pragma parameter SIZEHB " H. Bloom/Halation Radius" 4.0 1.0 30.0 1.0 #define SIZEHB params.SIZEHB -#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/Glow Sigma" 1.0 0.25 15.0 0.05 +#pragma parameter SIGMA_HB " Horizontal Bloom/Halation Sigma" 1.0 0.25 15.0 0.05 #define SIGMA_HB params.SIGMA_HB -#pragma parameter BLOOMCUT_H " Horizontal Bloom/Halation/(Glow) Substract" 0.0 0.0 0.5 0.01 +#pragma parameter BLOOMCUT_H " Horizontal Bloom/Halation Substract" 0.0 0.0 0.5 0.01 #define BLOOMCUT_H params.BLOOMCUT_H layout(std140, set = 0, binding = 0) uniform UBO diff --git a/crt/shaders/guest/hd/bloom_vertical.slang b/crt/shaders/guest/hd/bloom_vertical.slang index f19278a..58176dc 100644 --- a/crt/shaders/guest/hd/bloom_vertical.slang +++ b/crt/shaders/guest/hd/bloom_vertical.slang @@ -34,13 +34,13 @@ layout(push_constant) uniform Push } params; -#pragma parameter SIZEVB " V. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0 +#pragma parameter SIZEVB " V. Bloom/Halation Radius" 4.0 1.0 30.0 1.0 #define SIZEVB params.SIZEVB -#pragma parameter SIGMA_VB " Vertical Bloom/Halation/Glow Sigma" 1.0 0.25 15.0 0.05 +#pragma parameter SIGMA_VB " Vertical Bloom/Halation Sigma" 1.0 0.25 15.0 0.05 #define SIGMA_VB params.SIGMA_VB -#pragma parameter BLOOMCUT_V " Vertical Bloom/Halation/(Glow) Substract" 0.0 0.0 0.5 0.01 +#pragma parameter BLOOMCUT_V " Vertical Bloom/Halation Substract" 0.0 0.0 0.5 0.01 #define BLOOMCUT_V params.BLOOMCUT_V layout(std140, set = 0, binding = 0) uniform UBO diff --git a/crt/shaders/guest/hd/crt-guest-advanced-hd-pass1.slang b/crt/shaders/guest/hd/crt-guest-advanced-hd-pass1.slang index bf968d0..6bce52b 100644 --- a/crt/shaders/guest/hd/crt-guest-advanced-hd-pass1.slang +++ b/crt/shaders/guest/hd/crt-guest-advanced-hd-pass1.slang @@ -3,7 +3,7 @@ /* CRT - Guest - Advanced - HD - Pass1 - Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com + Copyright (C) 2018-2023 guest(r) - guest.r@gmail.com Incorporates many good ideas and suggestions from Dr. Venom. I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader. @@ -42,6 +42,7 @@ layout(push_constant) uniform Push float VARNG; float VSHARP; float internal_res; + float MAXS; } params; layout(std140, set = 0, binding = 0) uniform UBO @@ -64,9 +65,12 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter S_SHARP " Substractive Sharpness" 1.0 0.0 2.0 0.10 #define S_SHARP params.S_SHARP -#pragma parameter HSHARP " Sharpness Definition" 1.25 0.0 2.0 0.10 +#pragma parameter HSHARP " Sharpness Definition" 1.20 0.0 2.0 0.10 #define HSHARP params.HSHARP +#pragma parameter MAXS " Maximum Sharpness" 0.15 0.0 0.30 0.01 +#define MAXS params.MAXS + #pragma parameter HARNG " Substractive Sharpness Ringing" 0.2 0.0 4.0 0.10 #define HARNG params.HARNG @@ -81,7 +85,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter S_SHARPV " Vert. Substractive Sharpness" 1.0 0.0 2.0 0.10 #define S_SHARPV global.S_SHARPV -#pragma parameter VSHARP " Vert. Sharpness Definition" 1.25 0.0 2.0 0.10 +#pragma parameter VSHARP " Vert. Sharpness Definition" 1.20 0.0 2.0 0.10 #define VSHARP global.VSHARP #pragma parameter VARNG " Substractive Sharpness Ringing" 0.2 0.0 4.0 0.10 @@ -142,7 +146,7 @@ void main() vec3 cmax = 0.0.xxx; vec3 cmin = 1.0.xxx; float sharp = gaussian(hsharpness) * S_SHARP; - float maxsharp = 0.20; + float maxsharp = MAXS; float FPR = hsharpness; float fpx = 0.0; float sp = 0.0; diff --git a/crt/shaders/guest/hd/crt-guest-advanced-hd-pass2.slang b/crt/shaders/guest/hd/crt-guest-advanced-hd-pass2.slang index 758797a..287f5dd 100644 --- a/crt/shaders/guest/hd/crt-guest-advanced-hd-pass2.slang +++ b/crt/shaders/guest/hd/crt-guest-advanced-hd-pass2.slang @@ -3,7 +3,7 @@ /* CRT - Guest - Advanced - HD - Pass2 - Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com + Copyright (C) 2018-2023 guest(r) - guest.r@gmail.com Incorporates many good ideas and suggestions from Dr. Venom. I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader. @@ -27,7 +27,7 @@ layout(push_constant) uniform Push { float IOS, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, - glow, vertmask, inters, bloom, halation, scans, gamma_c, no_scanlines; + glow, inters, bloom, halation, scans, gamma_c, no_scanlines, MAXS; } params; layout(std140, set = 0, binding = 0) uniform UBO @@ -57,11 +57,14 @@ layout(std140, set = 0, binding = 0) uniform UBO float scan_falloff; float overscanX; float overscanY; - float bloom_dist; + float bloom_dist; } global; #pragma parameter bogus_vfiltering "[ VERTICAL/INTERLACING FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0 +#pragma parameter MAXS " Maximum Sharpness" 0.15 0.0 0.30 0.01 +#define MAXS params.MAXS + #pragma parameter VSHARPNESS " Vertical Filter Range" 1.0 1.0 8.0 0.05 #define VSHARPNESS global.VSHARPNESS @@ -71,7 +74,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter S_SHARPV " Vert. Substractive Sharpness" 1.0 0.0 2.0 0.10 #define S_SHARPV global.S_SHARPV -#pragma parameter VSHARP " Vert. Sharpness Definition" 1.25 0.0 2.0 0.10 +#pragma parameter VSHARP " Vert. Sharpness Definition" 1.20 0.0 2.0 0.10 #define VSHARP global.VSHARP #pragma parameter VARNG " Substractive Sharpness Ringing" 0.2 0.0 4.0 0.10 @@ -116,7 +119,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 -#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 +#pragma parameter glow " (Magic) Glow Strength" 0.08 -2.0 2.0 0.01 #define glow params.glow // Glow Strength #pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05 @@ -145,7 +148,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0 #define gsl params.gsl // Alternate scanlines -#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5 +#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 40.0 0.5 #define scanline1 params.scanline1 // scanline param, vertical sharpness #pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 70.0 1.0 @@ -154,25 +157,22 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter beam_min " Scanline Shape Dark Pixels" 1.20 0.25 10.0 0.05 #define beam_min params.beam_min // dark area beam min - narrow -#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025 +#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.2 3.5 0.025 #define beam_max params.beam_max // bright area beam max - wide #pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05 #define beam_size params.beam_size // increased max. beam size -#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1 -#define vertmask params.vertmask // Scanline deconvergence colors - #pragma parameter scans " Scanline Saturation / Mask Falloff" 0.50 -5.0 5.0 0.10 #define scans params.scans // scanline saturation -#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.20 2.0 0.05 +#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.10 2.0 0.05 #define scan_falloff global.scan_falloff // scanline falloff #pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05 #define scangamma global.scangamma -#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.0 1.0 +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 #define no_scanlines params.no_scanlines #pragma parameter internal_res " Internal Resolution" 1.0 1.0 8.0 0.10 @@ -280,7 +280,7 @@ vec3 v_resample (vec2 tex0, vec4 Size) { vec3 cmin = 1.0.xxx; float vsharpness = VSHARPNESS*internal_res; float sharp = gaussian(vsharpness) * S_SHARPV; - float maxsharp = 0.20; + float maxsharp = MAXS; float FPR = vsharpness; float fpx = 0.0; @@ -320,7 +320,7 @@ void main() vec4 SourceSize = vec4(global.SourceSize.x, global.OriginalSize.y, global.SourceSize.z, global.OriginalSize.w); float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = ((intera < 0.5) || (no_scanlines > 0.025)); float SourceY = SourceSize.y; float sy = 1.0; @@ -362,6 +362,7 @@ void main() pC4.x = pos.x; if (global.intres == 0.5 && prescalex.y < 1.5) pC4.y = floor(pC4.y * global.OriginalSize.y)*global.OriginalSize.w + 0.5*global.OriginalSize.w; + if (interb && no_scanlines > 0.025) pC4.y = pC4.y + smoothstep(0.40-0.5*no_scanlines, 0.60 + 0.5*no_scanlines, f)*SourceSize.w; vec3 color1 = COMPAT_TEXTURE(Pass1, pC4 ).rgb; vec3 scolor1 = COMPAT_TEXTURE(Pass1, pC4 ).aaa; @@ -370,7 +371,7 @@ void main() float prescaley = float(textureSize(LinearizePass, 0).y) / global.OriginalSize.y; - if (interb) color1 = v_resample(pos, SourceSize * vec4(1.0, prescaley, 1.0, 1.0/prescaley)); + if (interb && no_scanlines < 0.05) color1 = v_resample(pos, SourceSize * vec4(1.0, prescaley, 1.0, 1.0/prescaley)); pC4+=dy; @@ -430,33 +431,8 @@ if (!interb) w1 = pow(w1, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref1, scanpow1))); w2 = pow(w2, mix(2.0*abs(scans).xxx + 1.0, 1.0.xxx, mix(1.0.xxx, cref2, scanpow2))); - // Scanline Deconvergence - vec3 cd1 = one; vec3 cd2 = one; - -if (abs(vertmask) > 0.025) -{ - float vm = sqrt(abs(vertmask)); - float v_high1 = 1.0 + 0.3*vm; - float v_high2 = 1.0 + 0.6*vm; - float v_low = 1.0 - vm; - - float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0); - float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0); - - if (vertmask < 0.0) - { - cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1); - cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2); - } - else - { - cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1); - cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2); - } -} - - color = (gc(color1)*w1*cd1 + gc(color2)*w2*cd2)/mix(1.0.xxx, w1+w2, no_scanlines); + color = (gc(color1)*w1 + gc(color2)*w2); color = min(color, 1.0); } diff --git a/crt/shaders/guest/hd/deconvergence-hd.slang b/crt/shaders/guest/hd/deconvergence-hd.slang index c066d0d..6c29fca 100644 --- a/crt/shaders/guest/hd/deconvergence-hd.slang +++ b/crt/shaders/guest/hd/deconvergence-hd.slang @@ -70,12 +70,32 @@ layout(std140, set = 0, binding = 0) uniform UBO float maskboost; float smoothmask; float gamma_c; + float m_glow; + float m_glow_low; + float m_glow_high; + float m_glow_dist; + float m_glow_mask; + float smask_mit; + float mask_zoom; + float no_scanlines; } global; +#pragma parameter no_scanlines " No-scanline mode" 0.0 0.0 1.5 0.05 + #pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 -#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 +#pragma parameter m_glow " Ordinary Glow / Magic Glow" 0.0 0.0 1.0 1.0 + +#pragma parameter m_glow_low " Magic Glow Low Strength" 0.35 0.0 7.0 0.05 + +#pragma parameter m_glow_high " Magic Glow High Strength" 5.0 0.0 7.0 0.10 + +#pragma parameter m_glow_dist " Magic Glow Distribution" 1.0 0.20 4.0 0.05 + +#pragma parameter m_glow_mask " Magic Glow Mask Strength" 1.0 0.0 2.0 0.025 + +#pragma parameter glow " (Magic) Glow Strength" 0.08 -2.0 2.0 0.01 #define glow params.glow // Glow Strength #pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05 @@ -151,6 +171,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0 #define masksize params.masksize // Mask Size +#pragma parameter mask_zoom " CRT Mask Zoom (+ mask width)" 0.0 -4.0 4.0 1.0 +#define mask_zoom global.mask_zoom // Mask Size + #pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 #define maskDark params.maskDark // Dark "Phosphor" @@ -172,14 +195,14 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05 #define slotmask1 params.slotmask1 -#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0 +#pragma parameter slotwidth " Slot Mask Width (0:Auto)" 0.0 0.0 16.0 1.0 #define slotwidth params.slotwidth // Slot Mask Width -#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0 +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 2.0 1.0 4.0 1.0 #define double_slot params.double_slot // Slot Mask Height -#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0 -#define slotms global.slotms // Slot Mask Size +#pragma parameter slotms " Slot Mask Thickness" 1.0 1.0 4.0 1.0 +#define slotms global.slotms // Slot Mask Thickness #pragma parameter mclip " Keep Mask effect with clipping" 0.0 0.0 1.0 0.05 #define mclip global.mclip // @@ -187,6 +210,9 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter smoothmask " Smooth Masks in bright scanlines" 0.0 0.0 1.0 1.0 #define smoothmask global.smoothmask +#pragma parameter smask_mit " Mitigate Slotmask Interaction" 0.0 0.0 1.0 0.05 +#define smask_mit global.smask_mit + #pragma parameter gamma_out " Gamma out" 1.75 1.0 5.0 0.05 #define gamma_out global.gamma_out // output gamma @@ -244,6 +270,7 @@ layout(set = 0, binding = 2) uniform sampler2D LinearizePass; layout(set = 0, binding = 3) uniform sampler2D BloomPass; layout(set = 0, binding = 4) uniform sampler2D PrePass; layout(set = 0, binding = 5) uniform sampler2D Source; +layout(set = 0, binding = 6) uniform sampler2D GlowPass; #define eps 1e-10 @@ -251,31 +278,19 @@ layout(set = 0, binding = 5) uniform sampler2D Source; vec3 Mask(vec2 pos, float mx, float mb) { - vec2 pos0 = pos; - pos.y = floor(pos.y/masksize); - float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; - float next_line = float(fract((pos.y/stagg_lvl)*0.5) > 0.25); - pos0.x = (mshift > -0.25) ? (pos0.x + next_line * floor(mshift)) : (pos0.x + floor(pos.y / stagg_lvl) * floor(abs(mshift))); - pos = floor(pos0/masksize); - vec3 mask = vec3(maskDark, maskDark, maskDark); vec3 one = vec3(1.0); - // brightness correcture masks 5-12 - float sm = 0.45; if(shadowMask == 8.0 || shadowMask == 11.0 || shadowMask == 13.0) sm = 0.7; - float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - sm, 0.0) + 1.0, 1.0, mx); - - float mc = 1.0 - max(maskstr, 0.0); - // No mask if (shadowMask == -1.0) { - mask = vec3(1.0); + mask = one; } // Phosphor. else if (shadowMask == 0.0) { + float mc = 1.0 - max(maskstr, 0.0); pos.x = fract(pos.x*0.5); if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } else { mask.r = mc; mask.g = 1.0; mask.b = mc; } @@ -292,23 +307,23 @@ vec3 Mask(vec2 pos, float mx, float mb) if (fract((pos.y + odd)/2.0) < 0.49) line = maskDark; - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; - mask*=line; + mask*=line; } // Aperture-grille. else if (shadowMask == 2.0) { - pos.x = fract(pos.x/3.0); + pos.x = floor(mod(pos.x,3.0)); - if (pos.x < 0.3) mask.r = maskLight; - else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + if (pos.x < 0.5) mask.r = maskLight; + else if (pos.x < 1.5) mask.g = maskLight; + else mask.b = maskLight; } // Stretched VGA style shadow mask (same as prior shaders). @@ -319,7 +334,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // VGA style shadow mask. @@ -331,7 +346,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask.r = maskLight; else if (pos.x < 0.6) mask.g = maskLight; - else mask.b = maskLight; + else mask.b = maskLight; } // Trinitron mask 5 @@ -344,18 +359,18 @@ vec3 Mask(vec2 pos, float mx, float mb) mask.b = 1.0; } else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Trinitron mask 6 else if (shadowMask == 6.0) { mask = vec3(0.0); - pos.x = fract(pos.x/3.0); - if (pos.x < 0.3) mask.r = 1.0; - else if (pos.x < 0.6) mask.g = 1.0; + pos.x = floor(mod(pos.x,3.0)); + if (pos.x < 0.5) mask.r = 1.0; + else if (pos.x < 1.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 7 @@ -367,7 +382,7 @@ vec3 Mask(vec2 pos, float mx, float mb) { mask = 0.0.xxx; } else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // BW Trinitron mask 8 @@ -378,7 +393,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask = 1.0.xxx; else mask = 1.0.xxx; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // Magenta - Green - Black mask @@ -389,7 +404,7 @@ vec3 Mask(vec2 pos, float mx, float mb) if (pos.x < 0.3) mask = 0.0.xxx; else if (pos.x < 0.6) mask.rb = 1.0.xx; else mask.g = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RGBX @@ -401,7 +416,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.r = 1.0; else if (pos.x < 0.7) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -413,7 +428,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 0.4) mask.rg = 1.0.xx; else if (pos.x < 0.7) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // RRGGBBX mask @@ -425,7 +440,7 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 2.5) mask.r = 1.0; else if (pos.x < 4.5) mask.g = 1.0; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } // 4k mask @@ -439,27 +454,28 @@ vec3 Mask(vec2 pos, float mx, float mb) else if (pos.x < 3.5) mask.rgb = 1.0.xxx; else if (pos.x < 4.5) mask.gb = 1.0.xx; else mask.b = 1.0; - mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0); } + if (mask_layout > 0.5) mask = mask.rbg; float maskmin = min(min(mask.r,mask.g),mask.b); return (mask - maskmin) * (1.0 + (maskboost-1.0)*mb) + maskmin; } -float SlotMask(vec2 pos, float m) + +float SlotMask(vec2 pos, float m, float swidth) { if ((slotmask + slotmask1) == 0.0) return 1.0; else { - if (shadowMask == 2.0 || shadowMask == 6.0) pos.x = pos.x + slotms; - pos = floor(pos/slotms); - float mlen = slotwidth*2.0; - float px = fract(pos.x/mlen); + pos.y = floor(pos.y/slotms); + float mlen = swidth*2.0; + float px = floor(mod(pos.x, 0.99999*mlen)); float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot); float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m); float slot = 1.0; - if (py == 0.0 && px < 0.5) slot = slot_dark; else - if (py == double_slot && px >= 0.5) slot = slot_dark; + if (py == 0.0 && px < swidth) slot = slot_dark; else + if (py == double_slot && px >= swidth) slot = slot_dark; return slot; } @@ -595,7 +611,7 @@ void main() float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; - bool interb = (intera < 0.5); + bool interb = (intera < 0.5 || global.no_scanlines > 0.025); // Calculating texel coordinates @@ -648,12 +664,50 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob vec3 orig1 = color; vec3 cmask = one; - vec2 maskcoord = gl_FragCoord.xy * 1.000001; + vec2 maskcoord = gl_FragCoord.xy * 1.00001; - float smask = SlotMask(maskcoord, mx); - cmask*= Mask(maskcoord, mx, mb); + vec2 scoord = maskcoord; + + // mask widths and mask dark compensate (fractional part) values + + float mwidths[14] = float[14] (2.0, 3.0, 3.0, 3.0, 6.0, 2.4, 3.5, 2.4, 3.25, 3.5, 4.5, 4.25, 7.5, 6.25); + + float mwidth = mwidths[int(shadowMask)]; + float mask_compensate = fract(mwidth); + mwidth = floor(mwidth) * masksize; + float swidth = mwidth; + bool zoomed = (abs(mask_zoom) > 0.75); + float mscale = 1.0; + vec2 maskcoord0 = maskcoord; + maskcoord.y = floor(maskcoord.y/masksize); - if (mask_layout > 0.5) cmask = cmask.rbg; +if ( abs(mshift) > 0.75 ) +{ + float stagg_lvl = 1.0; if (fract(abs(mshift)) > 0.25 && abs(mshift) > 1.25) stagg_lvl = 2.0; + float next_line = float(fract((maskcoord.y/stagg_lvl)*0.5) > 0.25); + maskcoord0.x = (mshift > -0.25) ? (maskcoord0.x + next_line * floor(mshift)) : (maskcoord0.x + floor(maskcoord.y / stagg_lvl) * floor(abs(mshift))); +} + maskcoord = maskcoord0/masksize; if (mask_zoom >= 0.0) maskcoord = floor(maskcoord); + +if ( !zoomed ) + cmask*= Mask(maskcoord, mx, mb); +else{ + float mwidth1 = max(mwidth + mask_zoom, 2.0); + mscale = mwidth1/mwidth; + float mlerp = fract(maskcoord.x/mscale); + float mcoord = floor(maskcoord.x/mscale); if (shadowMask == 12.0 && mask_zoom == -2.0) mcoord = ceil(maskcoord.x/mscale); + cmask*=mix(Mask(vec2(mcoord,maskcoord.y), mx, mb), Mask(vec2(mcoord + 1.0, maskcoord.y), mx, mb), mlerp); +} + + if (slotwidth > 0.5) swidth = slotwidth; float smask = 1.0; + + float sm_offset = 0.0; bool bsm_offset = (shadowMask == 0.0 || shadowMask == 2.0 || shadowMask == 5.0 || shadowMask == 6.0 || shadowMask == 8.0 || shadowMask == 11.0); + if( zoomed ) { if (mask_layout < 0.5 && bsm_offset) sm_offset = 1.0; else if (bsm_offset) sm_offset = -1.0; } + + swidth = round(swidth*mscale); + smask = SlotMask(scoord + vec2(sm_offset,0.0), mx, swidth); + + smask = clamp(smask + mix(smask_mit, 0.0, min(w3, pow(w3*max(max(orig1.r,orig1.g),orig1.b), 0.33333))), 0.0, 1.0); cmask*=smask; vec3 cmask1 = cmask; @@ -673,11 +727,11 @@ if ((abs(global.deconrr) + abs(global.deconrry) + abs(global.deconrg) + abs(glob cmask = min(cmask, 1.0); cmask1 = min(cmask1, 1.0); - float bb = mix(brightboost, brightboost1, mx); - if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 1.0 + mask_compensate, 0.0) + 1.0, 1.0, mx); + float bb = mix(brightboost, brightboost1, mx) * dark_compensate; color*=bb; - vec3 Glow = COMPAT_TEXTURE(BloomPass, pos).rgb; + vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb; vec3 Ref = COMPAT_TEXTURE(LinearizePass, pos).rgb; float maxb = COMPAT_TEXTURE(BloomPass, pos).a; float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a; @@ -701,15 +755,29 @@ if (abs(bloom) > 0.025) Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx); color = color + 2.0*max((2.0*mix(maxb*maxb, maxb, colmx)-0.5*max(max(Ref.r,Ref.g),Ref.b)),0.25)*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.6)*Bloom*halation; } else - if (halation < 0.01) { + if (halation < -0.01) { float mbl = max(max(Bloom.r,Bloom.g),Bloom.b); Bloom = plant(Bloom + Ref + orig1 + Bloom*Bloom*Bloom, min(mbl*mbl,0.75)); color = color + 2.0*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.5)*Bloom*(-halation); } + float w = 0.25 + 0.60*mix(w3, 1.0, sqrt(colmx)); if (smoothmask > 0.5) { w3 = mix(1.0, w3, smoothstep(0.3, 0.6, mx1)); color = max(min(color/w3, 1.0)*w3, min(color,color*(1.0-w3))); } - Glow = mix(Glow, 0.25*color, 0.7*colmx); - if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; } + if (global.m_glow < 0.5) Glow = mix(Glow, 0.25*color, 0.7*colmx); + else + { + maxb = max(max(Glow.r,Glow.g),Glow.b); + orig1 = plant(orig1 + 0.001*Ref, 1.0); + Bloom = plant(Glow, 1.0); + Ref = abs(orig1-Bloom); + mx0 = max(max(orig1.g,orig1.g),orig1.b)-min(min(orig1.g,orig1.g),orig1.b); + mx2 = max(max(Bloom.g,Bloom.g),Bloom.b)-min(min(Bloom.g,Bloom.g),Bloom.b); + Bloom = mix(maxb*min(Bloom,orig1), w*mix(mix(Glow, max(max(Ref.g,Ref.g),Ref.b)*Glow, max(mx,mx0)), mix(color, Glow, mx2), max(mx0,mx2)*Ref), min(sqrt((1.10-mx0)*(0.10+mx2)),1.0)); + Glow = mix(global.m_glow_low*Glow, global.m_glow_high*Bloom, pow(colmx, global.m_glow_dist/gamma_in)); + } + + if (glow >= 0.0 && global.m_glow < 0.5) color = color + 0.5*Glow*glow; + else { if(global.m_glow > 0.5) cmask1 = max(mix(one, cmask1, global.m_glow_mask),0.0); color = color + abs(glow)*cmask1*Glow; } color = min(color, 1.0); diff --git a/crt/shaders/guest/hd/gaussian_horizontal.slang b/crt/shaders/guest/hd/gaussian_horizontal.slang new file mode 100644 index 0000000..d23c648 --- /dev/null +++ b/crt/shaders/guest/hd/gaussian_horizontal.slang @@ -0,0 +1,133 @@ +#version 450 + +/* + Gaussian blur - horizontal pass, dynamic range, resizable + + Copyright (C) 2020-2023 guest(r) - guest.r@gmail.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +layout(push_constant) uniform Push +{ + vec4 LinearizePassSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEH; + float SIGMA_H; + float m_glow; + float m_glow_cutoff; + float m_glow_low; + float m_glow_high; + float m_glow_dist; + float m_glow_mask; +} params; + +#pragma parameter bogus_mglow "[ MAGIC GLOW SETTINGS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter m_glow " Ordinary Glow / Magic Glow" 0.0 0.0 1.0 1.0 +#define m_glow params.m_glow + +#pragma parameter m_glow_cutoff " Magic Glow Cutoff" 0.12 0.0 0.4 0.01 +#define m_glow_cutoff params.m_glow_cutoff + +#pragma parameter m_glow_low " Magic Glow Low Strength" 0.35 0.0 7.0 0.05 + +#pragma parameter m_glow_high " Magic Glow High Strength" 5.0 0.0 7.0 0.10 + +#pragma parameter m_glow_dist " Magic Glow Distribution" 1.0 0.20 4.0 0.05 + +#pragma parameter m_glow_mask " Magic Glow Mask Strength" 1.0 0.0 2.0 0.025 + +#pragma parameter bogus_glow1 "[ GLOW PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter SIZEH " Horizontal Glow Radius" 6.0 1.0 50.0 1.0 +#define SIZEH params.SIZEH + +#pragma parameter SIGMA_H " Horizontal Glow Sigma" 1.20 0.20 15.0 0.10 +#define SIGMA_H params.SIGMA_H + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D LinearizePass; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + +float invsqrsigma = 1.0/(2.0*SIGMA_H*SIGMA_H); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + +void main() +{ + vec4 SourceSize1 = params.OriginalSize; + float f = fract(SourceSize1.x * vTexCoord.x); + f = 0.5 - f; + vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw; + vec3 color = vec3(0.0); + vec2 dx = vec2(SourceSize1.z, 0.0); + + float w; + float wsum = 0.0; + vec3 pixel; + float n = -SIZEH; + + do + { + pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx).rgb; + if (m_glow > 0.5) + { + pixel = max(pixel-m_glow_cutoff, 0.0); + pixel = plant(pixel, max(max(max(pixel.r,pixel.g),pixel.b)-m_glow_cutoff,0.0)); + } + w = gaussian(n+f); + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEH); + + color = color / wsum; + + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/hd/gaussian_vertical.slang b/crt/shaders/guest/hd/gaussian_vertical.slang new file mode 100644 index 0000000..29da738 --- /dev/null +++ b/crt/shaders/guest/hd/gaussian_vertical.slang @@ -0,0 +1,98 @@ +#version 450 + +/* + Gaussian blur - vertical pass, dynamic range, resizable + + Copyright (C) 2020 guest(r) - guest.r@gmail.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEV; + float SIGMA_V; +} params; + + +#pragma parameter SIZEV " Vertical Glow Radius" 6.0 1.0 50.0 1.0 +#define SIZEV params.SIZEV + +#pragma parameter SIGMA_V " Vertical Glow Sigma" 1.20 0.20 15.0 0.10 +#define SIGMA_V params.SIGMA_V + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + +float invsqrsigma = 1.0/(2.0*SIGMA_V*SIGMA_V); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +void main() +{ + vec4 SourceSize1 = vec4(params.SourceSize.x, params.OriginalSize.y, params.SourceSize.z, params.OriginalSize.w); + float f = fract(SourceSize1.y * vTexCoord.y); + f = 0.5 - f; + vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw; + vec3 color = vec3(0.0); + vec2 dy = vec2(0.0, SourceSize1.w); + + float w; + float wsum = 0.0; + vec3 pixel; + float n = -SIZEV; + + do + { + pixel = COMPAT_TEXTURE(Source, tex + n*dy).rgb; + w = gaussian(n+f); + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEV); + + color = color / wsum; + + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/hd/linearize-hd.slang b/crt/shaders/guest/hd/linearize-hd.slang index d50935b..9c9e6a3 100644 --- a/crt/shaders/guest/hd/linearize-hd.slang +++ b/crt/shaders/guest/hd/linearize-hd.slang @@ -3,7 +3,7 @@ /* Interlacing - Copyright (C) 2020-2021 guest(r) - guest.r@gmail.com + Copyright (C) 2020-2023 guest(r) - guest.r@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -59,7 +59,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4" 4.0 0.0 4.0 1.0 #define interm params.interm // interlace mode -#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05 +#pragma parameter iscan " Interlacing Scanline Effect ('Laced brightness)" 0.20 0.0 1.0 0.05 #define iscan params.iscan // interlacing effect scanlining #pragma parameter intres " Internal Resolution Y: 0.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match @@ -129,7 +129,7 @@ void main() c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r); if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii); } - if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; } + if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)) * (1.0-0.5*iscan); } } c = pow(c, vec3(gamma_in)); diff --git a/crt/shaders/guest/hd/pre-shaders-afterglow.slang b/crt/shaders/guest/hd/pre-shaders-afterglow.slang index d2369e5..9fb8b32 100644 --- a/crt/shaders/guest/hd/pre-shaders-afterglow.slang +++ b/crt/shaders/guest/hd/pre-shaders-afterglow.slang @@ -3,7 +3,7 @@ /* CRT Advanced Afterglow, color altering - Copyright (C) 2019-2022 guest(r) and Dr. Venom + Copyright (C) 2019-2023 guest(r) and Dr. Venom This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -60,7 +60,7 @@ layout(push_constant) uniform Push #pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0 #define TNTC params.TNTC -#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0 +#pragma parameter LS " LUT Size" 32.0 16.0 64.0 16.0 #define LS params.LS #define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons