diff --git a/crt/crt-guest-advanced-fast.slangp b/crt/crt-guest-advanced-fast.slangp new file mode 100644 index 0000000..f705d6c --- /dev/null +++ b/crt/crt-guest-advanced-fast.slangp @@ -0,0 +1,72 @@ +shaders = 9 + +textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" +SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png +SamplerLUT1_linear = true +SamplerLUT2 = shaders/guest/advanced/lut/inv-trinitron-lut.png +SamplerLUT2_linear = true +SamplerLUT3 = shaders/guest/advanced/lut/nec-lut.png +SamplerLUT3_linear = true +SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png +SamplerLUT4_linear = true + +shader0 = ../stock.slang +filter_linear0 = false +scale_type0 = source +scale0 = 1.0 + +shader1 = ../stock.slang +filter_linear1 = false +scale_type1 = source +scale1 = 1.0 +alias1 = StockPass + +shader2 = shaders/guest/fast/pre-shaders.slang +filter_linear2 = true +scale_type2 = source +scale2 = 1.0 +alias2 = PrePass + +shader3 = shaders/guest/fast/linearize.slang +filter_linear3 = true +scale_type3 = source +scale3 = 1.0 +float_framebuffer3 = true +alias3 = LinearizePass + +shader4 = shaders/guest/fast/bloom_horizontal.slang +filter_linear4 = true +scale_type_x4 = absolute +scale_x4 = 800.0 +scale_type_y4 = source +scale_y4 = 1.0 +float_framebuffer4 = true + +shader5 = shaders/guest/fast/bloom_vertical.slang +filter_linear5 = true +scale_type_x5 = source +scale_x5 = 1.0 +scale_type_y5 = source +scale_y5 = 2.0 +float_framebuffer5 = true +alias5 = BloomPass + +shader6 = shaders/guest/fast/crt-guest-advanced-pass1.slang +filter_linear6 = true +scale_type_x6 = viewport +scale_x6 = 1.0 +scale_type_y6 = source +scale_y6 = 0.5 +float_framebuffer6 = true + +shader7 = shaders/guest/fast/crt-guest-advanced-pass2.slang +filter_linear7 = true +scale_type7 = viewport +scale_x7 = 1.0 +scale_y7 = 1.0 + +shader8 = shaders/guest/fast/deconvergence-f.slang +filter_linear8 = true +scale_type8 = viewport +scale_x8 = 1.0 +scale_y8 = 1.0 diff --git a/crt/crt-guest-advanced-fastest.slangp b/crt/crt-guest-advanced-fastest.slangp new file mode 100644 index 0000000..f5f124b --- /dev/null +++ b/crt/crt-guest-advanced-fastest.slangp @@ -0,0 +1,39 @@ +shaders = 4 + +textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" +SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png +SamplerLUT1_linear = true +SamplerLUT2 = shaders/guest/advanced/lut/inv-trinitron-lut.png +SamplerLUT2_linear = true +SamplerLUT3 = shaders/guest/advanced/lut/nec-lut.png +SamplerLUT3_linear = true +SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png +SamplerLUT4_linear = true + +shader0 = shaders/guest/fast/pre-shadersf.slang +filter_linear0 = true +scale_type0 = source +scale0 = 1.0 +alias0 = PrePassDontChange + +shader1 = shaders/guest/fast/linearizef.slang +filter_linear1 = true +scale_type1 = source +scale1 = 1.0 +float_framebuffer1 = true +alias1 = LinearizePass + +shader2 = shaders/guest/fast/crt-guest-advanced-pass1f.slang +filter_linear2 = true +scale_type_x2 = viewport +scale_x2 = 1.0 +scale_type_y2 = source +scale_y2 = 1.0 +float_framebuffer2 = true + +shader3 = shaders/guest/fast/crt-guest-advanced-pass2f.slang +filter_linear3 = true +scale_type3 = viewport +scale_x3 = 1.0 +scale_y3 = 1.0 +alias3 = Pass2 diff --git a/crt/crt-guest-advanced-hires.slangp b/crt/crt-guest-advanced-hires.slangp new file mode 100644 index 0000000..d92ee91 --- /dev/null +++ b/crt/crt-guest-advanced-hires.slangp @@ -0,0 +1,78 @@ +shaders = 10 + +shader0 = ../stock.slang +filter_linear0 = false +scale_type0 = source +scale0 = 1.0 + +shader1 = ../stock.slang +filter_linear1 = false +scale_type1 = source +scale1 = 1.0 +alias1 = StockPass + +shader2 = shaders/guest/advanced/afterglow0.slang +filter_linear2 = false +scale_type2 = source +scale2 = 1.0 +alias2 = AfterglowPass + +shader3 = shaders/guest/advanced/pre-shaders-afterglow.slang +filter_linear3 = false +scale_type3 = source +scale3 = 1.0 +mipmap_input3 = true +alias3 = PrePass + +textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" +SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png +SamplerLUT1_linear = true +SamplerLUT2 = shaders/guest/advanced/lut/inv-trinitron-lut.png +SamplerLUT2_linear = true +SamplerLUT3 = shaders/guest/advanced/lut/nec-lut.png +SamplerLUT3_linear = true +SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png +SamplerLUT4_linear = true + +shader4 = shaders/guest/advanced/avg-lum-hires.slang +filter_linear4 = true +scale_type4 = source +scale4 = 1.0 +mipmap_input4 = true +alias4 = AvgLumPass + +shader5 = shaders/guest/advanced/linearize-hires.slang +filter_linear5 = true +scale_type5 = source +scale5 = 1.0 +alias5 = LinearizePass +float_framebuffer5 = true + +shader6 = shaders/guest/advanced/bloom_horizontal_ntsc.slang +filter_linear6 = true +scale_type_x6 = absolute +scale_x6 = 800.0 +scale_type_y6 = source +scale_y6 = 1.0 +float_framebuffer6 = true + +shader7 = shaders/guest/advanced/bloom_vertical_ntsc.slang +filter_linear7 = true +scale_type_x7 = absolute +scale_x7 = 800.0 +scale_type_y7 = absolute +scale_y7 = 600.0 +float_framebuffer7 = true +alias7 = GlowPass + +shader8 = shaders/guest/advanced/crt-guest-advanced-hires.slang +filter_linear8 = true +scale_type8 = viewport +scale_x8 = 1.0 +scale_y8 = 1.0 + +shader9 = shaders/guest/advanced/deconvergence.slang +filter_linear9 = true +scale_type9 = viewport +scale_x9 = 1.0 +scale_y9 = 1.0 diff --git a/crt/crt-guest-advanced.slangp b/crt/crt-guest-advanced.slangp new file mode 100644 index 0000000..49f4a92 --- /dev/null +++ b/crt/crt-guest-advanced.slangp @@ -0,0 +1,95 @@ +shaders = 12 + +shader0 = ../stock.slang +filter_linear0 = false +scale_type0 = source +scale0 = 1.0 + +shader1 = ../stock.slang +filter_linear1 = false +scale_type1 = source +scale1 = 1.0 +alias1 = StockPass + +shader2 = shaders/guest/advanced/afterglow0.slang +filter_linear2 = false +scale_type2 = source +scale2 = 1.0 +alias2 = AfterglowPass + +shader3 = shaders/guest/advanced/pre-shaders-afterglow.slang +filter_linear3 = false +scale_type3 = source +mipmap_input3 = true +scale3 = 1.0 +alias3 = PrePass + +textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" +SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png +SamplerLUT1_linear = true +SamplerLUT2 = shaders/guest/advanced/lut/inv-trinitron-lut.png +SamplerLUT2_linear = true +SamplerLUT3 = shaders/guest/advanced/lut/nec-lut.png +SamplerLUT3_linear = true +SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png +SamplerLUT4_linear = true + +shader4 = shaders/guest/advanced/avg-lum.slang +filter_linear4 = true +scale_type4 = source +scale4 = 1.0 +mipmap_input4 = true +alias4 = AvgLumPass + +shader5 = shaders/guest/advanced/linearize.slang +filter_linear5 = true +scale_type5 = source +scale5 = 1.0 +alias5 = LinearizePass +float_framebuffer5 = true + +shader6 = shaders/guest/advanced/gaussian_horizontal.slang +filter_linear6 = true +scale_type_x6 = absolute +scale_x6 = 800.0 +scale_type_y6 = source +scale_y6 = 1.0 +float_framebuffer6 = true + +shader7 = shaders/guest/advanced/gaussian_vertical.slang +filter_linear7 = true +scale_type_x7 = absolute +scale_x7 = 800.0 +scale_type_y7 = absolute +scale_y7 = 600.0 +float_framebuffer7 = true +alias7 = GlowPass + +shader8 = shaders/guest/advanced/bloom_horizontal.slang +filter_linear8 = true +scale_type_x8 = absolute +scale_x8 = 800.0 +scale_type_y8 = absolute +scale_y8 = 600.0 +float_framebuffer8 = true + +shader9 = shaders/guest/advanced/bloom_vertical.slang +filter_linear9 = true +scale_type_x9 = source +scale_x9 = 1.0 +scale_type_y9 = source +scale_y9 = 1.0 +float_framebuffer9 = true +alias9 = BloomPass + +shader10 = shaders/guest/advanced/crt-guest-advanced.slang +filter_linear10 = true +scale_type10 = viewport +scale_x10 = 1.0 +scale_y10 = 1.0 + +shader11 = shaders/guest/advanced/deconvergence.slang +filter_linear11 = true +scale_type11 = viewport +scale_x11 = 1.0 +scale_y11 = 1.0 diff --git a/crt/crt-guest-dr-venom2.slangp b/crt/crt-guest-dr-venom2.slangp deleted file mode 100644 index cc82eaa..0000000 --- a/crt/crt-guest-dr-venom2.slangp +++ /dev/null @@ -1,85 +0,0 @@ -shaders = 11 - -shader0 = ../stock.slang -filter_linear0 = false -scale_type0 = source -scale0 = 1.0 -alias0 = StockPass - -shader1 = shaders/guest/crt-gdv-new/afterglow0.slang -filter_linear1 = false -scale_type1 = source -scale1 = 1.0 -alias1 = AfterglowPass - -shader2 = shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang -filter_linear2 = false -scale_type2 = source -scale2 = 1.0 -alias2 = PrePass - -textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" -SamplerLUT1 = shaders/guest/lut/sony_trinitron1.png -SamplerLUT1_linear = true -SamplerLUT2 = shaders/guest/lut/sony_trinitron2.png -SamplerLUT2_linear = true -SamplerLUT3 = shaders/guest/lut/other1.png -SamplerLUT3_linear = true -SamplerLUT4 = shaders/guest/lut/custom_lut.png -SamplerLUT4_linear = true - -shader3 = shaders/guest/crt-gdv-new/avg-lum.slang -filter_linear3 = true -scale_type3 = source -scale3 = 1.0 -mipmap_input3 = true -alias3 = AvgLumPass - -shader4 = shaders/guest/crt-gdv-new/linearize.slang -filter_linear4 = true -scale_type4 = source -scale4 = 1.0 -alias4 = LinearizePass -float_framebuffer4 = true # comment this line for max precision - -shader5 = shaders/guest/crt-gdv-new/gaussian_horizontal.slang -filter_linear5 = true -scale_type_x5 = viewport -scale_x5 = 0.5 -scale_type_y5 = source -scale_y5 = 1.0 - -shader6 = shaders/guest/crt-gdv-new/gaussian_vertical.slang -filter_linear6 = true -scale_type_x6 = viewport -scale_x6 = 0.5 -scale_type_y6 = viewport -scale_y6 = 0.5 -alias6 = GlowPass - -shader7 = shaders/guest/crt-gdv-new/bloom_horizontal.slang -filter_linear7 = true -scale_type_x7 = source -scale_x7 = 1.0 -scale_type_y7 = source -scale_y7 = 1.0 - -shader8 = shaders/guest/crt-gdv-new/bloom_vertical.slang -filter_linear8 = true -scale_type_x8 = source -scale_x8 = 1.0 -scale_type_y8 = source -scale_y8 = 1.0 -alias8 = BloomPass - -shader9 = shaders/guest/crt-gdv-new/crt-guest-dr-venom2.slang -filter_linear9 = true -scale_type9 = viewport -scale_x9 = 1.0 -scale_y9 = 1.0 - -shader10 = shaders/guest/crt-gdv-new/deconvergence.slang -filter_linear10 = true -scale_type10 = viewport -scale_x10 = 1.0 -scale_y10 = 1.0 diff --git a/crt/shaders/guest/advanced/afterglow0.slang b/crt/shaders/guest/advanced/afterglow0.slang new file mode 100644 index 0000000..ad482a2 --- /dev/null +++ b/crt/shaders/guest/advanced/afterglow0.slang @@ -0,0 +1,76 @@ +#version 450 + +/* + Phosphor Afterglow Shader pass 0 + + 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 +{ + float PR, PG, PB; +} params; + +#pragma parameter bogus_afterglow "[ AFTERGLOW SETTINGS ]:" 0.0 0.0 1.0 1.0 +#pragma parameter PR " Persistence Red" 0.25 0.0 0.50 0.01 +#pragma parameter PG " Persistence Green" 0.25 0.0 0.50 0.01 +#pragma parameter PB " Persistence Blue" 0.25 0.0 0.50 0.01 + +#define PR params.PR +#define PG params.PG +#define PB params.PB + +#define COMPAT_TEXTURE(c,d) texture(c,d) + +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 OriginalHistory0; +layout(set = 0, binding = 3) uniform sampler2D AfterglowPassFeedback; + +#define TEX0 vTexCoord + + +void main() +{ + vec3 color = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy).rgb; + vec3 accumulate = COMPAT_TEXTURE(AfterglowPassFeedback, TEX0.xy).rgb; + + float w = 1.0; + if ((color.r + color.g + color.b < 1.5/255.0)) { w = 0.0; } + + vec3 result = mix( max(mix(color, accumulate, 0.49 + vec3(PR, PG, PB))- 3.0/255.0, 0.0), color, w); + + FragColor = vec4(result, w); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/avg-lum-hires.slang b/crt/shaders/guest/advanced/avg-lum-hires.slang new file mode 100644 index 0000000..e446989 --- /dev/null +++ b/crt/shaders/guest/advanced/avg-lum-hires.slang @@ -0,0 +1,87 @@ +#version 450 + +/* + Average Luminance Shader + + Copyright (C) 2018-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. + + Thanks to HunterK for the mipmap hint. :D +*/ + +layout(push_constant) uniform Push +{ + uint FrameCount; + vec4 SourceSize; + float lsmooth; +} params; + +#pragma parameter lsmooth "Raster Bloom Effect Smoothing" 0.70 0.50 0.99 0.01 + +#define lsmooth params.lsmooth + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define SourceSize params.SourceSize +#define InputSize SourceSize +#define TEX0 vTexCoord + +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 * 1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D PrePass; +layout(set = 0, binding = 3) uniform sampler2D AvgLumPassFeedback; + + +void main() +{ + if (vTexCoord.x > 0.2 || vTexCoord.y > 0.2) discard; + + float m = max(log2(SourceSize.x), log2(SourceSize.y)); + m = floor(max(m, 1.0)); + + float ltotal = 0.0; + + ltotal+= length(textureLod(PrePass, vec2(0.25, 0.25), m).rgb); + ltotal+= length(textureLod(PrePass, vec2(0.25, 0.75), m).rgb); + ltotal+= length(textureLod(PrePass, vec2(0.75, 0.25), m).rgb); + ltotal+= length(textureLod(PrePass, vec2(0.75, 0.75), m).rgb); + + ltotal*=0.25; + + ltotal = pow(0.577350269 * ltotal, 0.65); + + float lhistory = texture(AvgLumPassFeedback, vec2(0.1,0.1)).a; + + ltotal = mix(ltotal, lhistory, lsmooth); + + FragColor = vec4(ltotal); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/avg-lum-ntsc.slang b/crt/shaders/guest/advanced/avg-lum-ntsc.slang new file mode 100644 index 0000000..86da9b9 --- /dev/null +++ b/crt/shaders/guest/advanced/avg-lum-ntsc.slang @@ -0,0 +1,110 @@ +#version 450 + +/* + Average Luminance Shader, Smart Edge Interpolation Coefficients Calculation + + Copyright (C) 2018-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. + + Thanks to HunterK for the mipmap hint. :D +*/ + +layout(push_constant) uniform Push +{ + uint FrameCount; + vec4 SourceSize; + float lsmooth; + float sth; +} params; + +#pragma parameter lsmooth "Raster Bloom Effect Smoothing" 0.70 0.50 0.99 0.01 + +#define lsmooth params.lsmooth + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define SourceSize params.SourceSize +#define TEX0 vTexCoord + +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 * 1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D AvgLumPassFeedback; + +// Reference: http://www.compuphase.com/cmetric.htm +// Reference: ScaleFX, author Sp00kyFox + +float dist(vec3 A, vec3 B) +{ + float r = 0.5 * (A.r + B.r); + vec3 d = A - B; + vec3 c = vec3(2. + r, 4., 3. - r); + + return sqrt(dot(c*d, d)) / 3.; +} + +void main() +{ + float m = max(log2(SourceSize.x), log2(SourceSize.y)); + m = floor(max(m, 1.0)); + + vec2 dx = vec2(1.0/SourceSize.x, 0.0); + vec2 dy = vec2(0.0, 1.0/SourceSize.y); + vec2 y2 = 2.0*dy; + vec2 x2 = 2.0*dx; + + float ltotal = 0.0; + + ltotal+= length(textureLod(Source, vec2(0.25, 0.25), m).rgb); + ltotal+= length(textureLod(Source, vec2(0.25, 0.75), m).rgb); + ltotal+= length(textureLod(Source, vec2(0.75, 0.25), m).rgb); + ltotal+= length(textureLod(Source, vec2(0.75, 0.75), m).rgb); + + ltotal*=0.25; + + ltotal = pow(0.577350269 * ltotal, 0.65); + + float lhistory = texture(AvgLumPassFeedback, vec2(0.5,0.5)).a; + + ltotal = mix(ltotal, lhistory, lsmooth); + + vec3 l1 = COMPAT_TEXTURE(Source, TEX0.xy ).rgb; + vec3 r1 = COMPAT_TEXTURE(Source, TEX0.xy +dx ).rgb; + vec3 l2 = COMPAT_TEXTURE(Source, TEX0.xy -dx ).rgb; + vec3 r2 = COMPAT_TEXTURE(Source, TEX0.xy +x2 ).rgb; + + float c1 = dist(l2,l1); + float c2 = dist(l1,r1); + float c3 = dist(r2,r1); + + FragColor = vec4(c1,c2,c3,ltotal); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/avg-lum.slang b/crt/shaders/guest/advanced/avg-lum.slang new file mode 100644 index 0000000..86da9b9 --- /dev/null +++ b/crt/shaders/guest/advanced/avg-lum.slang @@ -0,0 +1,110 @@ +#version 450 + +/* + Average Luminance Shader, Smart Edge Interpolation Coefficients Calculation + + Copyright (C) 2018-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. + + Thanks to HunterK for the mipmap hint. :D +*/ + +layout(push_constant) uniform Push +{ + uint FrameCount; + vec4 SourceSize; + float lsmooth; + float sth; +} params; + +#pragma parameter lsmooth "Raster Bloom Effect Smoothing" 0.70 0.50 0.99 0.01 + +#define lsmooth params.lsmooth + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define SourceSize params.SourceSize +#define TEX0 vTexCoord + +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 * 1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D AvgLumPassFeedback; + +// Reference: http://www.compuphase.com/cmetric.htm +// Reference: ScaleFX, author Sp00kyFox + +float dist(vec3 A, vec3 B) +{ + float r = 0.5 * (A.r + B.r); + vec3 d = A - B; + vec3 c = vec3(2. + r, 4., 3. - r); + + return sqrt(dot(c*d, d)) / 3.; +} + +void main() +{ + float m = max(log2(SourceSize.x), log2(SourceSize.y)); + m = floor(max(m, 1.0)); + + vec2 dx = vec2(1.0/SourceSize.x, 0.0); + vec2 dy = vec2(0.0, 1.0/SourceSize.y); + vec2 y2 = 2.0*dy; + vec2 x2 = 2.0*dx; + + float ltotal = 0.0; + + ltotal+= length(textureLod(Source, vec2(0.25, 0.25), m).rgb); + ltotal+= length(textureLod(Source, vec2(0.25, 0.75), m).rgb); + ltotal+= length(textureLod(Source, vec2(0.75, 0.25), m).rgb); + ltotal+= length(textureLod(Source, vec2(0.75, 0.75), m).rgb); + + ltotal*=0.25; + + ltotal = pow(0.577350269 * ltotal, 0.65); + + float lhistory = texture(AvgLumPassFeedback, vec2(0.5,0.5)).a; + + ltotal = mix(ltotal, lhistory, lsmooth); + + vec3 l1 = COMPAT_TEXTURE(Source, TEX0.xy ).rgb; + vec3 r1 = COMPAT_TEXTURE(Source, TEX0.xy +dx ).rgb; + vec3 l2 = COMPAT_TEXTURE(Source, TEX0.xy -dx ).rgb; + vec3 r2 = COMPAT_TEXTURE(Source, TEX0.xy +x2 ).rgb; + + float c1 = dist(l2,l1); + float c2 = dist(l1,r1); + float c3 = dist(r2,r1); + + FragColor = vec4(c1,c2,c3,ltotal); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/bloom_horizontal.slang b/crt/shaders/guest/advanced/bloom_horizontal.slang new file mode 100644 index 0000000..72af8f4 --- /dev/null +++ b/crt/shaders/guest/advanced/bloom_horizontal.slang @@ -0,0 +1,101 @@ +#version 450 + +/* + Gaussian blur - horizontal 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 LinearizePassSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEHB; + float SIGMA_HB; +} params; + +#pragma parameter bogus_bloom "[ BLOOM/HALATION/(GLOW) PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter SIZEHB " Horizontal Bloom/Halation/(Glow) Radius" 4.0 1.0 50.0 1.0 +#define SIZEHB params.SIZEHB + +#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/(Glow) Sigma" 0.70 0.25 15.0 0.05 +#define SIGMA_HB params.SIGMA_HB + +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_HB*SIGMA_HB); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +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; + vec4 color = vec4(0.0); + vec2 dx = vec2(SourceSize1.z, 0.0); + + float w; + float wsum = 0.0; + vec4 pixel; + float n = -SIZEHB; + + do + { + pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx); + w = gaussian(n+f); + pixel.a = max(max(pixel.r, pixel.g),pixel.b); + pixel.a*=pixel.a*pixel.a; + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEHB); + + color = color / wsum; + + FragColor = vec4(color.rgb, pow(color.a, 0.333333)); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/bloom_horizontal_ntsc.slang b/crt/shaders/guest/advanced/bloom_horizontal_ntsc.slang new file mode 100644 index 0000000..687427f --- /dev/null +++ b/crt/shaders/guest/advanced/bloom_horizontal_ntsc.slang @@ -0,0 +1,101 @@ +#version 450 + +/* + Gaussian blur - horizontal 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 LinearizePassSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEHB; + float SIGMA_HB; +} params; + +#pragma parameter bogus_bloom "[ BLOOM/HALATION/(GLOW) PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter SIZEHB " Horizontal Bloom/Halation/(Glow) Radius" 6.0 1.0 50.0 1.0 +#define SIZEHB params.SIZEHB + +#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/(Glow) Sigma" 1.0 0.20 15.0 0.10 +#define SIGMA_HB params.SIGMA_HB + +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_HB*SIGMA_HB); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +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; + vec4 color = vec4(0.0); + vec2 dx = vec2(SourceSize1.z, 0.0); + + float w; + float wsum = 0.0; + vec4 pixel; + float n = -SIZEHB; + + do + { + pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx); + w = gaussian(n+f); + pixel.a = max(max(pixel.r, pixel.g),pixel.b); + pixel.a*=pixel.a*pixel.a; + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEHB); + + color = color / wsum; + + FragColor = vec4(color.rgb, pow(color.a, 0.333333)); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/bloom_vertical.slang b/crt/shaders/guest/advanced/bloom_vertical.slang new file mode 100644 index 0000000..5dd8a3c --- /dev/null +++ b/crt/shaders/guest/advanced/bloom_vertical.slang @@ -0,0 +1,101 @@ +#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 SIZEVB; + float SIGMA_VB; +} params; + + +#pragma parameter SIZEVB " Vertical Bloom/Halation/(Glow) Radius" 4.0 1.0 50.0 1.0 +#define SIZEVB params.SIZEVB + +#pragma parameter SIGMA_VB " Vertical Bloom/Halation/(Glow) Sigma" 0.70 0.25 15.0 0.05 +#define SIGMA_VB params.SIGMA_VB + +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_VB*SIGMA_VB); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +void main() +{ + vec4 SourceSize1 = params.SourceSize; + SourceSize1.yw = params.OriginalSize.yw; + + float f = fract(SourceSize1.y * vTexCoord.y); + f = 0.5 - f; + vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw; + vec4 color = vec4(0.0); + vec2 dy = vec2(0.0, SourceSize1.w); + + float w; + float wsum = 0.0; + vec4 pixel; + float n = -SIZEVB; + + do + { + pixel = COMPAT_TEXTURE(Source, tex + n*dy); + w = gaussian(n+f); + pixel.a*=pixel.a*pixel.a; + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEVB); + + color = color / wsum; + + FragColor = vec4(color.rgb, pow(color.a, 0.175)); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/bloom_vertical_ntsc.slang b/crt/shaders/guest/advanced/bloom_vertical_ntsc.slang new file mode 100644 index 0000000..91c6c75 --- /dev/null +++ b/crt/shaders/guest/advanced/bloom_vertical_ntsc.slang @@ -0,0 +1,101 @@ +#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 SIZEVB; + float SIGMA_VB; +} params; + + +#pragma parameter SIZEVB " Vertical Bloom/Halation/(Glow) Radius" 6.0 1.0 50.0 1.0 +#define SIZEVB params.SIZEVB + +#pragma parameter SIGMA_VB " Vertical Bloom/Halation/(Glow) Sigma" 1.0 0.20 15.0 0.10 +#define SIGMA_VB params.SIGMA_VB + +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_VB*SIGMA_VB); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +void main() +{ + vec4 SourceSize1 = params.SourceSize; + SourceSize1.yw = params.OriginalSize.yw; + + float f = fract(SourceSize1.y * vTexCoord.y); + f = 0.5 - f; + vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw; + vec4 color = vec4(0.0); + vec2 dy = vec2(0.0, SourceSize1.w); + + float w; + float wsum = 0.0; + vec4 pixel; + float n = -SIZEVB; + + do + { + pixel = COMPAT_TEXTURE(Source, tex + n*dy); + w = gaussian(n+f); + pixel.a*=pixel.a*pixel.a; + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEVB); + + color = color / wsum; + + FragColor = vec4(color.rgb, pow(color.a, 0.175)); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/convert-ntsc.slang b/crt/shaders/guest/advanced/convert-ntsc.slang new file mode 100644 index 0000000..2778803 --- /dev/null +++ b/crt/shaders/guest/advanced/convert-ntsc.slang @@ -0,0 +1,69 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float blendMode; +} params; + +#pragma parameter blendMode "NTSC Blend Mode (Main Mode Control)" 1.0 0.0 2.0 1.0 + +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; +layout(set = 0, binding = 3) uniform sampler2D PrePass0; + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + +vec3 declip(vec3 c, float b) +{ + float m = max(max(c.r,c.g),c.b); + if (m > b) c = c*b/m; + return c; +} + +void main() +{ + vec2 dx = vec2(params.SourceSize.z * 0.5, 0.0); + vec3 col1 = texture(Source, vTexCoord -dx).rgb; + vec3 col2 = texture(Source, vTexCoord +dx).rgb; + vec3 colc = max(col1, col2); + vec3 col = plant(sqrt(col1*col2), max(max(colc.r, colc.g),colc.b)); + + vec3 orig = texture(PrePass0, vTexCoord).rgb; + vec3 res = normalize(col + 0.00001) * min(length(col), length(orig)); + + float k2 = 1.0/(dot(col1 - res, col1 - res) + 0.0001); + float k3 = 1.0/(dot(col2 - res, col2 - res) + 0.0001); + + vec3 res1 = (k2 * col1 + k3 * col2) / (k2 + k3); + res1 = clamp(res1, min(col1,col2), max(col1, col2)); + + if ( params.blendMode == 1.0) res = res1; + + FragColor = vec4(res, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/crt-guest-advanced-hires.slang b/crt/shaders/guest/advanced/crt-guest-advanced-hires.slang new file mode 100644 index 0000000..7a3dda4 --- /dev/null +++ b/crt/shaders/guest/advanced/crt-guest-advanced-hires.slang @@ -0,0 +1,775 @@ +#version 450 + +/* + CRT - Guest - Advanced (Hi-Res version) + + Copyright (C) 2018-2021 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. + + 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 +{ + float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, + h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask, + slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, intres; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float bloom; + float halation; + float mclip; + float scans; + float scansub; + float slotms; + float gamma_c; + float mask_gamma; + float gamma_out; + float overscanX; + float overscanY; + float c_shape; + float barspeed; + float barintensity; + float bardir; +} global; + +#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 +#define glow params.glow // Glow Strength + +#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05 +#define bloom global.bloom // bloom effect + +#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025 +#define halation global.halation // halation effect + +#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02 +#define gamma_c global.gamma_c // adjust brightness + +#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025 +#define brightboost1 params.brightboost1 // adjust brightness + +#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#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 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 40.0 1.0 +#define scanline2 params.scanline2 // scanline param, vertical sharpness + +#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 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 2.5 0.05 +#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" 0.60 0.0 1.0 0.05 +#define scans global.scans // scanline saturation + + +// Scanline darken 'edges' effect - need to uncomment it. + +// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005 +// #define scansub global.scansub // scanline substraction + +#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10 +#define spike params.spike + +#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.10 +#define h_sharp params.h_sharp // pixel sharpness + +#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10 +#define s_sharp params.s_sharp // substractive sharpness + +#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match +#define intres params.intres // interlace resolution + +#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0 +#define TATE params.TATE // Screen orientation + +#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0 +#define IOS params.IOS // Smart Integer Scaling + +#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0 +#define OS params.OS // Do overscan + +#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0 +#define BLOOM params.BLOOM // Bloom overscan percentage + +#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01 +#define csize params.csize // corner size + +#pragma parameter bsize " Border smoothness" 600.0 100.0 700.0 10.0 +#define bsize params.bsize // border smoothness + +#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0 + +#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01 + +#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0 + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01 +#define warpX params.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01 +#define warpY params.warpY // Curvature Y + +#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05 +#define c_shape global.c_shape // curvature shape + +#pragma parameter overscanX " Overscan X original pixels" 0.0 -50.0 50.0 1.0 +#define overscanX global.overscanX // OverscanX pixels + +#pragma parameter overscanY " Overscan Y original pixels" 0.0 -50.0 50.0 1.0 +#define overscanY global.overscanY // OverscanY pixels + +#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0 +#define shadowMask params.shadowMask // Mask Style + +#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05 +#define maskstr params.maskstr // maskstr Mask Strength + +#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 dark color strength + +#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0 +#define masksize params.masksize // Mask Size + +#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 +#define maskDark params.maskDark // Dark "Phosphor" + +#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05 +#define maskLight params.maskLight // Light "Phosphor" + +#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05 +#define mask_gamma global.mask_gamma // Mask application gamma + +#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask + +#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 6.0 0.5 +#define slotwidth params.slotwidth // Slot Mask Width + +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.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 mclip " Keep Mask effect with clipping" 0.5 0.0 1.0 0.05 +#define mclip global.mclip // Slot Mask Size + +#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05 +#define gamma_out global.gamma_out // output gamma + + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define TEX0 vTexCoord + +#define OutputSize global.OutputSize +#define gl_FragCoord (vTexCoord * OutputSize.xy) + +#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 * 1.00001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D LinearizePass; +layout(set = 0, binding = 3) uniform sampler2D AvgLumPass; +layout(set = 0, binding = 4) uniform sampler2D GlowPass; +layout(set = 0, binding = 5) uniform sampler2D PrePass; + +#define eps 1e-10 + +float st(float x) +{ + return exp2(-10.0*x*x); +} + +float sw0(float x, float color, float scanline) +{ + float tmp = mix(beam_min, beam_max, color); + float ex = x*tmp; + ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4); + return exp2(-scanline*ex); +} + +float sw1(float x, float color, float scanline) +{ + x = mix (x, beam_min*x, max(x-0.4*color,0.0)); + float tmp = mix(1.2*beam_min, beam_max, color); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +float sw2(float x, float color, float scanline) +{ + float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color); + tmp = mix(beam_max, tmp, pow(x, color+0.3)); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +// Shadow mask (1-4 from PD CRT Lottes shader). + +vec3 Mask(vec2 pos, float mx) +{ + pos = floor(pos/masksize); + vec3 mask = vec3(maskDark, maskDark, maskDark); + vec3 one = vec3(1.0); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 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); + } + + // Phosphor. + else if (shadowMask == 0.0) + { + pos.x = fract(pos.x*0.5); + if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } + else { mask.r = mc; mask.g = 1.0; mask.b = mc; } + } + + // Very compressed TV style shadow mask. + else if (shadowMask == 1.0) + { + float line = maskLight; + float odd = 0.0; + + if (fract(pos.x/6.0) < 0.5) + odd = 1.0; + if (fract((pos.y + odd)/2.0) < 0.5) + line = maskDark; + + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + + mask*=line; + } + + // Aperture-grille. + else if (shadowMask == 2.0) + { + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // VGA style shadow mask. + else if (shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Trinitron mask 5 + else if (shadowMask == 5.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) + { mask.r = 1.0; + 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; + } + + // Trinitron mask 6 + else if (shadowMask == 6.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/3.0); + if (pos.x < 0.333) mask.r = 1.0; + else if (pos.x < 0.666) 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; + } + + // BW Trinitron mask 7 + else if (shadowMask == 7.0) + { + float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = vec3(maskTmp); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) mask = vec3(1.0); + } + + // 4k mask + else + { + 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.rg = 1.0.xx; + else if (pos.x < 0.7) mask.gb = 1.0.xx; + else mask.b = 1.0; + } + + return mask; +} + +float SlotMask(vec2 pos, float m) +{ + if ((slotmask + slotmask1) == 0.0) return 1.0; + else + { + pos = floor(pos/slotms); + float mlen = slotwidth*2.0; + float px = fract(pos.x/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; + + return slot; + } +} + +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape); + return pos*0.5 + 0.5; +} + +vec2 Overscan(vec2 pos, float dx, float dy){ + pos=pos*2.0-1.0; + pos*=vec2(dx,dy); + return pos*0.5+0.5; +} + +float humbar(float pos) +{ + if (global.barintensity == 0.0) return 1.0; else + { + pos = (global.barintensity >= 0.0) ? pos : (1.0-pos); + pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0)); + pos = (global.barintensity < 0.0) ? pos : (1.0-pos); + return (1.0-global.barintensity) + global.barintensity*pos; + } +} + +// Borrowed from maskstr's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002))); + coord = (cdist - min(coord,cdist)); + float dist = sqrt(dot(coord,coord)); + return clamp((cdist.x-dist)*bsize,0.0, 1.0); +} + +vec3 declip(vec3 c, float b) +{ + float m = max(max(c.r,c.g),c.b); + if (m > b) c = c*b/m; + return c; +} + +vec3 gc(vec3 c) +{ + float mc = max(max(c.r,c.g),c.b); + float mg = pow(mc, 1.0/gamma_c); + return c * mg/(mc + eps); +} + +void main() +{ + vec4 SourceSize = global.OriginalSize; + + float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.1,0.1)).a; + 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.75); + + bool notate = (TATE < 0.5); + + float SourceY = mix(SourceSize.y, SourceSize.x, TATE); + float sy = 1.0; + if (intres == 0.5) sy = SourceY/224.0; else + if (intres == 1.0) sy = SourceY/240.0; else + if (intres > 1.25) sy = intres; + if (notate) SourceSize.yw*=vec2(1.0/sy, sy); else SourceSize.xz*=vec2(1.0/sy, sy); + + // Calculating texel coordinates + + vec2 texcoord = TEX0.xy; + if (IOS > 0.0){ + vec2 ofactor = OutputSize.xy/SourceSize.xy; + vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor); + vec2 diff = ofactor/intfactor; + float scan = mix(diff.y, diff.x, TATE); + texcoord = Overscan(texcoord, scan, scan); + if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE); + } + + float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0; + texcoord = Overscan(texcoord, factor, factor); + texcoord = Overscan(texcoord, (SourceSize.x - overscanX)/SourceSize.x, (SourceSize.y - overscanY)/SourceSize.y); + vec2 pos = Warp(texcoord); + vec2 pos0 = Warp(TEX0.xy); + + vec2 coffset = vec2(0.5, 0.5); + + vec2 ps = SourceSize.zw; + vec2 OGL2Pos = pos * SourceSize.xy - coffset; + vec2 fp = fract(OGL2Pos); + + vec2 dx = vec2(ps.x,0.0); + vec2 dy = vec2(0.0, ps.y); + + // Reading the texels + vec2 x2 = 2.0*dx; + vec2 y2 = 2.0*dy; + + vec2 offx = dx; + vec2 off2 = x2; + vec2 offy = dy; + float fpx = fp.x; + if(!notate) + { + offx = dy; + off2 = y2; + offy = dx; + fpx = fp.y; + } + float f = (notate) ? fp.y : fp.x; + + vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps; + + if (interb) pC4.y = pos.y; + + float h_sharp1 = pow(h_sharp, 1.4); + + float zero = exp2(-h_sharp1); + + float sharp1 = s_sharp * zero; + + float wl5 = 4.0 + fpx; wl5*=0.5; + float wl4 = 3.0 + fpx; wl4*=0.5; + float wl3 = 2.0 + fpx; wl3*=0.5; + float wl2 = 1.0 + fpx; wl2*=0.5; + float wl1 = fpx; wl1*=0.5; + float wr1 = 1.0 - fpx; wr1*=0.5; + float wr2 = 2.0 - fpx; wr2*=0.5; + float wr3 = 3.0 - fpx; wr3*=0.5; + float wr4 = 4.0 - fpx; wr4*=0.5; + float wr5 = 5.0 - fpx; wr5*=0.5; + + wl5*=wl5; wl5 = exp2(-h_sharp1*wl5); + wl4*=wl4; wl4 = exp2(-h_sharp1*wl4); + wl3*=wl3; wl3 = exp2(-h_sharp1*wl3); + wl2*=wl2; wl2 = exp2(-h_sharp1*wl2); + wl1*=wl1; wl1 = exp2(-h_sharp1*wl1); + wr1*=wr1; wr1 = exp2(-h_sharp1*wr1); + wr2*=wr2; wr2 = exp2(-h_sharp1*wr2); + wr3*=wr3; wr3 = exp2(-h_sharp1*wr3); + wr4*=wr4; wr4 = exp2(-h_sharp1*wr4); + wr5*=wr5; wr5 = exp2(-h_sharp1*wr5); + + float fp1 = 1.-fpx; + + float twl5 = max(wl5 - sharp1, 0.0); + float twl4 = max(wl4 - sharp1, mix(0.0,mix(-0.03, 0.00, fpx),float(s_sharp > 0.05))); float swl4 = max(wl4 - sharp1, 0.0); + float twl3 = max(wl3 - sharp1, mix(0.0,mix(-0.10, -0.03, fpx),float(s_sharp > 0.05))); float swl3 = max(wl3 - sharp1, 0.0); + float twl2 = max(wl2 - sharp1, 0.0); + float twl1 = max(wl1 - sharp1, 0.0); + float twr1 = max(wr1 - sharp1, 0.0); + float twr2 = max(wr2 - sharp1, 0.0); + float twr3 = max(wr3 - sharp1, mix(0.0,mix(-0.10, -0.03, fp1),float(s_sharp > 0.05))); float swr3 = max(wr3 - sharp1, 0.0); + float twr4 = max(wr4 - sharp1, mix(0.0,mix(-0.03, 0.00, fp1),float(s_sharp > 0.05))); float swr4 = max(wr4 - sharp1, 0.0); + float twr5 = max(wr5 - sharp1, 0.0); + + float wtt = 1.0/(twl5+twl4+twl3+twl2+twl1+twr1+twr2+twr3+twr4+twr5); + float wt = 1.0/(swl3+twl2+twl1+twr1+twr2+swr3); + bool sharp = (s_sharp > 0.05); + + vec3 l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz; + vec3 l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz; + vec3 l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz; + vec3 l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz; + vec3 l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz; + vec3 r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz; + vec3 r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz; + vec3 r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz; + vec3 r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz; + vec3 r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz; + + vec3 sl3 = l3*l3*l3; sl3*=sl3; + vec3 sl2 = l2*l2*l2; sl2*=sl2; + vec3 sl1 = l1*l1*l1; sl1*=sl1; + vec3 sr1 = r1*r1*r1; sr1*=sr1; + vec3 sr2 = r2*r2*r2; sr2*=sr2; + vec3 sr3 = r3*r3*r3; sr3*=sr3; + + vec3 color1 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt; + + vec3 colmin1 = min(min(l1,r1), min(l2,r2)); + vec3 colmax1 = max(max(l1,r1), max(l2,r2)); + vec3 colmin2 = min(min(l3,r3), min(l4,r4)); + vec3 colmax2 = max(max(l3,r3), max(l4,r4)); + vec3 colmin = min(colmin1, colmin2); + vec3 colmax = max(colmax1, colmax2); + + if (sharp) color1 = clamp(color1, colmin, colmax); + + vec3 gtmp = vec3(1.0/6.0); + + vec3 scolor1 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt; + scolor1 = pow(scolor1, gtmp); vec3 mcolor1 = scolor1; + scolor1 = min(mix(color1, scolor1, spike),1.0); + + vec3 color2, scolor2, mcolor2; + + if (!interb) +{ + pC4+=offy; + + l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz; + l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz; + l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz; + l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz; + l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz; + r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz; + r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz; + r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz; + r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz; + r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz; + + sl3 = l3*l3*l3; sl3*=sl3; + sl2 = l2*l2*l2; sl2*=sl2; + sl1 = l1*l1*l1; sl1*=sl1; + sr1 = r1*r1*r1; sr1*=sr1; + sr2 = r2*r2*r2; sr2*=sr2; + sr3 = r3*r3*r3; sr3*=sr3; + + color2 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt; + + colmin1 = min(min(l1,r1), min(l2,r2)); + colmax1 = max(max(l1,r1), max(l2,r2)); + colmin2 = min(min(l3,r3), min(l3,r3)); + colmax2 = max(max(l4,r4), max(l4,r4)); + colmin = min(colmin1, colmin2); + colmax = max(colmax1, colmax2); + + if (sharp) color2 = clamp(color2, colmin, colmax); + + scolor2 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt; + scolor2 = pow(scolor2, gtmp); mcolor2 = scolor2; + scolor2 = min(mix(color2, scolor2, spike),1.0); +} + // calculating scanlines + + vec3 ctmp; vec3 mcolor; float w3; vec3 color; + vec3 one = vec3(1.0); + +if (!interb) +{ + float shape1 = mix(scanline1, scanline2, f); + float shape2 = mix(scanline1, scanline2, 1.0-f); + + float wt1 = st(f); + float wt2 = st(1.0-f); + + vec3 color00 = color1*wt1 + color2*wt2; + vec3 scolor0 = scolor1*wt1 + scolor2*wt2; + mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2); + + ctmp = color00/(wt1+wt2); + vec3 sctmp = scolor0/(wt1+wt2); + + float wf1, wf2; + + vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b); + vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b); + + float f1 = f; + float f2 = 1.0-f; + + if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else + if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else + { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);} + + if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; } + + // Scanline darken 'edges' effect - need to uncomment it. + + // float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1); + // float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2); + + // Scanline saturation application + + vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2); + w3 = wf1+wf2; + + cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001); + cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001); + + w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1); + w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2); + + vec3 cd1 = one; vec3 cd2 = one; 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; + color = min(color, 1.0); +} + + if (interb) + { + color = gc(color1); + mcolor = mcolor1; + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.20/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + vec2 maskcoord = gl_FragCoord.yx * 1.000001; + if (notate) maskcoord = maskcoord.yx; + + float smask = SlotMask(maskcoord, mx); + cmask*= Mask(maskcoord, mx); + + color = pow(color, vec3(mask_gamma/gamma_in)); + color = color*cmask; + color = min(color,1.0); + color = color*smask; + color = pow(color, vec3(gamma_in/mask_gamma)); + + cmask = min(cmask*smask, 1.0); + + 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.70); + color*=bb; + + vec3 Glow = COMPAT_TEXTURE(GlowPass, pos ).rgb; + vec3 Bloom = Glow; + float maxb = COMPAT_TEXTURE(GlowPass, pos ).a; + float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a; + + vec3 Bloom1 = min(Glow*(orig1+color), max(0.5*(colmx + orig1 - color),0.0)); + color = color + bloom*Bloom1; + + color = min(color, mix(one, cmask, mclip)); + if (!interb) color = declip(color, pow(w3,0.6)); + + if (halation > 0.025) { + Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx); + color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; } + + 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; } + + color = min(color, 1.0); + + color = pow(color, vec3(1.0/gamma_out)); + + float corner0 = corner(pos0); + + FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner0); +} diff --git a/crt/shaders/guest/advanced/crt-guest-advanced-ntsc.slang b/crt/shaders/guest/advanced/crt-guest-advanced-ntsc.slang new file mode 100644 index 0000000..d9c8086 --- /dev/null +++ b/crt/shaders/guest/advanced/crt-guest-advanced-ntsc.slang @@ -0,0 +1,904 @@ +#version 450 + +/* + CRT - Guest - Advanced + + Copyright (C) 2018-2021 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. + + 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 +{ + float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, + h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask, + slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float bloom; + float halation; + float scans; + float scansub; + float slotms; + float mclip; + float gamma_c; + float mask_gamma; + float smart_ei; + float ei_limit; + float sth; + float gamma_out; + float overscanY; + float intres; + float prescalex; + float c_shape; + float barspeed; + float barintensity; + float bardir; + float blendMode; + float scangamma; +} global; + + +#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter blendMode "NTSC Blend Mode (Main Mode Control)" 1.0 0.0 2.0 1.0 + +#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01 +#define glow params.glow // Glow Strength + +#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05 +#define bloom global.bloom // bloom effect + +#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025 +#define halation global.halation // halation effect + +#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02 +#define gamma_c global.gamma_c // adjust brightness + +#pragma parameter brightboost " Bright Boost Dark Pixels" 1.25 0.25 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025 +#define brightboost1 params.brightboost1 // adjust brightness + +#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#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 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 40.0 1.0 +#define scanline2 params.scanline2 // scanline param, vertical sharpness + +#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 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 2.5 0.05 +#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" 0.65 0.0 1.0 0.05 +#define scans global.scans // scanline saturation + +// Scanline darken 'edges' effect - need to uncomment it. + +// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005 +// #define scansub global.scansub // scanline substraction + +#pragma parameter spike " Scanline Spike Removal" 0.7 0.0 2.0 0.10 +#define spike params.spike + +#pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05 +#define scangamma global.scangamma + +#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter h_sharp " Horizontal sharpness" 3.70 0.10 15.0 0.10 +#define h_sharp params.h_sharp // pixel sharpness + +#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.20 0.0 1.5 0.10 +#define s_sharp params.s_sharp // substractive sharpness + +#pragma parameter smart_ei " Smart Edges Effect Strength" 0.0 0.0 20.0 0.25 +#define smart_ei global.smart_ei // smart edge handling + +#pragma parameter ei_limit " Smart Edges Effect Strength Limit" 2.0 1.0 12.0 0.1 +#define ei_limit global.ei_limit // smart edge handling + +#pragma parameter sth " Smart Edges Smoothing Threshold" 0.20 0.0 1.0 0.01 +#define sth global.sth // corner size + +#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match + +#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0 +#define TATE params.TATE // Screen orientation + +#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0 +#define IOS params.IOS // Smart Integer Scaling + +#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0 +#define OS params.OS // Do overscan + +#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0 +#define BLOOM params.BLOOM // Bloom overscan percentage + +#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01 +#define csize params.csize // corner size + +#pragma parameter bsize " Border smoothness" 600.0 100.0 700.0 10.0 +#define bsize params.bsize // border smoothness + +#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0 + +#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01 + +#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0 + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01 +#define warpX params.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01 +#define warpY params.warpY // Curvature Y + +#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05 +#define c_shape global.c_shape // curvature shape + +#pragma parameter overscanY " Overscan Y original pixels" 0.0 -50.0 50.0 1.0 +#define overscanY global.overscanY // OverscanY pixels + +#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 +#define prescalex global.prescalex // prescale-x factor + +#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0 +#define shadowMask params.shadowMask // Mask Style + +#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05 +#define maskstr params.maskstr // CGWG Mask Strength + +#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 dark color strength + +#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0 +#define masksize params.masksize // Mask Size + +#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 +#define maskDark params.maskDark // Dark "Phosphor" + +#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05 +#define maskLight params.maskLight // Light "Phosphor" + +#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.025 +#define mask_gamma global.mask_gamma // Mask application gamma + +#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask + +#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 6.0 0.5 +#define slotwidth params.slotwidth // Slot Mask Width + +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.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 mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05 +#define mclip global.mclip // Slot Mask Size + +#pragma parameter gamma_out "Gamma out" 2.0 1.0 5.0 0.05 +#define gamma_out global.gamma_out // output gamma + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define TEX0 vTexCoord + +#define OutputSize global.OutputSize +#define gl_FragCoord (vTexCoord * OutputSize.xy) + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D LinearizePass; +layout(set = 0, binding = 3) uniform sampler2D AvgLumPass; +layout(set = 0, binding = 4) uniform sampler2D GlowPass; +layout(set = 0, binding = 5) uniform sampler2D BloomPass; +layout(set = 0, binding = 6) uniform sampler2D PrePass0; +layout(set = 0, binding = 7) uniform sampler2D NtscPass; + +#define eps 1e-8 + +float st(float x) +{ + return exp2(-10.0*x*x); +} + +float sw0(float x, float color, float scanline) +{ + float tmp = mix(beam_min, beam_max, color); + float ex = x*tmp; + ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4); + return exp2(-scanline*ex); +} + +float sw1(float x, float color, float scanline) +{ + x = mix (x, beam_min*x, max(x-0.4*color,0.0)); + float tmp = mix(1.2*beam_min, beam_max, color); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +float sw2(float x, float color, float scanline) +{ + float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color); + tmp = mix(beam_max, tmp, pow(x, color+0.3)); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +// Shadow mask (1-4 from PD CRT Lottes shader). + +vec3 Mask(vec2 pos, float mx) +{ + pos = floor(pos/masksize); + vec3 mask = vec3(maskDark, maskDark, maskDark); + vec3 one = vec3(1.0); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 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); + } + + // Phosphor. + else if (shadowMask == 0.0) + { + pos.x = fract(pos.x*0.5); + if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } + else { mask.r = mc; mask.g = 1.0; mask.b = mc; } + } + + // Very compressed TV style shadow mask. + else if (shadowMask == 1.0) + { + float line = maskLight; + float odd = 0.0; + + if (fract(pos.x/6.0) < 0.5) + odd = 1.0; + if (fract((pos.y + odd)/2.0) < 0.5) + line = maskDark; + + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + + mask*=line; + } + + // Aperture-grille. + else if (shadowMask == 2.0) + { + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // VGA style shadow mask. + else if (shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Trinitron mask 5 + else if (shadowMask == 5.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) + { mask.r = 1.0; + 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; + } + + // Trinitron mask 6 + else if (shadowMask == 6.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/3.0); + if (pos.x < 0.333) mask.r = 1.0; + else if (pos.x < 0.666) 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; + } + + // BW Trinitron mask 7 + else if (shadowMask == 7.0) + { + float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = vec3(maskTmp); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) mask = vec3(1.0); + } + + // 4k mask + else + { + 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.rg = 1.0.xx; + else if (pos.x < 0.7) mask.gb = 1.0.xx; + else mask.b = 1.0; + } + + return mask; +} + +float SlotMask(vec2 pos, float m) +{ + if (slotmask == 0.0) return 1.0; + else + { + pos = floor(pos/slotms); + float mlen = slotwidth*2.0; + float px = fract(pos.x/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; + + return slot; + } +} + +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape); + return pos*0.5 + 0.5; +} + +vec2 Overscan(vec2 pos, float dx, float dy){ + pos=pos*2.0-1.0; + pos*=vec2(dx,dy); + return pos*0.5+0.5; +} + +float humbar(float pos) +{ + if (global.barintensity == 0.0) return 1.0; else + { + pos = (global.barintensity >= 0.0) ? pos : (1.0-pos); + pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0)); + pos = (global.barintensity < 0.0) ? pos : (1.0-pos); + return (1.0-global.barintensity) + global.barintensity*pos; + } +} + +// Borrowed from cgwg's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002))); + coord = (cdist - min(coord,cdist)); + float dist = sqrt(dot(coord,coord)); + return clamp((cdist.x-dist)*bsize,0.0, 1.0); +} + +vec3 declip(vec3 c, float b) +{ + float m = max(max(c.r,c.g),c.b); + if (m > b) c = c*b/m; + return c; +} + +vec3 gc(vec3 c) +{ + float mc = max(max(c.r,c.g),c.b); + float mg = pow(mc, 1.0/gamma_c); + return c * mg/(mc + eps); +} + +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 SourceSize = global.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0); + + bool nmode1 = (global.blendMode == 1.0); + bool nmode2 = (global.blendMode > 1.5); + + if (nmode2) SourceSize*= vec4(2.0, 1.0, 0.5, 1.0); + + float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a; + + 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.75); + bool notate = (TATE < 0.5); + + float SourceY = mix(SourceSize.y, SourceSize.x, TATE); + float sy = 1.0; + if (global.intres == 0.5) sy = SourceY/224.0; else + if (global.intres == 1.0) sy = SourceY/240.0; else + if (global.intres > 1.25) sy = global.intres; + if (notate) SourceSize*=vec4(1.0, 1.0/sy, 1.0, sy); else SourceSize*=vec4(1.0/sy, 1.0, sy, 1.0); + + // Calculating texel coordinates + + vec2 texcoord = TEX0.xy; + if (IOS > 0.0){ + vec2 ofactor = OutputSize.xy/SourceSize.xy; + vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor); + vec2 diff = ofactor/intfactor; + float scan = mix(diff.y, diff.x, TATE); + texcoord = Overscan(texcoord, scan, scan); + if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE); + } + + float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0; + texcoord = Overscan(texcoord, factor, factor); + + texcoord = Overscan(texcoord, 1.0, (SourceSize.y - overscanY)/SourceSize.y); + + vec2 pos = Warp(texcoord); + vec2 pos0 = Warp(TEX0.xy); + + bool smarte = (smart_ei > 0.0 && notate); // smart edge interpolation on / off + + vec2 coffset = vec2(0.5, 0.5); + + vec2 ps = SourceSize.zw; + vec2 OGL2Pos = pos * SourceSize.xy - coffset; + vec2 fp = fract(OGL2Pos); + + vec2 dx = vec2(ps.x,0.0); + vec2 dy = vec2(0.0, ps.y); + + // Reading the texels + vec2 x2 = 2.0*dx; + vec2 y2 = 2.0*dy; + + vec2 offx = dx; + vec2 off2 = x2; + vec2 offy = dy; + float fpx = fp.x; + if(!notate) + { + offx = dy; + off2 = y2; + offy = dx; + fpx = fp.y; + } + float f = (notate) ? fp.y : fp.x; + + vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps; + + vec2 pC5 = mix(vec2(pos.x, pC4.y), vec2(pC4.x, pos.y), float(!notate)); + + if (interb) pC4.y = pos.y; + + float zero = exp2(-h_sharp); + float sharp1 = s_sharp * zero; + + float fdivider = min(prescalex + 0.325*float(nmode2), 2.0); + + float wl3 = (2.0 + fpx)/fdivider; + float wl2 = (1.0 + fpx)/fdivider; + float wl1 = ( fpx)/fdivider; + float wr1 = (1.0 - fpx)/fdivider; + float wr2 = (2.0 - fpx)/fdivider; + float wr3 = (3.0 - fpx)/fdivider; + + wl3*=wl3; wl3 = exp2(-h_sharp*wl3); + wl2*=wl2; wl2 = exp2(-h_sharp*wl2); + wl1*=wl1; wl1 = exp2(-h_sharp*wl1); + wr1*=wr1; wr1 = exp2(-h_sharp*wr1); + wr2*=wr2; wr2 = exp2(-h_sharp*wr2); + wr3*=wr3; wr3 = exp2(-h_sharp*wr3); + + float fp1 = 1.-fpx; + + float twl3 = max(wl3 - sharp1, 0.0); + float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1)); + float twl1 = max(wl1 - sharp1, 0.0); + float twr1 = max(wr1 - sharp1, 0.0); + float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx)); + float twr3 = max(wr3 - sharp1, 0.0); + + bool sharp = (sharp1 > 0.0); + + float rwl3, rwl2, rwr2; + + float rwl1 = twl1; + float rwr1 = twr1; + vec3 c1, c2; + + if (smarte) + { + rwl3 = wl3; rwl2 = wl2; + rwl1 = wl1; rwr1 = wr1; + rwr2 = wr2; + twl3 = 0.0; twr3 = 0.0; + vec3 t = COMPAT_TEXTURE(AvgLumPass, pC4 - offy).xyz; + vec3 a = COMPAT_TEXTURE(AvgLumPass, pC4 ).xyz; + vec3 b = COMPAT_TEXTURE(AvgLumPass, pC4 + offy).xyz; + vec3 d = COMPAT_TEXTURE(AvgLumPass, pC4 +dy+dy).xyz; + c1 = (h_sharp > 2.6) ? a : min(a,(t + a + b)/3.0); c1 = max(c1 - sth, 0.0); + c2 = (h_sharp > 2.6) ? b : min(b,(a + b + d)/3.0); c2 = max(c2 - sth, 0.0); + } + + vec3 cc, l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, colmin, colmax; + +if (nmode2) +{ + l3 = pow(COMPAT_TEXTURE(NtscPass, pC4 -off2).rgb, gamma_in.xxx); + l2 = pow(COMPAT_TEXTURE(NtscPass, pC4 -offx).rgb, gamma_in.xxx); + l1 = pow(COMPAT_TEXTURE(NtscPass, pC4 ).rgb, gamma_in.xxx); + r1 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx).rgb, gamma_in.xxx); + r2 = pow(COMPAT_TEXTURE(NtscPass, pC4 +off2).rgb, gamma_in.xxx); + r3 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx+off2).rgb, gamma_in.xxx); +} +else +{ + l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb; + l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb; + r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb; + r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb; + cc = pow(COMPAT_TEXTURE(NtscPass, pC5).rgb, gamma_in.xxx); +} + colmin = min(min(l1,r1), min(l2,r2)); + colmax = max(max(l1,r1), max(l2,r2)); + + if (smarte) + { + float pc = min(1.0 + smart_ei*c1.y, ei_limit); + float pl = min(1.0 + smart_ei*max(c1.y,c1.x), ei_limit); + float pr = min(1.0 + smart_ei*max(c1.y,c1.z), ei_limit); + twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc); + twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr); + float wmax = max(twl1, twr1); + float sharp_ei = s_sharp*pow(zero, pc)/wmax; + twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1)); + twl1 = max(twl1/wmax - sharp_ei, 0.0); + twr1 = max(twr1/wmax - sharp_ei, 0.0); + twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx)); + } + color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3); + if (sharp) color1 = clamp(color1, colmin, colmax); + if (nmode1 && !interb) color1 = min(normalize (color1+eps) * length(sqrt(color1 * cc)) ,1.0); + + color1 = pow(color1, vec3(scangamma/gamma_in)); + + float ts = 0.033; + + bool ntscbm = (global.blendMode == 0.0); + +if (ntscbm) +{ + l2 = COMPAT_TEXTURE(PrePass0, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(PrePass0, pC4 ).rgb; + r1 = COMPAT_TEXTURE(PrePass0, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(PrePass0, pC4 +off2).rgb; +} + + float lm2 = max(max(l2.r,l2.g),l2.b); + float lm1 = max(max(l1.r,l1.g),l1.b); + float rm1 = max(max(r1.r,r1.g),r1.b); + float rm2 = max(max(r2.r,r2.g),r2.b); + +if (ntscbm) +{ + lm2 = pow(lm2, gamma_in); + lm1 = pow(lm1, gamma_in); + rm1 = pow(rm1, gamma_in); + rm2 = pow(rm2, gamma_in); +} + + float swl2 = max(twl2, eps) * (lm2+ts); + float swl1 = twl1 * (lm1+ts); + float swr1 = twr1 * (rm1+ts); + float swr2 = max(twr2, eps) * (rm2+ts); + + float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2); + vec3 mcolor1 = vec3(fscolor1); + vec3 scolor1 = vec3(clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0)); + + vec3 scolor2, mcolor2; + + if (!interb) +{ + pC4+=offy; + pC5+=offy; + +if (nmode2) +{ + l3 = pow(COMPAT_TEXTURE(NtscPass, pC4 -off2).rgb, gamma_in.xxx); + l2 = pow(COMPAT_TEXTURE(NtscPass, pC4 -offx).rgb, gamma_in.xxx); + l1 = pow(COMPAT_TEXTURE(NtscPass, pC4 ).rgb, gamma_in.xxx); + r1 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx).rgb, gamma_in.xxx); + r2 = pow(COMPAT_TEXTURE(NtscPass, pC4 +off2).rgb, gamma_in.xxx); + r3 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx+off2).rgb, gamma_in.xxx); +} +else +{ + l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb; + l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb; + r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb; + r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb; + cc = pow(COMPAT_TEXTURE(NtscPass, pC5).rgb, gamma_in.xxx); +} + + colmin = min(min(l1,r1), min(l2,r2)); + colmax = max(max(l1,r1), max(l2,r2)); + + if (smarte) + { + float pc = min(1.0 + smart_ei*c2.y, ei_limit); + float pl = min(1.0 + smart_ei*max(c2.y,c2.x), ei_limit); + float pr = min(1.0 + smart_ei*max(c2.y,c2.z), ei_limit); + twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc); + twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr); + float wmax = max(twl1, twr1); + float sharp_ei = s_sharp*pow(zero, pc)/wmax; + twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1)); + twl1 = max(twl1/wmax - sharp_ei, 0.0); + twr1 = max(twr1/wmax - sharp_ei, 0.0); + twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx)); + } + color2 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3); + if (sharp) color2 = clamp(color2, colmin, colmax); + if (nmode1 && !interb) color2 = min(normalize (color2+eps) * length(sqrt(color2 * cc)) ,1.0); + + color2 = pow(color2, vec3(scangamma/gamma_in)); + +if (ntscbm) +{ + l2 = COMPAT_TEXTURE(PrePass0, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(PrePass0, pC4 ).rgb; + r1 = COMPAT_TEXTURE(PrePass0, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(PrePass0, pC4 +off2).rgb; +} + + lm2 = max(max(l2.r,l2.g),l2.b); + lm1 = max(max(l1.r,l1.g),l1.b); + rm1 = max(max(r1.r,r1.g),r1.b); + rm2 = max(max(r2.r,r2.g),r2.b); + +if (ntscbm) +{ + lm2 = pow(lm2, gamma_in); + lm1 = pow(lm1, gamma_in); + rm1 = pow(rm1, gamma_in); + rm2 = pow(rm2, gamma_in); +} + + swl2 = max(twl2, 0.0) * (lm2+ts); + swl1 = twl1 * (lm1+ts); + swr1 = twr1 * (rm1+ts); + swr2 = max(twr2, 0.0) * (rm2+ts); + + float fscolor2 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2); + mcolor2 = vec3(fscolor2); + scolor2 = vec3(clamp(mix(max(max(color2.r,color2.g),color2.b), fscolor2, spike), 0.0, 1.0)); +} + + vec3 ctmp; vec3 mcolor; float w3; vec3 color; + vec3 one = vec3(1.0); + +if (!interb) +{ + // calculating scanlines + + float shape1 = mix(scanline1, scanline2, f); + float shape2 = mix(scanline1, scanline2, 1.0-f); + + float wt1 = st(f); + float wt2 = st(1.0-f); + + vec3 color00 = color1*wt1 + color2*wt2; + vec3 scolor0 = scolor1*wt1 + scolor2*wt2; + mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2); + + ctmp = color00/(wt1+wt2); + vec3 sctmp = scolor0/(wt1+wt2); + mcolor = clamp(mix(ctmp, mcolor, 1.5), 0.0, 1.0); + + float wf1, wf2; + + vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b); + vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b); + + float f1 = f; + float f2 = 1.0-f; + + if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else + if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else + { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);} + + if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; } + + // Scanline darken 'edges' effect - need to uncomment it. + + // float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1); + // float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2); + + // Scanline saturation application + + vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2); + w3 = wf1+wf2; + + cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001); + cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001); + + w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1); + w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2); + + vec3 cd1 = one; vec3 cd2 = one; 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; + + color = min(color, 1.0); +} + + if (interb) + { + color = gc(color1); + mcolor = clamp(mix(color1, mcolor1, 1.25), 0.0, 1.0); + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.20/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + vec2 maskcoord = gl_FragCoord.yx * 1.000001; + if (notate) maskcoord = maskcoord.yx; + + float smask = SlotMask(maskcoord, mx); + cmask*= Mask(maskcoord, mx); + + color = pow(color, vec3(mask_gamma/gamma_in)); + color = color*cmask; + color = min(color,1.0); + color = color*smask; + color = pow(color, vec3(gamma_in/mask_gamma)); + + cmask = min(cmask*smask, 1.0); + + 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.70); + color*=bb; + + vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb; + vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos).rgb; + float maxb = COMPAT_TEXTURE(BloomPass, pos).a; + float vig = COMPAT_TEXTURE(PrePass0, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a; + + vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0)); + color = color + bloom*Bloom1; + + color = min(color, mix(one, cmask, mclip)); + if (!interb) color = declip(color, pow(w3,0.60)); + + if (halation > 0.025) { + Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx); + color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; } + + color = pow(color, vec3(gamma_in/scangamma)); + + 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; } + + color = min(color, 1.0); + + color = pow(color, vec3(1.0/gamma_out)); + + FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner(pos0)); +} diff --git a/crt/shaders/guest/advanced/crt-guest-advanced.slang b/crt/shaders/guest/advanced/crt-guest-advanced.slang new file mode 100644 index 0000000..ed08394 --- /dev/null +++ b/crt/shaders/guest/advanced/crt-guest-advanced.slang @@ -0,0 +1,822 @@ +#version 450 + +/* + CRT - Guest - Advanced + + Copyright (C) 2018-2021 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. + + 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 +{ + float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, + h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask, + slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float bloom; + float halation; + float scans; + float scansub; + float slotms; + float mclip; + float gamma_c; + float mask_gamma; + float smart_ei; + float ei_limit; + float sth; + float gamma_out; + float overscanY; + float intres; + float prescalex; + float c_shape; + float barspeed; + float barintensity; + float bardir; +} global; + + +#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 +#define glow params.glow // Glow Strength + +#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05 +#define bloom global.bloom // bloom effect + +#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025 +#define halation global.halation // halation effect + +#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02 +#define gamma_c global.gamma_c // adjust brightness + +#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025 +#define brightboost1 params.brightboost1 // adjust brightness + +#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#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 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 40.0 1.0 +#define scanline2 params.scanline2 // scanline param, vertical sharpness + +#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 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 2.5 0.05 +#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" 0.60 0.0 1.0 0.05 +#define scans global.scans // scanline saturation + +// Scanline darken 'edges' effect - need to uncomment it. + +// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005 +// #define scansub global.scansub // scanline substraction + +#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10 +#define spike params.spike + +#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.10 +#define h_sharp params.h_sharp // pixel sharpness + +#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10 +#define s_sharp params.s_sharp // substractive sharpness + +#pragma parameter smart_ei " Smart Edges Effect Strength" 0.0 0.0 20.0 0.25 +#define smart_ei global.smart_ei // smart edge handling + +#pragma parameter ei_limit " Smart Edges Effect Strength Limit" 2.0 1.0 12.0 0.1 +#define ei_limit global.ei_limit // smart edge handling + +#pragma parameter sth " Smart Edges Smoothing Threshold" 0.20 0.0 1.0 0.01 +#define sth global.sth // corner size + +#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match + +#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0 +#define TATE params.TATE // Screen orientation + +#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0 +#define IOS params.IOS // Smart Integer Scaling + +#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0 +#define OS params.OS // Do overscan + +#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0 +#define BLOOM params.BLOOM // Bloom overscan percentage + +#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01 +#define csize params.csize // corner size + +#pragma parameter bsize " Border smoothness" 600.0 100.0 700.0 10.0 +#define bsize params.bsize // border smoothness + +#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0 + +#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01 + +#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0 + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01 +#define warpX params.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01 +#define warpY params.warpY // Curvature Y + +#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05 +#define c_shape global.c_shape // curvature shape + +#pragma parameter overscanY " Overscan Y original pixels" 0.0 -50.0 50.0 1.0 +#define overscanY global.overscanY // OverscanY pixels + +#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 +#define prescalex global.prescalex // prescale-x factor + +#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0 +#define shadowMask params.shadowMask // Mask Style + +#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05 +#define maskstr params.maskstr // CGWG Mask Strength + +#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 dark color strength + +#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0 +#define masksize params.masksize // Mask Size + +#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 +#define maskDark params.maskDark // Dark "Phosphor" + +#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05 +#define maskLight params.maskLight // Light "Phosphor" + +#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05 +#define mask_gamma global.mask_gamma // Mask application gamma + +#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask + +#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 6.0 0.5 +#define slotwidth params.slotwidth // Slot Mask Width + +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.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 mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05 +#define mclip global.mclip // Slot Mask Size + +#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05 +#define gamma_out global.gamma_out // output gamma + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define TEX0 vTexCoord + +#define OutputSize global.OutputSize +#define gl_FragCoord (vTexCoord * OutputSize.xy) + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D LinearizePass; +layout(set = 0, binding = 3) uniform sampler2D AvgLumPass; +layout(set = 0, binding = 4) uniform sampler2D GlowPass; +layout(set = 0, binding = 5) uniform sampler2D BloomPass; +layout(set = 0, binding = 6) uniform sampler2D PrePass; + +#define eps 1e-10 + +float st(float x) +{ + return exp2(-10.0*x*x); +} + +float sw0(float x, float color, float scanline) +{ + float tmp = mix(beam_min, beam_max, color); + float ex = x*tmp; + ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4); + return exp2(-scanline*ex); +} + +float sw1(float x, float color, float scanline) +{ + x = mix (x, beam_min*x, max(x-0.4*color,0.0)); + float tmp = mix(1.2*beam_min, beam_max, color); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +float sw2(float x, float color, float scanline) +{ + float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color); + tmp = mix(beam_max, tmp, pow(x, color+0.3)); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +// Shadow mask (1-4 from PD CRT Lottes shader). + +vec3 Mask(vec2 pos, float mx) +{ + pos = floor(pos/masksize); + vec3 mask = vec3(maskDark, maskDark, maskDark); + vec3 one = vec3(1.0); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 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); + } + + // Phosphor. + else if (shadowMask == 0.0) + { + pos.x = fract(pos.x*0.5); + if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } + else { mask.r = mc; mask.g = 1.0; mask.b = mc; } + } + + // Very compressed TV style shadow mask. + else if (shadowMask == 1.0) + { + float line = maskLight; + float odd = 0.0; + + if (fract(pos.x/6.0) < 0.5) + odd = 1.0; + if (fract((pos.y + odd)/2.0) < 0.5) + line = maskDark; + + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + + mask*=line; + } + + // Aperture-grille. + else if (shadowMask == 2.0) + { + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // VGA style shadow mask. + else if (shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Trinitron mask 5 + else if (shadowMask == 5.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) + { mask.r = 1.0; + 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; + } + + // Trinitron mask 6 + else if (shadowMask == 6.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/3.0); + if (pos.x < 0.333) mask.r = 1.0; + else if (pos.x < 0.666) 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; + } + + // BW Trinitron mask 7 + else if (shadowMask == 7.0) + { + float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = vec3(maskTmp); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) mask = vec3(1.0); + } + + // 4k mask + else + { + 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.rg = 1.0.xx; + else if (pos.x < 0.7) mask.gb = 1.0.xx; + else mask.b = 1.0; + } + + return mask; +} + +float SlotMask(vec2 pos, float m) +{ + if ((slotmask + slotmask1) == 0.0) return 1.0; + else + { + pos = floor(pos/slotms); + float mlen = slotwidth*2.0; + float px = fract(pos.x/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; + + return slot; + } +} + +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape); + return pos*0.5 + 0.5; +} + +vec2 Overscan(vec2 pos, float dx, float dy){ + pos=pos*2.0-1.0; + pos*=vec2(dx,dy); + return pos*0.5+0.5; +} + +float humbar(float pos) +{ + if (global.barintensity == 0.0) return 1.0; else + { + pos = (global.barintensity >= 0.0) ? pos : (1.0-pos); + pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0)); + pos = (global.barintensity < 0.0) ? pos : (1.0-pos); + return (1.0-global.barintensity) + global.barintensity*pos; + } +} + +// Borrowed from cgwg's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002))); + coord = (cdist - min(coord,cdist)); + float dist = sqrt(dot(coord,coord)); + return clamp((cdist.x-dist)*bsize,0.0, 1.0); +} + +vec3 declip(vec3 c, float b) +{ + float m = max(max(c.r,c.g),c.b); + if (m > b) c = c*b/m; + return c; +} + +vec3 gc(vec3 c) +{ + float mc = max(max(c.r,c.g),c.b); + float mg = pow(mc, 1.0/gamma_c); + return c * mg/(mc + eps); +} + +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 SourceSize = global.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0); + + float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a; + + 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.75); + bool notate = (TATE < 0.5); + + float SourceY = mix(SourceSize.y, SourceSize.x, TATE); + float sy = 1.0; + if (global.intres == 0.5) sy = SourceY/224.0; else + if (global.intres == 1.0) sy = SourceY/240.0; else + if (global.intres > 1.25) sy = global.intres; + if (notate) SourceSize*=vec4(1.0, 1.0/sy, 1.0, sy); else SourceSize*=vec4(1.0/sy, 1.0, sy, 1.0); + + // Calculating texel coordinates + + vec2 texcoord = TEX0.xy; + if (IOS > 0.0){ + vec2 ofactor = OutputSize.xy/SourceSize.xy; + vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor); + vec2 diff = ofactor/intfactor; + float scan = mix(diff.y, diff.x, TATE); + texcoord = Overscan(texcoord, scan, scan); + if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE); + } + + float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0; + texcoord = Overscan(texcoord, factor, factor); + + texcoord = Overscan(texcoord, 1.0, (SourceSize.y - overscanY)/SourceSize.y); + + vec2 pos = Warp(texcoord); + vec2 pos0 = Warp(TEX0.xy); + + bool smarte = (smart_ei > 0.0 && notate); // smart edge interpolation on / off + + vec2 coffset = vec2(0.5, 0.5); + + vec2 ps = SourceSize.zw; + vec2 OGL2Pos = pos * SourceSize.xy - coffset; + vec2 fp = fract(OGL2Pos); + + vec2 dx = vec2(ps.x,0.0); + vec2 dy = vec2(0.0, ps.y); + + // Reading the texels + vec2 x2 = 2.0*dx; + vec2 y2 = 2.0*dy; + + vec2 offx = dx; + vec2 off2 = x2; + vec2 offy = dy; + float fpx = fp.x; + if(!notate) + { + offx = dy; + off2 = y2; + offy = dx; + fpx = fp.y; + } + float f = (notate) ? fp.y : fp.x; + + vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps; + + if (interb) pC4.y = pos.y; + + float zero = exp2(-h_sharp); + float sharp1 = s_sharp * zero; + + float fdivider = min(prescalex, 2.0); + + float wl3 = (2.0 + fpx)/fdivider; + float wl2 = (1.0 + fpx)/fdivider; + float wl1 = ( fpx)/fdivider; + float wr1 = (1.0 - fpx)/fdivider; + float wr2 = (2.0 - fpx)/fdivider; + float wr3 = (3.0 - fpx)/fdivider; + + wl3*=wl3; wl3 = exp2(-h_sharp*wl3); + wl2*=wl2; wl2 = exp2(-h_sharp*wl2); + wl1*=wl1; wl1 = exp2(-h_sharp*wl1); + wr1*=wr1; wr1 = exp2(-h_sharp*wr1); + wr2*=wr2; wr2 = exp2(-h_sharp*wr2); + wr3*=wr3; wr3 = exp2(-h_sharp*wr3); + + float fp1 = 1.-fpx; + + float twl3 = max(wl3 - sharp1, 0.0); + float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1)); float scl2 = max(twl2, 0.0); + float twl1 = max(wl1 - sharp1, 0.0); + float twr1 = max(wr1 - sharp1, 0.0); + float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx)); float scr2 = max(twr2, 0.0); + float twr3 = max(wr3 - sharp1, 0.0); + + bool sharp = (sharp1 > 0.0); + + float rwl3, rwl2, rwr2; + + float rwl1 = twl1; + float rwr1 = twr1; + vec3 c1, c2; + + if (smarte) + { + rwl3 = wl3; rwl2 = wl2; + rwl1 = wl1; rwr1 = wr1; + rwr2 = wr2; + twl3 = 0.0; twr3 = 0.0; + vec3 t = COMPAT_TEXTURE(AvgLumPass, pC4 - offy).xyz; + vec3 a = COMPAT_TEXTURE(AvgLumPass, pC4 ).xyz; + vec3 b = COMPAT_TEXTURE(AvgLumPass, pC4 + offy).xyz; + vec3 d = COMPAT_TEXTURE(AvgLumPass, pC4 +dy+dy).xyz; + c1 = (h_sharp > 2.6) ? a : min(a,(t + a + b)/3.0); c1 = max(c1 - sth, 0.0); + c2 = (h_sharp > 2.6) ? b : min(b,(a + b + d)/3.0); c2 = max(c2 - sth, 0.0); + } + + vec3 l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, colmin, colmax; + + l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb; + l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb; + r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb; + r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb; + + colmin = min(min(l1,r1), min(l2,r2)); + colmax = max(max(l1,r1), max(l2,r2)); + + if (smarte) + { + float pc = min(1.0 + smart_ei*c1.y, ei_limit); + float pl = min(1.0 + smart_ei*max(c1.y,c1.x), ei_limit); + float pr = min(1.0 + smart_ei*max(c1.y,c1.z), ei_limit); + twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc); + twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr); + float wmax = max(twl1, twr1); + float sharp_ei = s_sharp*pow(zero, pc)/wmax; + twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1)); + twl1 = max(twl1/wmax - sharp_ei, 0.0); + twr1 = max(twr1/wmax - sharp_ei, 0.0); + twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx)); + } + color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3); + + if (sharp) color1 = clamp(color1, colmin, colmax); + float ts = 0.033; + + float lm2 = max(max(l2.r,l2.g),l2.b); + float lm1 = max(max(l1.r,l1.g),l1.b); + float rm1 = max(max(r1.r,r1.g),r1.b); + float rm2 = max(max(r2.r,r2.g),r2.b); + + float swl2 = max(twl2, 0.0) * (lm2+ts); + float swl1 = twl1 * (lm1+ts); + float swr1 = twr1 * (rm1+ts); + float swr2 = max(twr2, 0.0) * (rm2+ts); + + float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2); + vec3 mcolor1 = vec3(fscolor1); + vec3 scolor1 = vec3(clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0)); + + vec3 scolor2, mcolor2; + + if (!interb) +{ + pC4+=offy; + + l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb; + l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb; + r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb; + r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb; + + colmin = min(min(l1,r1), min(l2,r2)); + colmax = max(max(l1,r1), max(l2,r2)); + + if (smarte) + { + float pc = min(1.0 + smart_ei*c2.y, ei_limit); + float pl = min(1.0 + smart_ei*max(c2.y,c2.x), ei_limit); + float pr = min(1.0 + smart_ei*max(c2.y,c2.z), ei_limit); + twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc); + twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr); + float wmax = max(twl1, twr1); + float sharp_ei = s_sharp*pow(zero, pc)/wmax; + twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1)); + twl1 = max(twl1/wmax - sharp_ei, 0.0); + twr1 = max(twr1/wmax - sharp_ei, 0.0); + twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx)); + } + color2 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3); + + if (sharp) color2 = clamp(color2, colmin, colmax); + + lm2 = max(max(l2.r,l2.g),l2.b); + lm1 = max(max(l1.r,l1.g),l1.b); + rm1 = max(max(r1.r,r1.g),r1.b); + rm2 = max(max(r2.r,r2.g),r2.b); + + swl2 = max(twl2, 0.0) * (lm2+ts); + swl1 = twl1 * (lm1+ts); + swr1 = twr1 * (rm1+ts); + swr2 = max(twr2, 0.0) * (rm2+ts); + + float fscolor2 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2); + mcolor2 = vec3(fscolor2); + scolor2 = vec3(clamp(mix(max(max(color2.r,color2.g),color2.b), fscolor2, spike), 0.0, 1.0)); +} + + vec3 ctmp; vec3 mcolor; float w3; vec3 color; + vec3 one = vec3(1.0); + +if (!interb) +{ + // calculating scanlines + + float shape1 = mix(scanline1, scanline2, f); + float shape2 = mix(scanline1, scanline2, 1.0-f); + + float wt1 = st(f); + float wt2 = st(1.0-f); + + vec3 color00 = color1*wt1 + color2*wt2; + vec3 scolor0 = scolor1*wt1 + scolor2*wt2; + mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2); + + ctmp = color00/(wt1+wt2); + vec3 sctmp = scolor0/(wt1+wt2); + mcolor = clamp(mix(ctmp, mcolor, 1.25), 0.0, 1.0); + + float wf1, wf2; + + vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b); + vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b); + + float f1 = f; + float f2 = 1.0-f; + + if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else + if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else + { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);} + + if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; } + + // Scanline darken 'edges' effect - need to uncomment it. + + // float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1); + // float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2); + + // Scanline saturation application + + vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2); + w3 = wf1+wf2; + + cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001); + cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001); + + w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1); + w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2); + + vec3 cd1 = one; vec3 cd2 = one; 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; + + color = min(color, 1.0); +} + + if (interb) + { + color = gc(color1); + mcolor = clamp(mix(color1, mcolor1, 1.25), 0.0, 1.0); + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.20/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + vec2 maskcoord = gl_FragCoord.yx * 1.000001; + if (notate) maskcoord = maskcoord.yx; + + float smask = SlotMask(maskcoord, mx); + cmask*= Mask(maskcoord, mx); + + color = pow(color, vec3(mask_gamma/gamma_in)); + color = color*cmask; + color = min(color,1.0); + color = color*smask; + color = pow(color, vec3(gamma_in/mask_gamma)); + + cmask = min(cmask*smask, 1.0); + + 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.70); + color*=bb; + + vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb; + vec3 Bloom = COMPAT_TEXTURE(BloomPass, 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; + + vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0)); + color = color + bloom*Bloom1; + + color = min(color, mix(one, cmask, mclip)); + if (!interb) color = declip(color, pow(w3,0.60)); + + if (halation > 0.025) { + Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx); + color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; } + + 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; } + + color = min(color, 1.0); + + color = pow(color, vec3(1.0/gamma_out)); + + FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner(pos0)); +} diff --git a/crt/shaders/guest/advanced/custom-fast-sharpen.slang b/crt/shaders/guest/advanced/custom-fast-sharpen.slang new file mode 100644 index 0000000..0fa6dbe --- /dev/null +++ b/crt/shaders/guest/advanced/custom-fast-sharpen.slang @@ -0,0 +1,85 @@ +#version 450 + +/* + Fast Sharpen Shader (Custom) + + Copyright (C) 2005 - 2019 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 SHARPEN, CONTR, DETAILS; +} params; + +#pragma parameter SHARPEN "Sharpen strength" 0.00 0.0 4.00 0.10 +#pragma parameter CONTR "Ammount of sharpening" 0.05 0.0 0.25 0.01 +#pragma parameter DETAILS "Details sharpened " 1.00 0.0 1.00 0.05 + +#define SHARPEN params.SHARPEN +#define CONTR params.CONTR +#define DETAILS params.DETAILS + +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; + + +void main() +{ + vec2 g01 = vec2(-1.0, 0.0)*params.SourceSize.zw; + vec2 g21 = vec2( 1.0, 0.0)*params.SourceSize.zw; + + vec3 c01 = texture(Source, vTexCoord + g01).rgb; + vec3 c21 = texture(Source, vTexCoord + g21).rgb; + vec3 c11 = texture(Source, vTexCoord ).rgb; + + vec3 b11 = 0.5*(c01+c21); + + float contrast = max(max(c11.r,c11.g),c11.b); + contrast = mix(2.0*CONTR, CONTR, contrast); + + vec3 mn1 = min(c01,c21); mn1 = min(mn1,c11*(1.0-contrast)); + vec3 mx1 = max(c01,c21); mx1 = max(mx1,c11*(1.0+contrast)); + + vec3 dif = pow(mx1-mn1+0.0001, vec3(0.75,0.75,0.75)); + vec3 sharpen = mix(vec3(SHARPEN*DETAILS), vec3(SHARPEN), dif); + + c11 = clamp(mix(c11,b11,-sharpen), mn1,mx1); + + FragColor = vec4(c11,1.0); +} diff --git a/crt/shaders/guest/advanced/deconvergence.slang b/crt/shaders/guest/advanced/deconvergence.slang new file mode 100644 index 0000000..2ce761f --- /dev/null +++ b/crt/shaders/guest/advanced/deconvergence.slang @@ -0,0 +1,198 @@ +#version 450 + +/* + CRT - Guest - Advanced - Deconvergence pass + noise + + Copyright (C) 2021 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 OutputSize; + uint FrameCount; + float deconr; + float TATE; + float decons; + float addnoised; + float noiseresd; + float shadowMask; + float masksize; + float deconrr; + float deconrg; + float deconrb; + float deconrry; + float deconrgy; + float deconrby; + float deconsmooth; + float dctypex; + float dctypey; +} params; + +#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0 +#define TATE params.TATE // Screen orientation + +#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05 + +#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05 + +#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter decons " Deconvergence Strength (and Type)" 0.5 -4.0 4.0 0.10 +#define decons params.decons // Horizontal deconvergence colors strength + +#pragma parameter deconsmooth " Deconvergence Smoothing" 0.0 0.0 1.0 0.10 + +#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02 +#define addnoised params.addnoised // add noise + +#pragma parameter noiseresd " Noise Resolution" 2.0 0.0 10.0 1.0 +#define noiseresd params.noiseresd // add noise + + +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) + + +// noise function: +// Dedicated to the public domain. +// If you want a real license, you may consider this MIT/BSD/CC0/WTFPL-licensed (take your pick). +// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz + +vec3 noise(vec3 v){ + if (addnoised < 0.0) v.z = -addnoised; else v.z = v.z/6000.0; + // ensure reasonable range + v = fract(v) + fract(v*1e4) + fract(v*1e-4); + // seed + v += vec3(0.12345, 0.6789, 0.314159); + // more iterations => more random + v = fract(v*dot(v, v)*123.456); + v = fract(v*dot(v, v)*123.456); + v = fract(v*dot(v, v)*123.456); + return v; +} + +void main() +{ + + vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb; + vec3 result = color; + + if ((abs(params.deconrr) + abs(params.deconrg) + abs(params.deconrb) + abs(params.deconrry) + abs(params.deconrgy) + abs(params.deconrby)) > 0.20) + { + float step = 1.0; + float dstep = step; + step*= (TATE < 0.5) ? (params.OutputSize.z) : (params.OutputSize.w); + float stepy = (TATE < 0.5) ? (params.OutputSize.w) : (params.OutputSize.z); + float stepx = (TATE < 0.5) ? (params.OutputSize.z) : (params.OutputSize.w); + + vec2 sx = mix(vec2(stepx, 0.0), vec2(0.0, stepx), TATE); + + float ds = decons; + + vec2 dx = (TATE < 0.5) ? vec2(step, 0.0) : vec2(0.0, step); + vec2 dy = (TATE > 0.5) ? vec2(stepy, 0.0) : vec2(0.0, stepy); + + float posx = 2.0*vTexCoord.x - 1.0; + float posy = 2.0*vTexCoord.y - 1.0; + + if (params.dctypex > 0.025) + { + posx = sign(posx)*pow(abs(posx), 1.05-params.dctypex); + dx = posx * dx; + } + + if (params.dctypey > 0.025) + { + + posy = sign(posy)*pow(abs(posy), 1.05-params.dctypey); + dy = posy * dy; + } + + if (params.dctypex > 0.025 || params.dctypey > 0.025) ds *= sqrt(posx*posx*sign(params.dctypex) + posy*posy*sign(params.dctypey)); + + vec2 rc = params.deconrr * dx + params.deconrry*dy; + vec2 gc = params.deconrg * dx + params.deconrgy*dy; + vec2 bc = params.deconrb * dx + params.deconrby*dy; + + dx = (dx+dy) * params.deconsmooth; + + float r1 = COMPAT_TEXTURE(Source, vTexCoord + rc ).r; + float g1 = COMPAT_TEXTURE(Source, vTexCoord + gc ).g; + float b1 = COMPAT_TEXTURE(Source, vTexCoord + bc ).b; + + float r2 = COMPAT_TEXTURE(Source, vTexCoord + rc -dx).r; + float g2 = COMPAT_TEXTURE(Source, vTexCoord + gc -dx).g; + float b2 = COMPAT_TEXTURE(Source, vTexCoord + bc -dx).b; + + float r3 = COMPAT_TEXTURE(Source, vTexCoord + rc +dx).r; + float g3 = COMPAT_TEXTURE(Source, vTexCoord + gc +dx).g; + float b3 = COMPAT_TEXTURE(Source, vTexCoord + bc +dx).b; + + vec3 result1 = vec3(r1,g1,b1); + vec3 result2 = vec3(r2,g2,b2); + vec3 result3 = vec3(r3,g3,b3); + result = (result1+result2+result3)/3.0; + + vec3 dcolor = max(max(COMPAT_TEXTURE(Source, vTexCoord + sx).rgb, COMPAT_TEXTURE(Source, vTexCoord - sx).rgb), color); + + float mc = max(max(dcolor.r, dcolor.g), dcolor.b); + if (decons < 0.0) mc = 0.9; + + result = clamp(mix(color, sqrt(mix(result*result, color*result, sqrt(mc))), abs(ds)), min(result,color), max(result, color)); + } + + float rc = 0.6*sqrt(max(max(result.r, result.g), result.b))+0.4; + + if (abs(addnoised) > 0.01) result = mix(result, noise(vec3(floor(params.OutputSize.xy * vTexCoord / noiseresd), float(params.FrameCount))), 0.25*abs(addnoised) * rc); + + float corner = COMPAT_TEXTURE(Source, vTexCoord).a; + + FragColor = vec4(result*corner, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/gaussian_horizontal.slang b/crt/shaders/guest/advanced/gaussian_horizontal.slang new file mode 100644 index 0000000..c0be5a9 --- /dev/null +++ b/crt/shaders/guest/advanced/gaussian_horizontal.slang @@ -0,0 +1,99 @@ +#version 450 + +/* + Gaussian blur - horizontal 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 LinearizePassSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEH; + float SIGMA_H; +} params; + +#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; +} 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); +} + +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; + 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/fast/smoothing - kopija.slang b/crt/shaders/guest/advanced/gaussian_vertical.slang similarity index 56% rename from crt/shaders/guest/fast/smoothing - kopija.slang rename to crt/shaders/guest/advanced/gaussian_vertical.slang index 6222be8..29da738 100644 --- a/crt/shaders/guest/fast/smoothing - kopija.slang +++ b/crt/shaders/guest/advanced/gaussian_vertical.slang @@ -1,9 +1,9 @@ #version 450 /* - Smart Smoothing Difference Shader + Gaussian blur - vertical pass, dynamic range, resizable - Copyright (C) 2019 guest(r) - guest.r@gmail.com + 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 @@ -19,9 +19,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#pragma name SmoothPass +*/ layout(push_constant) uniform Push { @@ -29,13 +27,16 @@ layout(push_constant) uniform Push vec4 OriginalSize; vec4 OutputSize; uint FrameCount; - float STH; + float SIZEV; + float SIGMA_V; } params; -#pragma parameter STH "Smart Smoothing Threshold" 0.7 0.4 1.2 0.05 -#define STH params.STH -#define SourceSize params.SourceSize -#define COMPAT_TEXTURE(c,d) texture(c,d) + +#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 { @@ -58,27 +59,40 @@ layout(location = 0) in vec2 vTexCoord; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D Source; -float df (vec3 A, vec3 B) +#define COMPAT_TEXTURE(c,d) texture(c,d) + +float invsqrsigma = 1.0/(2.0*SIGMA_V*SIGMA_V); + +float gaussian(float x) { - float diff = length(A-B); - float luma = clamp(length(0.5*min(A,B) + 0.25*(A+B) + 1e-8), 0.0001, 1.0); - float diff1 = diff/luma; - return 1.0 - clamp(7.0*(max(1.5*diff,diff1)-STH), 0.0, 1.0); + return exp(-x*x*invsqrsigma); } void main() { - vec2 dx = vec2(SourceSize.z, 0.0); - vec2 dy = vec2(0.0, SourceSize.w); + 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); - vec3 l1 = COMPAT_TEXTURE(Source, vTexCoord.xy -dx).xyz; - vec3 ct = COMPAT_TEXTURE(Source, vTexCoord.xy ).xyz; - vec3 r1 = COMPAT_TEXTURE(Source, vTexCoord.xy +dx).xyz; + 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; - float dl = df(ct, l1); - float dr = df(ct, r1); - - float resx = dl; float resy = dr; - - FragColor = vec4(resx,resy,1.0,1.0); + FragColor = vec4(color, 1.0); } \ No newline at end of file diff --git a/crt/shaders/guest/advanced/linearize-hires.slang b/crt/shaders/guest/advanced/linearize-hires.slang new file mode 100644 index 0000000..cbacce9 --- /dev/null +++ b/crt/shaders/guest/advanced/linearize-hires.slang @@ -0,0 +1,172 @@ +#version 450 + +/* + Interlacing + + 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 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float GAMMA_INPUT; + float inter; + float interm; + float iscan; + float intres; + float iscans; + float downsample_levelx; + float downsample_levely; + float prescalex; +} params; + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + vec4 SourceSize; + mat4 MVP; +} global; + + +#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05 +#define GAMMA_INPUT params.GAMMA_INPUT + +#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0 + +#pragma parameter inter " Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0 +#define inter params.inter // interlace resolution + +#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 +#define iscan params.iscan // interlacing effect scanlining + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match +#define intres params.intres // interlace resolution + +#pragma parameter downsample_levelx " Downsampling-X (High-res content, pre-scalers)" 0.0 0.0 3.0 0.05 +#define downsample_levelx params.downsample_levelx // downsample level + +#pragma parameter downsample_levely " Downsampling-Y (High-res content, pre-scalers)" 0.0 0.0 3.0 0.05 +#define downsample_levely params.downsample_levely // downsample level + +#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05 +#define iscans params.iscans // interlace saturation + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D PrePass; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + + +vec3 fetch_pixel(vec2 coord) +{ + vec2 dx = vec2(global.SourceSize.z, 0.0) * downsample_levelx; + vec2 dy = vec2(0.0, global.SourceSize.w) * downsample_levely; + vec2 d1 = dx + dy; + vec2 d2 = dx - dy; + + float sum = 15.0; + vec3 result = 3.0*COMPAT_TEXTURE(PrePass, coord ).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dy).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dy).rgb + + COMPAT_TEXTURE(PrePass, coord + d1).rgb + + COMPAT_TEXTURE(PrePass, coord - d1).rgb + + COMPAT_TEXTURE(PrePass, coord + d2).rgb + + COMPAT_TEXTURE(PrePass, coord - d2).rgb; + + return result/sum; +} + + +void main() +{ + vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb; + vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, params.OriginalSize.w)).rgb; + + if ((downsample_levelx + downsample_levely) > 0.025) + { + c1 = fetch_pixel(vTexCoord); + c2 = fetch_pixel(vTexCoord + vec2(0.0, params.OriginalSize.w)); + } + + vec3 c = c1; + + float intera = 1.0; + float gamma_in = clamp(GAMMA_INPUT, 1.0, 5.0); + + float m1 = max(max(c1.r,c1.g),c1.b); + float m2 = max(max(c2.r,c2.g),c2.b); + vec3 df = abs(c1-c2); + + float d = max(max(df.r,df.g),df.b); + if (interm == 2.0) d = mix(0.1*d,10.0*d, step(m1/(m2+0.0001),m2/(m1+0.0001))); + + float r = m1; + + float yres_div = 1.0; if (intres > 1.25) yres_div = intres; + + if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5) + { + intera = 0.5; + float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0); + float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0); + float ii = abs(line_no-frame_no); + + if (interm < 3.5) + { + c2 = plant(mix(c2, c2*c2, iscans), max(max(c2.r,c2.g),c2.b)); + r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0); + 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); + intera = 0.0; + } + if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); + 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));} + } + c = pow(c, vec3(gamma_in)); + + if (vTexCoord.x > 0.5) gamma_in = intera; else gamma_in = 1.0/gamma_in; + + FragColor = vec4(c, gamma_in); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/linearize-ntsc.slang b/crt/shaders/guest/advanced/linearize-ntsc.slang new file mode 100644 index 0000000..1466472 --- /dev/null +++ b/crt/shaders/guest/advanced/linearize-ntsc.slang @@ -0,0 +1,176 @@ +#version 450 + +/* + Interlacing + + 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 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float GAMMA_INPUT; + float inter; + float interm; + float iscan; + float intres; + float iscans; + float downsample_levelx; + float downsample_levely; + float prescalex; +} params; + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + vec4 SourceSize; + mat4 MVP; +} global; + + +#pragma parameter GAMMA_INPUT "Gamma Input" 2.0 1.0 5.0 0.05 +#define GAMMA_INPUT params.GAMMA_INPUT + +#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0 + +#pragma parameter inter " Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0 +#define inter params.inter // interlace resolution + +#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 +#define iscan params.iscan // interlacing effect scanlining + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match + +#define intres params.intres // interlace resolution + +#pragma parameter downsample_levelx " Downsampling-X (High-res content, pre-scalers)" 0.0 0.0 2.0 0.05 +#define downsample_levelx params.downsample_levelx // downsample level + +#pragma parameter downsample_levely " Downsampling-Y (High-res content, pre-scalers)" 0.0 0.0 2.0 0.05 +#define downsample_levely params.downsample_levely // downsample level + +#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match +#define prescalex params.prescalex // prescale-x factor + +#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05 +#define iscans params.iscans // interlace saturation + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D PrePass; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + + +vec3 fetch_pixel(vec2 coord) +{ + vec2 dx = vec2(global.SourceSize.z, 0.0) * downsample_levelx; + vec2 dy = vec2(0.0, global.SourceSize.w) * downsample_levely; + vec2 d1 = dx + dy; + vec2 d2 = dx - dy; + + float sum = 15.0; + vec3 result = 3.0*COMPAT_TEXTURE(PrePass, coord ).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dy).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dy).rgb + + COMPAT_TEXTURE(PrePass, coord + d1).rgb + + COMPAT_TEXTURE(PrePass, coord - d1).rgb + + COMPAT_TEXTURE(PrePass, coord + d2).rgb + + COMPAT_TEXTURE(PrePass, coord - d2).rgb; + + return result/sum; +} + + +void main() +{ + vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb; + vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, params.OriginalSize.w)).rgb; + + if ((downsample_levelx + downsample_levely) > 0.025) + { + c1 = fetch_pixel(vTexCoord); + c2 = fetch_pixel(vTexCoord + vec2(0.0, params.OriginalSize.w)); + } + + vec3 c = c1; + + float intera = 1.0; + float gamma_in = clamp(GAMMA_INPUT, 1.0, 5.0); + + float m1 = max(max(c1.r,c1.g),c1.b); + float m2 = max(max(c2.r,c2.g),c2.b); + vec3 df = abs(c1-c2); + + float d = max(max(df.r,df.g),df.b); + if (interm == 2.0) d = mix(0.1*d,10.0*d, step(m1/(m2+0.0001),m2/(m1+0.0001))); + + float r = m1; + + float yres_div = 1.0; if (intres > 1.25) yres_div = intres; + + if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5) + { + intera = 0.5; + float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0); + float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0); + float ii = abs(line_no-frame_no); + + if (interm < 3.5) + { + c2 = plant(mix(c2, c2*c2, iscans), max(max(c2.r,c2.g),c2.b)); + r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0); + 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); + intera = 0.0; + } + if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); + 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));} + } + c = pow(c, vec3(gamma_in)); + + if (vTexCoord.x > 0.5) gamma_in = intera; else gamma_in = 1.0/gamma_in; + + FragColor = vec4(c, gamma_in); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/linearize.slang b/crt/shaders/guest/advanced/linearize.slang new file mode 100644 index 0000000..14b0472 --- /dev/null +++ b/crt/shaders/guest/advanced/linearize.slang @@ -0,0 +1,176 @@ +#version 450 + +/* + Interlacing + + 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 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float GAMMA_INPUT; + float inter; + float interm; + float iscan; + float intres; + float iscans; + float downsample_levelx; + float downsample_levely; + float prescalex; +} params; + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + vec4 SourceSize; + mat4 MVP; +} global; + + +#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05 +#define GAMMA_INPUT params.GAMMA_INPUT + +#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0 + +#pragma parameter inter " Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0 +#define inter params.inter // interlace resolution + +#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 +#define iscan params.iscan // interlacing effect scanlining + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match + +#define intres params.intres // interlace resolution + +#pragma parameter downsample_levelx " Downsampling-X (High-res content, pre-scalers)" 0.0 0.0 3.0 0.05 +#define downsample_levelx params.downsample_levelx // downsample level + +#pragma parameter downsample_levely " Downsampling-Y (High-res content, pre-scalers)" 0.0 0.0 3.0 0.05 +#define downsample_levely params.downsample_levely // downsample level + +#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match +#define prescalex params.prescalex // prescale-x factor + +#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05 +#define iscans params.iscans // interlace saturation + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D PrePass; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + + +vec3 fetch_pixel(vec2 coord) +{ + vec2 dx = vec2(global.SourceSize.z, 0.0) * downsample_levelx; + vec2 dy = vec2(0.0, global.SourceSize.w) * downsample_levely; + vec2 d1 = dx + dy; + vec2 d2 = dx - dy; + + float sum = 15.0; + vec3 result = 3.0*COMPAT_TEXTURE(PrePass, coord ).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dy).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dy).rgb + + COMPAT_TEXTURE(PrePass, coord + d1).rgb + + COMPAT_TEXTURE(PrePass, coord - d1).rgb + + COMPAT_TEXTURE(PrePass, coord + d2).rgb + + COMPAT_TEXTURE(PrePass, coord - d2).rgb; + + return result/sum; +} + + +void main() +{ + vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb; + vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, params.OriginalSize.w)).rgb; + + if ((downsample_levelx + downsample_levely) > 0.025) + { + c1 = fetch_pixel(vTexCoord); + c2 = fetch_pixel(vTexCoord + vec2(0.0, params.OriginalSize.w)); + } + + vec3 c = c1; + + float intera = 1.0; + float gamma_in = clamp(GAMMA_INPUT, 1.0, 5.0); + + float m1 = max(max(c1.r,c1.g),c1.b); + float m2 = max(max(c2.r,c2.g),c2.b); + vec3 df = abs(c1-c2); + + float d = max(max(df.r,df.g),df.b); + if (interm == 2.0) d = mix(0.1*d,10.0*d, step(m1/(m2+0.0001),m2/(m1+0.0001))); + + float r = m1; + + float yres_div = 1.0; if (intres > 1.25) yres_div = intres; + + if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5) + { + intera = 0.5; + float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0); + float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0); + float ii = abs(line_no-frame_no); + + if (interm < 3.5) + { + c2 = plant(mix(c2, c2*c2, iscans), max(max(c2.r,c2.g),c2.b)); + r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0); + 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); + intera = 0.0; + } + if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); + 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));} + } + c = pow(c, vec3(gamma_in)); + + if (vTexCoord.x > 0.5) gamma_in = intera; else gamma_in = 1.0/gamma_in; + + FragColor = vec4(c, gamma_in); +} \ No newline at end of file diff --git a/crt/shaders/guest/advanced/lut/inv-trinitron-lut.png b/crt/shaders/guest/advanced/lut/inv-trinitron-lut.png new file mode 100644 index 0000000..ea93bda Binary files /dev/null and b/crt/shaders/guest/advanced/lut/inv-trinitron-lut.png differ diff --git a/crt/shaders/guest/advanced/lut/nec-lut.png b/crt/shaders/guest/advanced/lut/nec-lut.png new file mode 100644 index 0000000..d18e00d Binary files /dev/null and b/crt/shaders/guest/advanced/lut/nec-lut.png differ diff --git a/crt/shaders/guest/advanced/lut/ntsc-lut.png b/crt/shaders/guest/advanced/lut/ntsc-lut.png new file mode 100644 index 0000000..ef7e883 Binary files /dev/null and b/crt/shaders/guest/advanced/lut/ntsc-lut.png differ diff --git a/crt/shaders/guest/advanced/lut/trinitron-lut.png b/crt/shaders/guest/advanced/lut/trinitron-lut.png new file mode 100644 index 0000000..d38bdd7 Binary files /dev/null and b/crt/shaders/guest/advanced/lut/trinitron-lut.png differ diff --git a/crt/shaders/guest/advanced/pre-shaders-afterglow.slang b/crt/shaders/guest/advanced/pre-shaders-afterglow.slang new file mode 100644 index 0000000..622716e --- /dev/null +++ b/crt/shaders/guest/advanced/pre-shaders-afterglow.slang @@ -0,0 +1,356 @@ +#version 450 + +/* + CRT Advanced Afterglow, color altering + + Copyright (C) 2019-2021 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 + 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 TNTC; + float LS; + float LUTLOW, LUTBR; + float CP, CS; + float WP; + float wp_saturation; + float AS, sat; + float BP; + float vigstr; + float vigdef; + float sega_fix; + float pre_bb; +} params; + +#pragma parameter AS " Afterglow Strength" 0.20 0.0 0.60 0.01 +#define AS params.AS + +#pragma parameter sat " Afterglow saturation" 0.20 0.0 1.0 0.01 +#define sat params.sat + +#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter CS " Display Gamut: sRGB, Modern, DCI, Adobe, Rec.2020" 0.0 0.0 4.0 1.0 + +#pragma parameter CP " CRT Profile: EBU | P22 | SMPTE-C | Philips | Trin." 0.0 -1.0 5.0 1.0 + +#define CP params.CP +#define CS params.CS + +#pragma parameter TNTC " LUT Colors: Trin. | invTrin. | 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 +#define LS params.LS + +#define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons + +#define LUTBR 1.0 // "Fix LUT Brightness" from 0.0 to 1.0 + +#pragma parameter WP " Color Temperature %" 0.0 -100.0 100.0 5.0 + +#pragma parameter wp_saturation " Saturation Adjustment" 1.0 0.0 2.0 0.05 + +#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01 + +#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0 + +#pragma parameter BP " Raise Black Level" 0.0 0.0 25.0 1.0 + +#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.025 + +#pragma parameter vigdef " Vignette Definition" 7.0 0.4 15.0 0.2 + +#define WP params.WP +#define wp_saturation params.wp_saturation +#define BP params.BP + +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 StockPass; +layout(set = 0, binding = 3) uniform sampler2D AfterglowPass; +layout(set = 0, binding = 4) uniform sampler2D SamplerLUT1; +layout(set = 0, binding = 5) uniform sampler2D SamplerLUT2; +layout(set = 0, binding = 6) uniform sampler2D SamplerLUT3; +layout(set = 0, binding = 7) uniform sampler2D SamplerLUT4; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + + +// Color profile matrices + +const mat3 Profile0 = +mat3( + 0.412391, 0.212639, 0.019331, + 0.357584, 0.715169, 0.119195, + 0.180481, 0.072192, 0.950532 +); + +const mat3 Profile1 = +mat3( + 0.430554, 0.222004, 0.020182, + 0.341550, 0.706655, 0.129553, + 0.178352, 0.071341, 0.939322 +); + +const mat3 Profile2 = +mat3( + 0.396686, 0.210299, 0.006131, + 0.372504, 0.713766, 0.115356, + 0.181266, 0.075936, 0.967571 +); + +const mat3 Profile3 = +mat3( + 0.393521, 0.212376, 0.018739, + 0.365258, 0.701060, 0.111934, + 0.191677, 0.086564, 0.958385 +); + +const mat3 Profile4 = +mat3( + 0.392258, 0.209410, 0.016061, + 0.351135, 0.725680, 0.093636, + 0.166603, 0.064910, 0.850324 +); + +const mat3 Profile5 = +mat3( + 0.377923, 0.195679, 0.010514, + 0.317366, 0.722319, 0.097826, + 0.207738, 0.082002, 1.076960 +); + +const mat3 ToSRGB = +mat3( + 3.240970, -0.969244, 0.055630, +-1.537383, 1.875968, -0.203977, +-0.498611, 0.041555, 1.056972 +); + +const mat3 ToModern = +mat3( + 2.791723, -0.894766, 0.041678, +-1.173165, 1.815586, -0.130886, +-0.440973, 0.032000, 1.002034 +); + +const mat3 ToDCI = +mat3( + 2.493497, -0.829489, 0.035846, +-0.931384, 1.762664, -0.076172, +-0.402711, 0.023625, 0.956885 +); + +const mat3 ToAdobe = +mat3( + 2.041588, -0.969244, 0.013444, +-0.565007, 1.875968, -0.11836, +-0.344731, 0.041555, 1.015175 +); + +const mat3 ToREC = +mat3( + 1.716651, -0.666684, 0.017640, +-0.355671, 1.616481, -0.042771, +-0.253366, 0.015769, 0.942103 +); + +// Color temperature matrices + +const mat3 D65_to_D55 = mat3 ( + 0.4850339153, 0.2500956126, 0.0227359648, + 0.3488957224, 0.6977914447, 0.1162985741, + 0.1302823568, 0.0521129427, 0.6861537456); + + +const mat3 D65_to_D93 = mat3 ( + 0.3683017655, 0.1899055978, 0.0172641453, + 0.3555467892, 0.7110935785, 0.1185155964, + 0.2475020592, 0.0990008237, 1.3035108450); + + +vec3 fix_lut(vec3 lutcolor, vec3 ref) +{ + float r = length(ref); + float l = length(lutcolor); + float m = max(max(ref.r,ref.g),ref.b); + ref = normalize(lutcolor + 0.0000001) * mix(r, l, pow(m,1.25)); + return mix(lutcolor, ref, LUTBR); +} + +vec2 ctransform (vec2 inputc) +{ + return vec2( inputc.x * sqrt(1.0 - 0.5*inputc.y*inputc.y), inputc.y * sqrt(1.0 - 0.5*inputc.x*inputc.x)); +} + +float vignette (vec2 coords) +{ + vec2 ccoords = ctransform(2.0*(coords-0.5)); + ccoords = ccoords * ccoords; + float vstr = sqrt(ccoords.x+ccoords.y); + vstr = pow(vstr, params.vigdef); + return max(mix(1.0, 1.0-vstr, params.vigstr), 0.0); +} + +void main() +{ + vec4 imgColor = COMPAT_TEXTURE(StockPass, vTexCoord.xy); + vec4 aftglow = COMPAT_TEXTURE(AfterglowPass, vTexCoord.xy); + + float w = 1.0-aftglow.w; + + float l = length(aftglow.rgb); + aftglow.rgb = AS*w*normalize(pow(aftglow.rgb + 0.01, vec3(sat)))*l; + float bp = w * BP/255.0; + + imgColor.rgb = imgColor.rgb * params.pre_bb; + + if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0); + + imgColor.rgb = min(imgColor.rgb, 1.0); + + vec3 color = imgColor.rgb; + + if (int(TNTC) == 0) + { + color.rgb = imgColor.rgb; + } + else + { + float lutlow = LUTLOW/255.0; float invLS = 1.0/LS; + vec3 lut_ref = imgColor.rgb + lutlow*(1.0 - pow(imgColor.rgb, 0.333.xxx)); + float lutb = lut_ref.b * (1.0-0.5*invLS); + lut_ref.rg = lut_ref.rg * (1.0-invLS) + 0.5*invLS; + float tile1 = ceil (lutb * (LS-1.0)); + float tile0 = max(tile1 - 1.0, 0.0); + float f = fract(lutb * (LS-1.0)); if (f == 0.0) f = 1.0; + vec2 coord0 = vec2(tile0 + lut_ref.r, lut_ref.g)*vec2(invLS, 1.0); + vec2 coord1 = vec2(tile1 + lut_ref.r, lut_ref.g)*vec2(invLS, 1.0); + vec4 color1, color2, res; + + if (int(TNTC) == 1) + { + color1 = COMPAT_TEXTURE(SamplerLUT1, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT1, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 2) + { + color1 = COMPAT_TEXTURE(SamplerLUT2, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT2, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 3) + { + color1 = COMPAT_TEXTURE(SamplerLUT3, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT3, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 4) + { + color1 = COMPAT_TEXTURE(SamplerLUT4, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT4, coord1); + res = mix(color1, color2, f); + } + + res.rgb = fix_lut (res.rgb, imgColor.rgb); + + color = mix(imgColor.rgb, res.rgb, min(TNTC,1.0)); + } + + vec3 c = clamp(color, 0.0, 1.0); + + float p; + mat3 m_out; + + if (CS == 0.0) { p = 2.2; m_out = ToSRGB; } else + if (CS == 1.0) { p = 2.2; m_out = ToModern; } else + if (CS == 2.0) { p = 2.6; m_out = ToDCI; } else + if (CS == 3.0) { p = 2.2; m_out = ToAdobe; } else + if (CS == 4.0) { p = 2.4; m_out = ToREC; } + + color = pow(c, vec3(p)); + + mat3 m_in = Profile0; + + if (CP == 0.0) { m_in = Profile0; } else + if (CP == 1.0) { m_in = Profile1; } else + if (CP == 2.0) { m_in = Profile2; } else + if (CP == 3.0) { m_in = Profile3; } else + if (CP == 4.0) { m_in = Profile4; } else + if (CP == 5.0) { m_in = Profile5; } + + color = m_in*color; + color = m_out*color; + + color = clamp(color, 0.0, 1.0); + + color = pow(color, vec3(1.0/p)); + + if (CP == -1.0) color = c; + + vec3 scolor1 = normalize(pow(color + 0.000000001, vec3(wp_saturation)))*length(color); + float luma = dot(color, vec3(0.2126, 0.7152, 0.0722)); + vec3 scolor2 = mix(vec3(luma), color, wp_saturation); + color = (wp_saturation > 1.0) ? scolor1 : scolor2; + + p = 2.2; + + color = pow(color, vec3(p)); + + color = clamp(color, 0.0, 1.0); + + vec3 warmer = D65_to_D55*color; + warmer = ToSRGB*warmer; + + vec3 cooler = D65_to_D93*color; + cooler = ToSRGB*cooler; + + float m = abs(WP)/100.0; + + vec3 comp = (WP < 0.0) ? cooler : warmer; + + color = mix(color, comp, m); + color = pow(max(color, 0.0), vec3(1.0/p)); + + color = color + aftglow.rgb + bp; + + FragColor = vec4(color, vignette(vTexCoord.xy)); +} \ No newline at end of file diff --git a/crt/shaders/guest/avg-lum0.slang b/crt/shaders/guest/avg-lum0.slang deleted file mode 100644 index f2ef96f..0000000 --- a/crt/shaders/guest/avg-lum0.slang +++ /dev/null @@ -1,63 +0,0 @@ -#version 450 - -// Avg. Luminance Smoothing - -layout(push_constant) uniform Push -{ - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; -} params; - -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 OriginalHistory1; -layout(set = 0, binding = 3) uniform sampler2D OriginalHistory2; -layout(set = 0, binding = 4) uniform sampler2D OriginalHistory3; -layout(set = 0, binding = 5) uniform sampler2D OriginalHistory4; -layout(set = 0, binding = 6) uniform sampler2D OriginalHistory5; -layout(set = 0, binding = 7) uniform sampler2D OriginalHistory6; -layout(set = 0, binding = 8) uniform sampler2D OriginalHistory7; - -#define PrevTexture OriginalHistory1 -#define Prev1Texture OriginalHistory2 -#define Prev2Texture OriginalHistory3 -#define Prev3Texture OriginalHistory4 -#define Prev4Texture OriginalHistory5 -#define Prev5Texture OriginalHistory6 -#define Prev6Texture OriginalHistory7 - -#define TEX0 vTexCoord -#define COMPAT_TEXTURE(c,d) texture(c,d) - - -void main() -{ - vec3 color = COMPAT_TEXTURE(PrevTexture, TEX0.xy).rgb; - color+= COMPAT_TEXTURE(Prev6Texture, TEX0.xy).rgb; - color+= COMPAT_TEXTURE(Prev5Texture, TEX0.xy).rgb; - color+= COMPAT_TEXTURE(Prev4Texture, TEX0.xy).rgb; - color+= COMPAT_TEXTURE(Prev3Texture, TEX0.xy).rgb; - color+= COMPAT_TEXTURE(Prev2Texture, TEX0.xy).rgb; - color+= COMPAT_TEXTURE(Prev1Texture, TEX0.xy).rgb; - - FragColor = vec4(color/7.0,1.0); -} \ No newline at end of file diff --git a/crt/shaders/guest/crt-sm/blur_horiz-sm.slang b/crt/shaders/guest/crt-sm/blur_horiz-sm.slang index 66aed49..a144a66 100644 --- a/crt/shaders/guest/crt-sm/blur_horiz-sm.slang +++ b/crt/shaders/guest/crt-sm/blur_horiz-sm.slang @@ -14,9 +14,9 @@ layout(push_constant) uniform Push // Lower values might need more taps. // Adapted from crt-easymode-halation by Easymode. -#pragma parameter TAPSH "H. Glow Radius" 5.0 1.0 10.0 1.0 +#pragma parameter TAPSH "H. Glow Radius" 4.0 1.0 10.0 1.0 #define TAPSH params.TAPSH -#pragma parameter GLOW_FALLOFF_H "Horizontal Glow Grade" 0.25 0.00 1.5 0.02 +#pragma parameter GLOW_FALLOFF_H "Horizontal Glow Grade" 0.35 0.00 1.5 0.02 #define GLOW_FALLOFF_H params.GLOW_FALLOFF_H layout(std140, set = 0, binding = 0) uniform UBO diff --git a/crt/shaders/guest/crt-sm/blur_vert-sm.slang b/crt/shaders/guest/crt-sm/blur_vert-sm.slang index da76dd6..60f5851 100644 --- a/crt/shaders/guest/crt-sm/blur_vert-sm.slang +++ b/crt/shaders/guest/crt-sm/blur_vert-sm.slang @@ -15,9 +15,9 @@ layout(push_constant) uniform Push // Adapted from crt-easymode-halation by Easymode. // Parameter lines go here: -#pragma parameter TAPSV "V. Glow Radius" 5.0 1.0 10.0 1.0 +#pragma parameter TAPSV "V. Glow Radius" 4.0 1.0 10.0 1.0 #define TAPSV params.TAPSV -#pragma parameter GLOW_FALLOFF_V "Vertical Glow Grade" 0.25 0.00 1.5 0.02 +#pragma parameter GLOW_FALLOFF_V "Vertical Glow Grade" 0.35 0.00 1.5 0.02 #define GLOW_FALLOFF_V params.GLOW_FALLOFF_V layout(std140, set = 0, binding = 0) uniform UBO diff --git a/crt/shaders/guest/crt-sm/crt-guest-sm.slang b/crt/shaders/guest/crt-sm/crt-guest-sm.slang index 7fc9823..9c05780 100644 --- a/crt/shaders/guest/crt-sm/crt-guest-sm.slang +++ b/crt/shaders/guest/crt-sm/crt-guest-sm.slang @@ -65,12 +65,14 @@ layout(std140, set = 0, binding = 0) uniform UBO float warpx; float warpy; float bloom; + float halation; float autobrm; float sclip; } global; #pragma parameter bglow "Base Glow" 0.0 0.0 1.0 0.01 #pragma parameter bloom "Bloom" 0.40 0.0 2.0 0.05 +#pragma parameter halation "Halation" 0.0 0.0 2.0 0.05 #pragma parameter autobrm "Automatic Brightness (Mask)" 0.5 0.0 1.0 0.1 #pragma parameter smart "1:Smart 2:Crop 3:Overscan Y Integer Scaling" 0.0 0.0 3.0 1.0 #pragma parameter brightboost1 "Bright boost dark colors" 1.40 0.5 5.0 0.10 @@ -99,6 +101,7 @@ layout(std140, set = 0, binding = 0) uniform UBO #define brightboost1 params.brightboost1 #define brightboost2 params.brightboost2 #define bloom global.bloom +#define halation global.halation #define stype params.stype #define scanline1 params.scanline1 #define scanline2 params.scanline2 @@ -242,6 +245,8 @@ void main() vec2 OGL2Pos = tex * SourceSize1.xy - vec2(0.5,0.5); vec2 fp = fract(OGL2Pos); + float fpx = fp.x; + float fp1 = 1.0-fpx; vec2 pC4 = (floor(OGL2Pos) + vec2(0.5)) * SourceSize1.zw; @@ -256,15 +261,20 @@ void main() float wr1 = 1.0 - fp.x; float wr2 = 2.0 - fp.x; - wl2*=wl2; wl2 = exp2(-h_sharp*wl2); float sl2 = wl2; - wl1*=wl1; wl1 = exp2(-h_sharp*wl1); float sl1 = wl1; - wr1*=wr1; wr1 = exp2(-h_sharp*wr1); float sr1 = wr1; - wr2*=wr2; wr2 = exp2(-h_sharp*wr2); float sr2 = wr2; + wl2*=wl2; wl2 = exp2(-h_sharp*wl2); + wl1*=wl1; wl1 = exp2(-h_sharp*wl1); + wr1*=wr1; wr1 = exp2(-h_sharp*wr1); + wr2*=wr2; wr2 = exp2(-h_sharp*wr2); - wl2 = max(wl2 - zero, mix(0.0,mix(-0.14, -0.035, fp.x),float(cubic > 0.05))); + wl2 = max(wl2 - zero, mix(0.0,mix(-0.14, 0.0, 1.0-fp1*fp1),float(cubic > 0.05))); wl1 = max(wl1 - zero, 0.0); wr1 = max(wr1 - zero, 0.0); - wr2 = max(wr2 - zero, mix(0.0,mix(-0.14, -0.035, 1.-fp.x),float(cubic > 0.05))); + wr2 = max(wr2 - zero, mix(0.0,mix(-0.14, 0.0, 1.0-fpx*fpx),float(cubic > 0.05))); + + float sl2 = max(wl2,0.0); + float sl1 = wl1; + float sr1 = wr1; + float sr2 = max(wr2,0.0); float wtt = 1.0/(wl2+wl1+wr1+wr2); float wts = 1.0/(sl2+sl1+sr1+sr2); @@ -281,11 +291,11 @@ void main() if (cubic > 0.05) color1 = clamp(color1, colmin, colmax); - l1*=l1; l1*=l1; r1*=r1; r1*=r1; l2*=l2; l2*=l2; r2*=r2; r2*=r2; + l1*=l1; l1*=l1*l1; r1*=r1; r1*=r1*r1; l2*=l2; l2*=l2*l2; r2*=r2; r2*=r2*r2; vec3 scolor1 = (sl2*l2+sl1*l1+sr1*r1+sr2*r2)*wts; - scolor1 = pow(scolor1, vec3(1.0/4.0)); vec3 mscolor1 = scolor1; + scolor1 = pow(scolor1, vec3(1.0/6.0)); vec3 mscolor1 = scolor1; - scolor1 = mix(color1, scolor1, 1.1); + scolor1 = mix(color1, scolor1, 1.0); pC4+=dy; l2 = COMPAT_TEXTURE(LinPass, pC4 - dx).rgb; @@ -300,11 +310,11 @@ void main() if (cubic > 0.05) color2 = clamp(color2, colmin, colmax); - l1*=l1; l1*=l1; r1*=r1; r1*=r1; l2*=l2; l2*=l2; r2*=r2; r2*=r2; + l1*=l1; l1*=l1*l1; r1*=r1; r1*=r1*r1; l2*=l2; l2*=l2*l2; r2*=r2; r2*=r2*r2; vec3 scolor2 = (sl2*l2+sl1*l1+sr1*r1+sr2*r2)*wts; - scolor2 = pow(scolor2, vec3(1.0/4.0)); vec3 mscolor2 = scolor2; + scolor2 = pow(scolor2, vec3(1.0/6.0)); vec3 mscolor2 = scolor2; - scolor2 = mix(color2, scolor2, 1.1); + scolor2 = mix(color2, scolor2, 1.0); float f1 = fp.y; float f2 = 1.0 - fp.y; @@ -353,11 +363,11 @@ void main() vec3 ctemp = (t1*color1 + t2*color2)*wt; vec3 orig = ctemp; float pixbr = max(max(orig.r,orig.g),orig.b); vec3 one = vec3(1.0); - vec3 tmp1 = clamp(mix(orig, msctemp, 1.75),0.0,1.0); + vec3 tmp1 = clamp(mix(orig, msctemp, 1.25),0.0,1.0); ctemp = w1+w2; float w3 = max(max(ctemp.r,ctemp.g),ctemp.b); - tmp1 = pow(tmp1, vec3(0.75)); + tmp1 = pow(tmp1, vec3(0.65)); float pixbr1 = max(max(tmp1.r,tmp1.g),tmp1.b); float maskd = mix(min(maskdark,1.0), 0.25*max(maskbright,0.0), pixbr1); if (mask == 3.0 || mask == 4.0) maskd*=1.33; maskd = mix(1.0, 1.0/(1.0-0.5*maskd), autobrm); @@ -436,6 +446,8 @@ void main() vec3 Bloom = COMPAT_TEXTURE(Source, tex).rgb; vec3 Bglow = COMPAT_TEXTURE(LinPass, tex).rgb; Bglow = clamp(Bloom - Bglow,0.0,1.0); + vec3 hglow = 0.5*(Bloom + Bglow); + float maxb = max(max(hglow.r,hglow.g),hglow.b); maxb*=maxb; vec3 Bloom1 = 2.0*Bloom*Bloom; Bloom1 = min(Bloom1, 0.75); @@ -452,6 +464,10 @@ void main() color = min(color,1.0); color = declip(color, pow(w3, 1.0-sclip)); + float colmx = pixbr1; + Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx); + color = color + 0.75*(0.75+maxb)*Bloom*(0.75+sqrt(colmx))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; + color = color + bglow*Bglow; color = min(color, mix(cmask,one,sclip)); diff --git a/crt/shaders/guest/fast/bloom_horizontal.slang b/crt/shaders/guest/fast/bloom_horizontal.slang new file mode 100644 index 0000000..1e88d1d --- /dev/null +++ b/crt/shaders/guest/fast/bloom_horizontal.slang @@ -0,0 +1,103 @@ +#version 450 + +/* + Gaussian blur - horizontal pass, dynamic range, resizable + + Copyright (C) 2021 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. + +*/ + +#pragma format R16G16B16A16_SFLOAT + +layout(push_constant) uniform Push +{ + vec4 LinearizePassSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEHB; + float SIGMA_HB; +} params; + +#pragma parameter bogus_glow "[ GLOW/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 +#define SIZEHB params.SIZEHB + +#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/Glow Sigma" 0.70 0.5 15.0 0.05 +#define SIGMA_HB params.SIGMA_HB + +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_HB*SIGMA_HB); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +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; + vec4 color = vec4(0.0); + vec2 dx = vec2(SourceSize1.z, 0.0); + + float w; + float wsum = 0.0; + vec4 pixel; + float n = -SIZEHB; + + do + { + pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx); + w = gaussian(n+f); + pixel.a = max(max(pixel.r, pixel.g),pixel.b); + pixel.a*=pixel.a*pixel.a; + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEHB); + + color = color / wsum; + + FragColor = vec4(color.rgb, pow(color.a, 0.333333)); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/bloom_vertical.slang b/crt/shaders/guest/fast/bloom_vertical.slang new file mode 100644 index 0000000..bc7a423 --- /dev/null +++ b/crt/shaders/guest/fast/bloom_vertical.slang @@ -0,0 +1,102 @@ +#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. + +*/ + +#pragma format R16G16B16A16_SFLOAT + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEVB; + float SIGMA_VB; +} params; + + +#pragma parameter SIZEVB " V. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0 +#define SIZEVB params.SIZEVB + +#pragma parameter SIGMA_VB " Vertical Bloom/Halation/Glow Sigma" 0.70 0.5 15.0 0.05 +#define SIGMA_VB params.SIGMA_VB + +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_VB*SIGMA_VB); + +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; + vec4 color = vec4(0.0); + vec2 dy = vec2(0.0, SourceSize1.w); + + float w; + float wsum = 0.0; + vec4 pixel; + float n = -SIZEVB; + + do + { + pixel = COMPAT_TEXTURE(Source, tex + n*dy); + w = gaussian(n+f); + pixel.a*=pixel.a*pixel.a; + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEVB); + + color = color / wsum; + + FragColor = vec4(color.rgb, pow(color.a, 0.175)); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/crt-guest-advanced-pass1.slang b/crt/shaders/guest/fast/crt-guest-advanced-pass1.slang new file mode 100644 index 0000000..21af228 --- /dev/null +++ b/crt/shaders/guest/fast/crt-guest-advanced-pass1.slang @@ -0,0 +1,166 @@ +#version 450 + +/* + CRT - Guest - Advanced - Fast - Pass1 + + Copyright (C) 2018-2021 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. + + 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 IOS, h_sharp, s_sharp, spike; + float prescalex; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + + +#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.10 +#define h_sharp params.h_sharp // pixel sharpness + +#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10 +#define s_sharp params.s_sharp // substractive sharpness + +#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10 +#define spike params.spike + +#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with linearize pass, values must match +#define prescalex params.prescalex // prescale-x factor + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define TEX0 vTexCoord + +#define OutputSize params.OutputSize +#define gl_FragCoord (vTexCoord * OutputSize.xy) + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D LinearizePass; + + +void main() +{ + vec4 SourceSize = params.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0); + + float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; + + // Calculating texel coordinates + + vec2 texcoord = TEX0.xy; + + vec2 pos = texcoord; + + vec2 coffset = vec2(0.5, 0.5); + + vec2 ps = SourceSize.zw; + vec2 OGL2Pos = pos * SourceSize.xy - coffset; + float fpx = fract(OGL2Pos.x); + + vec2 offx = vec2(ps.x,0.0); + + // Reading the texels + vec2 x2 = 2.0*offx; + + vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps; + + float zero = exp2(-h_sharp); + float sharp1 = s_sharp * zero; + + float fdivider = min(prescalex, 2.0); + + float wl3 = (2.0 + fpx)/fdivider; + float wl2 = (1.0 + fpx)/fdivider; + float wl1 = ( fpx)/fdivider; + float wr1 = (1.0 - fpx)/fdivider; + float wr2 = (2.0 - fpx)/fdivider; + float wr3 = (3.0 - fpx)/fdivider; + + wl3*=wl3; wl3 = exp2(-h_sharp*wl3); + wl2*=wl2; wl2 = exp2(-h_sharp*wl2); + wl1*=wl1; wl1 = exp2(-h_sharp*wl1); + wr1*=wr1; wr1 = exp2(-h_sharp*wr1); + wr2*=wr2; wr2 = exp2(-h_sharp*wr2); + wr3*=wr3; wr3 = exp2(-h_sharp*wr3); + + float fp1 = 1.-fpx; + + float twl3 = max(wl3 - sharp1, 0.0); + float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1)); + float twl1 = max(wl1 - sharp1, 0.0); + float twr1 = max(wr1 - sharp1, 0.0); + float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx)); + float twr3 = max(wr3 - sharp1, 0.0); + + bool sharp = (sharp1 > 0.0); + + vec3 l3, l2, l1, r1, r2, r3, color1, colmin, colmax; + + l3 = COMPAT_TEXTURE(LinearizePass, pC4 -x2).rgb; + l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb; + r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(LinearizePass, pC4 +x2).rgb; + r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+x2).rgb; + + colmin = min(min(l1,r1), min(l2,r2)); + colmax = max(max(l1,r1), max(l2,r2)); + + color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3); + + if (sharp) color1 = clamp(color1, colmin, colmax); + float ts = 0.033; + + float lm2 = max(max(l2.r,l2.g),l2.b); + float lm1 = max(max(l1.r,l1.g),l1.b); + float rm1 = max(max(r1.r,r1.g),r1.b); + float rm2 = max(max(r2.r,r2.g),r2.b); + + float swl2 = max(twl2,0.0) * (lm2+ts); + float swl1 = twl1 * (lm1+ts); + float swr1 = twr1 * (rm1+ts); + float swr2 = max(twr2,0.0) * (rm2+ts); + + float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2); + float sresult = clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0); + + FragColor = vec4(color1, sresult); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/crt-guest-advanced-pass1f.slang b/crt/shaders/guest/fast/crt-guest-advanced-pass1f.slang new file mode 100644 index 0000000..1e4a298 --- /dev/null +++ b/crt/shaders/guest/fast/crt-guest-advanced-pass1f.slang @@ -0,0 +1,159 @@ +#version 450 + +/* + CRT - Guest - Advanced - Fast - Pass1 + + Copyright (C) 2018-2021 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. + + 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 IOS, h_sharp, s_sharp, spike; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + + +#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.10 +#define h_sharp params.h_sharp // pixel sharpness + +#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10 +#define s_sharp params.s_sharp // substractive sharpness + +#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10 +#define spike params.spike + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define TEX0 vTexCoord + +#define SourceSize params.OriginalSize +#define OutputSize params.OutputSize +#define gl_FragCoord (vTexCoord * OutputSize.xy) + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D LinearizePass; + + +void main() +{ + float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; + + // Calculating texel coordinates + + vec2 texcoord = TEX0.xy; + + vec2 pos = texcoord; + + vec2 coffset = vec2(0.5, 0.5); + + vec2 ps = SourceSize.zw; + vec2 OGL2Pos = pos * SourceSize.xy - coffset; + float fpx = fract(OGL2Pos.x); + + vec2 offx = vec2(ps.x,0.0); + + // Reading the texels + vec2 x2 = 2.0*offx; + + vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps; + + float zero = exp2(-h_sharp); + float sharp1 = s_sharp * zero; + + float wl3 = 2.0 + fpx; + float wl2 = 1.0 + fpx; + float wl1 = fpx; + float wr1 = 1.0 - fpx; + float wr2 = 2.0 - fpx; + float wr3 = 3.0 - fpx; + + wl3*=wl3; wl3 = exp2(-h_sharp*wl3); + wl2*=wl2; wl2 = exp2(-h_sharp*wl2); + wl1*=wl1; wl1 = exp2(-h_sharp*wl1); + wr1*=wr1; wr1 = exp2(-h_sharp*wr1); + wr2*=wr2; wr2 = exp2(-h_sharp*wr2); + wr3*=wr3; wr3 = exp2(-h_sharp*wr3); + + float fp1 = 1.-fpx; + + float twl3 = max(wl3 - sharp1, 0.0); + float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1)); + float twl1 = max(wl1 - sharp1, 0.0); + float twr1 = max(wr1 - sharp1, 0.0); + float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx)); + float twr3 = max(wr3 - sharp1, 0.0); + + bool sharp = (sharp1 > 0.0); + + vec3 l3, l2, l1, r1, r2, r3, color1, colmin, colmax; + + l3 = COMPAT_TEXTURE(LinearizePass, pC4 -x2).rgb; + l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb; + l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb; + r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb; + r2 = COMPAT_TEXTURE(LinearizePass, pC4 +x2).rgb; + r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+x2).rgb; + + colmin = min(min(l1,r1), min(l2,r2)); + colmax = max(max(l1,r1), max(l2,r2)); + + color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3); + + if (sharp) color1 = clamp(color1, colmin, colmax); + float ts = 0.033; + + float lm2 = max(max(l2.r,l2.g),l2.b); + float lm1 = max(max(l1.r,l1.g),l1.b); + float rm1 = max(max(r1.r,r1.g),r1.b); + float rm2 = max(max(r2.r,r2.g),r2.b); + + float swl2 = max(twl2,0.0) * (lm2+ts); + float swl1 = twl1 * (lm1+ts); + float swr1 = twr1 * (rm1+ts); + float swr2 = max(twr2,0.0) * (rm2+ts); + + float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2); + float sresult = clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0); + + FragColor = vec4(color1, sresult); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/crt-guest-advanced-pass2.slang b/crt/shaders/guest/fast/crt-guest-advanced-pass2.slang new file mode 100644 index 0000000..69a1309 --- /dev/null +++ b/crt/shaders/guest/fast/crt-guest-advanced-pass2.slang @@ -0,0 +1,601 @@ +#version 450 + +/* + CRT - Guest - Advanced - Fast - Pass2 + + Copyright (C) 2018-2021 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. + + 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 +{ + float brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, + glow, shadowMask, masksize, vertmask, slotmask, slotwidth, double_slot, mcut, maskDark, maskLight, + maskstr, inters, bloom, halation, scans, slotms, mclip, gamma_c, gamma_out, DER, DEG, DEB, DES, IOS; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float addnoise; + float warpX; + float warpY; + float csize; + float bsize; + float intres; + float c_shape; + float barspeed; + float barintensity; + float bardir; + float slotmask1; +} global; + +#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match + +#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0 +#define IOS params.IOS // Smart Integer Scaling + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01 +#define warpX global.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01 +#define warpY global.warpY // Curvature Y + +#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05 +#define c_shape global.c_shape // curvature shape + +#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01 +#define csize global.csize // corner size + +#pragma parameter bsize " Border smoothness" 400.0 100.0 700.0 10.0 +#define bsize global.bsize // border smoothness + +#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0 + +#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01 + +#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0 + +#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 +#define glow params.glow // Glow Strength + +#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05 +#define bloom params.bloom // bloom effect + +#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025 +#define halation params.halation // halation effect + +#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02 +#define gamma_c params.gamma_c // adjust brightness + +#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025 +#define brightboost1 params.brightboost1 // adjust brightness + +#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#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 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 40.0 1.0 +#define scanline2 params.scanline2 // scanline param, vertical sharpness + +#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 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 2.5 0.05 +#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" 0.60 0.0 1.0 0.05 +#define scans params.scans // scanline saturation + +#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0 +#define shadowMask params.shadowMask // Mask Style + +#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05 +#define maskstr params.maskstr // CGWG Mask Strength + +#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 dark color strength + +#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0 +#define masksize params.masksize // Mask Size + +#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 +#define maskDark params.maskDark // Dark "Phosphor" + +#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05 +#define maskLight params.maskLight // Light "Phosphor" + +#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask + +#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 6.0 0.5 +#define slotwidth params.slotwidth // Slot Mask Width + +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.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 mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05 +#define mclip params.mclip // Slot Mask Size + +#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05 +#define gamma_out params.gamma_out // output gamma + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define TEX0 vTexCoord + +#define OutputSize global.OutputSize +#define gl_FragCoord (vTexCoord * OutputSize.xy) + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D LinearizePass; +layout(set = 0, binding = 4) uniform sampler2D BloomPass; +layout(set = 0, binding = 5) uniform sampler2D PrePass; + +#define eps 1e-10 + +float st(float x) +{ + return exp2(-10.0*x*x); +} + +float sw0(float x, float color, float scanline) +{ + float tmp = mix(beam_min, beam_max, color); + float ex = x*tmp; + ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4); + return exp2(-scanline*ex); +} + +float sw1(float x, float color, float scanline) +{ + x = mix (x, beam_min*x, max(x-0.4*color,0.0)); + float tmp = mix(1.2*beam_min, beam_max, color); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +float sw2(float x, float color, float scanline) +{ + float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color); + tmp = mix(beam_max, tmp, pow(x, color+0.3)); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +// Shadow mask (1-4 from PD CRT Lottes shader). + +vec3 Mask(vec2 pos, float mx) +{ + pos = floor(pos/masksize); + vec3 mask = vec3(maskDark, maskDark, maskDark); + vec3 one = vec3(1.0); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 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); + } + + // Phosphor. + else if (shadowMask == 0.0) + { + pos.x = fract(pos.x*0.5); + if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } + else { mask.r = mc; mask.g = 1.0; mask.b = mc; } + } + + // Very compressed TV style shadow mask. + else if (shadowMask == 1.0) + { + float line = maskLight; + float odd = 0.0; + + if (fract(pos.x/6.0) < 0.5) + odd = 1.0; + if (fract((pos.y + odd)/2.0) < 0.5) + line = maskDark; + + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + + mask*=line; + } + + // Aperture-grille. + else if (shadowMask == 2.0) + { + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // VGA style shadow mask. + else if (shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Trinitron mask 5 + else if (shadowMask == 5.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) + { mask.r = 1.0; + 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; + } + + // Trinitron mask 6 + else if (shadowMask == 6.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/3.0); + if (pos.x < 0.333) mask.r = 1.0; + else if (pos.x < 0.666) 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; + } + + // BW Trinitron mask 7 + else if (shadowMask == 7.0) + { + float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = vec3(maskTmp); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) mask = vec3(1.0); + } + + // 4k mask + else + { + 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.rg = 1.0.xx; + else if (pos.x < 0.7) mask.gb = 1.0.xx; + else mask.b = 1.0; + } + + return mask; +} + +float SlotMask(vec2 pos, float m) +{ + if (slotmask == 0.0) return 1.0; + else + { + pos = floor(pos/slotms); + float mlen = slotwidth*2.0; + float px = fract(pos.x/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; + + return slot; + } +} + + +vec3 declip(vec3 c, float b) +{ + float m = max(max(c.r,c.g),c.b); + if (m > b) c = c*b/m; + return c; +} + +vec3 gc(vec3 c) +{ + float mc = max(max(c.r,c.g),c.b); + float mg = pow(mc, 1.0/gamma_c); + return c * mg/(mc + eps); +} + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + +vec2 Overscan(vec2 pos, float dx, float dy){ + pos=pos*2.0-1.0; + pos*=vec2(dx,dy); + return pos*0.5+0.5; +} + +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape); + return pos*0.5 + 0.5; +} + +float humbar(float pos) +{ + if (global.barintensity == 0.0) return 1.0; else + { + pos = (global.barintensity >= 0.0) ? pos : (1.0-pos); + pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0)); + pos = (global.barintensity < 0.0) ? pos : (1.0-pos); + return (1.0-global.barintensity) + global.barintensity*pos; + } +} + +// Borrowed from cgwg's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002))); + coord = (cdist - min(coord,cdist)); + float dist = sqrt(dot(coord,coord)); + return clamp((cdist.x-dist)*bsize,0.0, 1.0); +} + +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.75); + + float SourceY = SourceSize.y; + float sy = 1.0; + if (global.intres == 0.5) sy = SourceY/224.0; else + if (global.intres == 1.0) sy = SourceY/240.0; else + if (global.intres > 1.25) sy = global.intres; + SourceSize*=vec4(1.0, 1.0/sy, 1.0, sy); + + // Calculating texel coordinates + + vec2 texcoord = TEX0.xy; + + if (IOS > 0.0){ + vec2 ofactor = OutputSize.xy/SourceSize.xy; + vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor); + vec2 diff = ofactor/intfactor; + float scan = diff.y; + texcoord = Overscan(texcoord, scan, scan); + if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y); + } + + vec2 pos = Warp(texcoord); + vec2 cpos = (IOS > 2.5) ? TEX0 : texcoord; + float corner0 = corner(Warp(cpos)); + + float coffset = 0.5; + + vec2 ps = SourceSize.zw; + float OGL2Pos = pos.y * SourceSize.y - coffset; + float f = fract(OGL2Pos); + + vec2 dx = vec2(ps.x,0.0); + vec2 dy = vec2(0.0, ps.y); + + // Reading the texels + + vec2 pC4; + + pC4.y = floor(OGL2Pos) * ps.y + 0.5*ps.y; + pC4.x = pos.x; + + if (interb) pC4.y = pos.y; + + vec3 color1 = COMPAT_TEXTURE(Source, pC4 ).rgb; + vec3 scolor1 = COMPAT_TEXTURE(Source, pC4 ).aaa; + + pC4+=dy; + + vec3 color2 = COMPAT_TEXTURE(Source, pC4 ).rgb; + vec3 scolor2 = COMPAT_TEXTURE(Source, pC4 ).aaa; + + // calculating scanlines + + vec3 ctmp; vec3 mcolor; float w3; vec3 color; + vec3 one = vec3(1.0); + +if (!interb) +{ + float shape1 = mix(scanline1, scanline2, f); + float shape2 = mix(scanline1, scanline2, 1.0-f); + + float wt1 = st(f); + float wt2 = st(1.0-f); + + vec3 color00 = color1*wt1 + color2*wt2; + vec3 scolor0 = scolor1*wt1 + scolor2*wt2; + + ctmp = color00/(wt1+wt2); + vec3 sctmp = max(scolor0/(wt1+wt2), ctmp); + mcolor = sctmp; + + float wf1, wf2; + + vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b); + vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b); + + float f1 = f; + float f2 = 1.0-f; + + if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else + if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else + { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);} + + if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; } + + // Scanline saturation application + + vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2); + w3 = wf1+wf2; + + cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001); + cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001); + + w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1); + w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2); + + vec3 cd1 = one; vec3 cd2 = one; 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; + color = min(color, 1.0); +} + + if (interb) + { + color = gc(color1); + mcolor = clamp(mix(color1, scolor1, 1.25), 0.0, 1.0); + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.20/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + float smask = SlotMask(gl_FragCoord.xy * 1.000001, mx); + cmask*= Mask(gl_FragCoord.xy * 1.000001, mx); + + color = color*cmask; + color = min(color,1.0); + color = color*smask; + + cmask = min(cmask*smask, 1.0); + + 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.70); + color*=bb; + + vec3 Glow = COMPAT_TEXTURE(BloomPass, pos ).rgb; + vec3 Bloom = Glow; + 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; + + vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0)); + color = color + bloom*Bloom1; + + color = min(color, mix(one, cmask, mclip)); + if (!interb) color = declip(color, pow(w3,0.60)); + + if (halation > 0.025) { + Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx); + color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; } + + 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; } + + color = min(color, 1.0); + + color = pow(color, vec3(1.0/gamma_out)); + + FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner0); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/crt-guest-advanced-pass2f.slang b/crt/shaders/guest/fast/crt-guest-advanced-pass2f.slang new file mode 100644 index 0000000..8b7ab4c --- /dev/null +++ b/crt/shaders/guest/fast/crt-guest-advanced-pass2f.slang @@ -0,0 +1,633 @@ +#version 450 + +/* + CRT - Guest - Advanced - Fastest - Pass2 + + Copyright (C) 2018-2021 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. + + 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 +{ + float brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size, + glow, shadowMask, masksize, vertmask, slotmask, slotwidth, double_slot, mcut, maskDark, maskLight, + maskstr, inters, bloom, halation, scans, slotms, mclip, gamma_c, gamma_out, DER, DEG, DEB, DES, IOS; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float warpX; + float warpY; + float csize; + float bsize; + float c_shape; + float slotmask1; +} global; + +#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0 +#define IOS params.IOS // Smart Integer Scaling + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01 +#define warpX global.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01 +#define warpY global.warpY // Curvature Y + +#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05 +#define c_shape global.c_shape // curvature shape + +#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01 +#define csize global.csize // corner size + +#pragma parameter bsize " Border smoothness" 400.0 100.0 700.0 10.0 +#define bsize global.bsize // border smoothness + +#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter glow " Glow Strength" 0.08 0.0 2.0 0.01 +#define glow params.glow // Glow Strength + +#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05 +#define bloom params.bloom // bloom effect + +#pragma parameter halation " Halation Strength" 0.0 0.0 1.0 0.025 +#define halation params.halation // halation effect + +#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02 +#define gamma_c params.gamma_c // adjust brightness + +#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025 +#define brightboost1 params.brightboost1 // adjust brightness + +#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#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 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 40.0 1.0 +#define scanline2 params.scanline2 // scanline param, vertical sharpness + +#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 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 2.5 0.05 +#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" 0.60 0.0 1.0 0.05 +#define scans params.scans // scanline saturation + +#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0 +#define shadowMask params.shadowMask // Mask Style + +#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05 +#define maskstr params.maskstr // CGWG Mask Strength + +#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 dark color strength + +#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0 +#define masksize params.masksize // Mask Size + +#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05 +#define maskDark params.maskDark // Dark "Phosphor" + +#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05 +#define maskLight params.maskLight // Light "Phosphor" + +#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask + +#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 6.0 0.5 +#define slotwidth params.slotwidth // Slot Mask Width + +#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.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 mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05 +#define mclip params.mclip // Slot Mask Size + +#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 + +#pragma parameter DEG " Deconvergence Green offset" 0.0 -15.0 15.0 0.5 + +#pragma parameter DEB " Deconvergence Blue offset" 0.0 -15.0 15.0 0.5 + +#pragma parameter DES " Deconvergence Strength" 0.7 0.0 1.0 0.05 + +#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05 +#define gamma_out params.gamma_out // output gamma + +#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize pass, values must match +#define inters params.inters // interlacing effect smoothing + +#define COMPAT_TEXTURE(c,d) texture(c,d) +#define TEX0 vTexCoord + +#define SourceSize global.SourceSize +#define OutputSize global.OutputSize +#define gl_FragCoord (vTexCoord * OutputSize.xy) + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D LinearizePass; +layout(set = 0, binding = 4) uniform sampler2D PrePassDontChange; +layout(set = 0, binding = 5) uniform sampler2D Pass2Feedback; + +#define eps 1e-10 + +float st(float x) +{ + return exp2(-10.0*x*x); +} + +float sw0(float x, float color, float scanline) +{ + float tmp = mix(beam_min, beam_max, color); + float ex = x*tmp; + ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4); + return exp2(-scanline*ex); +} + +float sw1(float x, float color, float scanline) +{ + x = mix (x, beam_min*x, max(x-0.4*color,0.0)); + float tmp = mix(1.2*beam_min, beam_max, color); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +float sw2(float x, float color, float scanline) +{ + float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color); + tmp = mix(beam_max, tmp, pow(x, color+0.3)); + float ex = x*tmp; + return exp2(-scanline*ex*ex); +} + +// Shadow mask (1-4 from PD CRT Lottes shader). + +vec3 Mask(vec2 pos, float mx) +{ + pos = floor(pos/masksize); + vec3 mask = vec3(maskDark, maskDark, maskDark); + vec3 one = vec3(1.0); + float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 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); + } + + // Phosphor. + else if (shadowMask == 0.0) + { + pos.x = fract(pos.x*0.5); + if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; } + else { mask.r = mc; mask.g = 1.0; mask.b = mc; } + } + + // Very compressed TV style shadow mask. + else if (shadowMask == 1.0) + { + float line = maskLight; + float odd = 0.0; + + if (fract(pos.x/6.0) < 0.5) + odd = 1.0; + if (fract((pos.y + odd)/2.0) < 0.5) + line = maskDark; + + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + + mask*=line; + } + + // Aperture-grille. + else if (shadowMask == 2.0) + { + pos.x = fract(pos.x/3.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // VGA style shadow mask. + else if (shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x/6.0); + + if (pos.x < 0.333) mask.r = maskLight; + else if (pos.x < 0.666) mask.g = maskLight; + else mask.b = maskLight; + } + + // Trinitron mask 5 + else if (shadowMask == 5.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) + { mask.r = 1.0; + 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; + } + + // Trinitron mask 6 + else if (shadowMask == 6.0) + { + mask = vec3(0.0); + pos.x = fract(pos.x/3.0); + if (pos.x < 0.333) mask.r = 1.0; + else if (pos.x < 0.666) 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; + } + + // BW Trinitron mask 7 + else if (shadowMask == 7.0) + { + float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate; + mask = vec3(maskTmp); + pos.x = fract(pos.x/2.0); + if (pos.x < 0.5) mask = vec3(1.0); + } + + // 4k mask + else + { + 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.rg = 1.0.xx; + else if (pos.x < 0.7) mask.gb = 1.0.xx; + else mask.b = 1.0; + } + + return mask; +} + +float SlotMask(vec2 pos, float m) +{ + if (slotmask == 0.0) return 1.0; + else + { + pos = floor(pos/slotms); + float mlen = slotwidth*2.0; + float px = fract(pos.x/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; + + return slot; + } +} + + +vec3 declip(vec3 c, float b) +{ + float m = max(max(c.r,c.g),c.b); + if (m > b) c = c*b/m; + return c; +} + +vec3 gc(vec3 c) +{ + float mc = max(max(c.r,c.g),c.b); + float mg = pow(mc, 1.0/gamma_c); + return c * mg/(mc + eps); +} + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + +vec2 Overscan(vec2 pos, float dx, float dy){ + pos=pos*2.0-1.0; + pos*=vec2(dx,dy); + return pos*0.5+0.5; +} + +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape); + return pos*0.5 + 0.5; +} + +// Borrowed from cgwg's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002))); + coord = (cdist - min(coord,cdist)); + float dist = sqrt(dot(coord,coord)); + return clamp((cdist.x-dist)*bsize,0.0, 1.0); +} + +vec3 calculate_bloom (vec2 pos, vec2 x, vec2 y) +{ + return ( COMPAT_TEXTURE(LinearizePass, pos -x -y).rgb * 0.091849 + + COMPAT_TEXTURE(LinearizePass, pos -y).rgb * 0.119368 + + COMPAT_TEXTURE(LinearizePass, pos +x -y).rgb * 0.091849 + + COMPAT_TEXTURE(LinearizePass, pos -x ).rgb * 0.119368 + + COMPAT_TEXTURE(LinearizePass, pos ).rgb * 0.155131 + + COMPAT_TEXTURE(LinearizePass, pos +x ).rgb * 0.119368 + + COMPAT_TEXTURE(LinearizePass, pos -x +y).rgb * 0.091849 + + COMPAT_TEXTURE(LinearizePass, pos +y).rgb * 0.119368 + + COMPAT_TEXTURE(LinearizePass, pos +x +y).rgb * 0.091849 ); +} + +void main() +{ + float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a; + bool interb = (intera < 0.75); + vec4 result = COMPAT_TEXTURE(Pass2Feedback, vTexCoord); + + vec2 texcoord = TEX0.xy; + + if (IOS > 0.0){ + vec2 ofactor = OutputSize.xy/SourceSize.xy; + vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor); + vec2 diff = ofactor/intfactor; + float scan = diff.y; + texcoord = Overscan(texcoord, scan, scan); + if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y); + } + + vec2 yy = vec2(0.0, global.OriginalSize.w); + vec2 xx = vec2(global.OriginalSize.z, 0.0); + vec2 y2 = yy+yy; + vec2 pos = Warp(texcoord); + vec2 pc4 = pos; + pc4 = floor(pc4 * global.OriginalSize.xy - vec2(0.0, 0.5)) * global.OriginalSize.zw + 0.5*global.OriginalSize.zw; + + float same2 = COMPAT_TEXTURE(PrePassDontChange,pc4-yy).a; + float same3 = COMPAT_TEXTURE(PrePassDontChange,pc4 ).a; + float same4 = COMPAT_TEXTURE(PrePassDontChange,pc4+yy).a; + float same5 = COMPAT_TEXTURE(PrePassDontChange,pc4+y2).a; + + float refresh1 = 30.0; + float refresh2 = round(TEX0.y*29.0); + + bool frames = (floor(mod(float(global.FrameCount), refresh1)) == refresh2); + bool not_same = (same2 + same3 + same4 + same5) > 0.25; + +if ( not_same || frames || interb ) + +{ + + float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a; + + // Calculating texel coordinates + + vec2 cpos = (IOS > 2.5) ? TEX0 : texcoord; + float corner0 = corner(Warp(cpos)); + + float coffset = 0.5; + + vec2 ps = SourceSize.zw; + float OGL2Pos = pos.y * SourceSize.y - coffset; + float f = fract(OGL2Pos); + + vec2 dx = vec2(ps.x,0.0); + vec2 dy = vec2(0.0, ps.y); + + // Reading the texels + + vec2 pC4; + + pC4.y = floor(OGL2Pos) * ps.y + 0.5*ps.y; + pC4.x = pos.x; + + if (interb) pC4.y = pos.y - inters * SourceSize.w; + + vec3 color1 = COMPAT_TEXTURE(Source, pC4 ).rgb; + vec3 dcolor1 = color1; + dcolor1.r = COMPAT_TEXTURE(Source, pC4 + dx*params.DER).r; + dcolor1.g = COMPAT_TEXTURE(Source, pC4 + dx*params.DEG).g; + dcolor1.b = COMPAT_TEXTURE(Source, pC4 + dx*params.DEB).b; + color1 = mix(color1, dcolor1, params.DES); + + vec3 scolor1 = COMPAT_TEXTURE(Source, pC4 ).aaa; + + if (interb) pC4.y = pos.y + inters * SourceSize.w; else + pC4+=dy; + + vec3 color2 = COMPAT_TEXTURE(Source, pC4 ).rgb; + vec3 dcolor2 = color2; + dcolor2.r = COMPAT_TEXTURE(Source, pC4 + dx*params.DER).r; + dcolor2.g = COMPAT_TEXTURE(Source, pC4 + dx*params.DEG).g; + dcolor2.b = COMPAT_TEXTURE(Source, pC4 + dx*params.DEB).b; + color2 = mix(color2, dcolor2, params.DES); + + vec3 scolor2 = COMPAT_TEXTURE(Source, pC4 ).aaa; + + // calculating scanlines + + vec3 ctmp; vec3 mcolor; float w3; vec3 color; + vec3 one = vec3(1.0); + +if (!interb) +{ + float shape1 = mix(scanline1, scanline2, f); + float shape2 = mix(scanline1, scanline2, 1.0-f); + + float wt1 = st(f); + float wt2 = st(1.0-f); + + vec3 color00 = color1*wt1 + color2*wt2; + vec3 scolor0 = scolor1*wt1 + scolor2*wt2; + + ctmp = color00/(wt1+wt2); + vec3 sctmp = max(scolor0/(wt1+wt2), ctmp); + mcolor = sctmp; + + float wf1, wf2; + + vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b); + vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b); + + float f1 = f; + float f2 = 1.0-f; + + if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else + if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else + { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);} + + if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; } + + // Scanline saturation application + + vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2); + w3 = wf1+wf2; + + cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001); + cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001); + + w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1); + w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2); + + vec3 cd1 = one; vec3 cd2 = one; 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; + color = min(color, 1.0); +} + + if (interb) + { + color = gc(0.5*(color1+color2)); + mcolor = clamp(mix(color1, scolor1, 1.25), 0.0, 1.0); + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.20/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + float smask = SlotMask(gl_FragCoord.xy * 1.000001, mx); + cmask*= Mask(gl_FragCoord.xy * 1.000001, mx); + + color = color*cmask; + color = min(color,1.0); + color = color*smask; + + cmask = min(cmask*smask, 1.0); + + 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); + float maxb = max(max(Glow.r, Glow.g),Glow.b); + Glow = pow(Glow, 1.4.xxx); + vec3 Bloom = Glow; + + vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0)); + color = color + bloom*Bloom1; + + color = min(color, mix(one, cmask, mclip)); + if (!interb) color = declip(color, pow(w3,0.60)); + + if (halation > 0.025) { + Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx); + color = color + 0.75*(0.75+maxb)*Bloom*(0.4+sqrt(colmx))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; } + + Glow = mix(Glow, 0.25*color, 0.7*colmx); + color = color + 0.5*glow*Glow; + + color = pow(color, vec3(1.0/gamma_out)); + color = min(color, 1.0); + + result = vec4(color*corner0, corner0); +} + FragColor = result; +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/deconvergence-f.slang b/crt/shaders/guest/fast/deconvergence-f.slang new file mode 100644 index 0000000..dac9614 --- /dev/null +++ b/crt/shaders/guest/fast/deconvergence-f.slang @@ -0,0 +1,176 @@ +#version 450 + +/* + CRT - Guest - Advanced - Deconvergence pass (NTSC) + noise + + Copyright (C) 2021 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 OutputSize; + uint FrameCount; + float decons; + float addnoised; + float noiseresd; + float deconrr; + float deconrg; + float deconrb; + float deconrry; + float deconrgy; + float deconrby; + float dctypex; + float dctypey; +} params; + +#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0 + +#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05 + +#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05 + +#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -12.0 12.0 0.25 + +#pragma parameter decons " Deconvergence Strength (and Type)" 0.5 -4.0 4.0 0.10 +#define decons params.decons // Horizontal deconvergence colors strength + +#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02 +#define addnoised params.addnoised // add noise + +#pragma parameter noiseresd " Noise Resolution" 2.0 0.0 10.0 1.0 +#define noiseresd params.noiseresd // add noise + + +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) + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + +// noise function: +// Dedicated to the public domain. +// If you want a real license, you may consider this MIT/BSD/CC0/WTFPL-licensed (take your pick). +// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz + +vec3 noise(vec3 v){ + if (addnoised < 0.0) v.z = -addnoised; else v.z = v.z/6000.0; + // ensure reasonable range + v = fract(v) + fract(v*1e4) + fract(v*1e-4); + // seed + v += vec3(0.12345, 0.6789, 0.314159); + // more iterations => more random + v = fract(v*dot(v, v)*123.456); + v = fract(v*dot(v, v)*123.456); + v = fract(v*dot(v, v)*123.456); + return v; +} + +void main() +{ + + vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb; + vec3 result = color; + + if ((abs(params.deconrr) + abs(params.deconrg) + abs(params.deconrb) + abs(params.deconrry) + abs(params.deconrgy) + abs(params.deconrby)) > 0.20) + { + float stepx = params.OutputSize.z; + float stepy = params.OutputSize.w; + + vec2 dx = vec2(stepx, 0.0); + vec2 dy = vec2(0.0, stepy); + + float ds = decons; + + float posx = 2.0*vTexCoord.x - 1.0; + float posy = 2.0*vTexCoord.y - 1.0; + + if (params.dctypex > 0.025) + { + posx = sign(posx)*pow(abs(posx), 1.05-params.dctypex); + dx = posx * dx; + } + + if (params.dctypey > 0.025) + { + + posy = sign(posy)*pow(abs(posy), 1.05-params.dctypey); + dy = posy * dy; + } + + if (params.dctypex > 0.025 || params.dctypey > 0.025) ds *= sqrt(posx*posx*sign(params.dctypex) + posy*posy*sign(params.dctypey)); + + vec2 rc = params.deconrr * dx + params.deconrry*dy; + vec2 gc = params.deconrg * dx + params.deconrgy*dy; + vec2 bc = params.deconrb * dx + params.deconrby*dy; + + float r = COMPAT_TEXTURE(Source, vTexCoord + rc ).r; + float g = COMPAT_TEXTURE(Source, vTexCoord + gc ).g; + float b = COMPAT_TEXTURE(Source, vTexCoord + bc ).b; + + result = vec3(r,g,b); + + vec3 dcolor = max(max(COMPAT_TEXTURE(Source, vTexCoord + dx).rgb, COMPAT_TEXTURE(Source, vTexCoord - dx).rgb), color); + + float mc = max(max(dcolor.r, dcolor.g), dcolor.b); + if (decons < 0.0) mc = 0.9; + float dclamp = min(2.0-0.40*abs(ds),1.0); + + result = clamp(mix(color, sqrt(mix(result*result, color*result, sqrt(mc))), abs(ds)), dclamp*min(result,color), min(1.0/dclamp*max(result, color),1.0)); + } + + float rc = 0.6*sqrt(max(max(result.r, result.g), result.b))+0.4; + + if (abs(addnoised) > 0.01) result = mix(result, noise(vec3(floor(params.OutputSize.xy * vTexCoord / noiseresd), float(params.FrameCount))), 0.25*abs(addnoised) * rc); + + float corner = COMPAT_TEXTURE(Source, vTexCoord).a; + + FragColor = vec4(result*corner, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/linearize.slang b/crt/shaders/guest/fast/linearize.slang new file mode 100644 index 0000000..2a21a03 --- /dev/null +++ b/crt/shaders/guest/fast/linearize.slang @@ -0,0 +1,176 @@ +#version 450 + +/* + Interlacing + + 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 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float GAMMA_INPUT; + float inter; + float interm; + float iscan; + float intres; + float iscans; + float downsample_levelx; + float downsample_levely; + float prescalex; +} params; + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + vec4 SourceSize; + mat4 MVP; +} global; + + +#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05 +#define GAMMA_INPUT params.GAMMA_INPUT + +#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0 + +#pragma parameter inter " Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0 +#define inter params.inter // interlace resolution + +#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 +#define iscan params.iscan // interlacing effect scanlining + +#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match + +#define intres params.intres // interlace resolution + +#pragma parameter downsample_levelx " Downsampling-X (High-res content, pre-scalers)" 0.0 0.0 2.0 0.05 +#define downsample_levelx params.downsample_levelx // downsample level + +#pragma parameter downsample_levely " Downsampling-Y (High-res content, pre-scalers)" 0.0 0.0 2.0 0.05 +#define downsample_levely params.downsample_levely // downsample level + +#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match +#define prescalex params.prescalex // prescale-x factor + +#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05 +#define iscans params.iscans // interlace saturation + +#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 * 1.000001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D PrePass; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + + +vec3 fetch_pixel(vec2 coord) +{ + vec2 dx = vec2(global.SourceSize.z, 0.0) * downsample_levelx; + vec2 dy = vec2(0.0, global.SourceSize.w) * downsample_levely; + vec2 d1 = dx + dy; + vec2 d2 = dx - dy; + + float sum = 15.0; + vec3 result = 3.0*COMPAT_TEXTURE(PrePass, coord ).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dx).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord + dy).rgb + + 2.0*COMPAT_TEXTURE(PrePass, coord - dy).rgb + + COMPAT_TEXTURE(PrePass, coord + d1).rgb + + COMPAT_TEXTURE(PrePass, coord - d1).rgb + + COMPAT_TEXTURE(PrePass, coord + d2).rgb + + COMPAT_TEXTURE(PrePass, coord - d2).rgb; + + return result/sum; +} + + +void main() +{ + vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb; + vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, params.OriginalSize.w)).rgb; + + if ((downsample_levelx + downsample_levely) > 0.025) + { + c1 = fetch_pixel(vTexCoord); + c2 = fetch_pixel(vTexCoord + vec2(0.0, params.OriginalSize.w)); + } + + vec3 c = c1; + + float intera = 1.0; + float gamma_in = clamp(GAMMA_INPUT, 1.0, 5.0); + + float m1 = max(max(c1.r,c1.g),c1.b); + float m2 = max(max(c2.r,c2.g),c2.b); + vec3 df = abs(c1-c2); + + float d = max(max(df.r,df.g),df.b); + if (interm == 2.0) d = mix(0.1*d,10.0*d, step(m1/(m2+0.0001),m2/(m1+0.0001))); + + float r = m1; + + float yres_div = 1.0; if (intres > 1.25) yres_div = intres; + + if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5) + { + intera = 0.5; + float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0); + float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0); + float ii = abs(line_no-frame_no); + + if (interm < 3.5) + { + c2 = plant(mix(c2, c2*c2, iscans), max(max(c2.r,c2.g),c2.b)); + r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0); + 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); + intera = 0.0; + } + if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); + 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));} + } + c = pow(c, vec3(gamma_in)); + + if (vTexCoord.x > 0.5) gamma_in = intera; else gamma_in = 1.0/gamma_in; + + FragColor = vec4(c, gamma_in); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/linearizef.slang b/crt/shaders/guest/fast/linearizef.slang new file mode 100644 index 0000000..bba8cce --- /dev/null +++ b/crt/shaders/guest/fast/linearizef.slang @@ -0,0 +1,129 @@ +#version 450 + +/* + Interlacing + + 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 OriginalSize; + vec4 OutputSize; + vec4 SourceSize; + uint FrameCount; + float GAMMA_INPUT; + float inter; + float interm; + float inters; + float iscan; +} params; + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + + +#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05 +#define GAMMA_INPUT params.GAMMA_INPUT + +#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0 + +#pragma parameter inter " Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0 +#define inter params.inter // interlace resolution + +#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 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 +#define iscan params.iscan // interlacing effect scanlining + + +#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 * 1.000001; +} + +#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) +#define SourceSize params.SourceSize + + +vec3 plant (vec3 tar, float r) +{ + float t = max(max(tar.r,tar.g),tar.b) + 0.00001; + return tar * r / t; +} + + +void main() +{ + vec3 c1 = COMPAT_TEXTURE(Source, vTexCoord).rgb; + vec3 c2 = COMPAT_TEXTURE(Source, vTexCoord + vec2(0.0, 1.0/params.OriginalSize.y)).rgb; + vec3 c = c1; + + float intera = 1.0; + float gamma_in = clamp(GAMMA_INPUT, 1.0, 5.0); + + float m1 = max(max(c1.r,c1.g),c1.b); + float m2 = max(max(c2.r,c2.g),c2.b); + vec3 df = abs(c1-c2); + + float d = max(max(df.r,df.g),df.b); + if (interm == 2.0) d = mix(0.1*d,10.0*d, step(m1/(m2+0.0001),m2/(m1+0.0001))); + + float r = m1; + + if (inter <= params.OriginalSize.y && interm > 0.5) + { + intera = 0.5; + float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0); + float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0); + float ii = abs(line_no-frame_no); + + if (interm < 3.5) + { + r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0); + 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); + intera = 0.0; + } + if (interm == 5.0) { c = mix(c2, c1, 0.5); } + } + c = pow(c, vec3(gamma_in)); + + if (vTexCoord.x > 0.5) gamma_in = intera; else gamma_in = 1.0/gamma_in; + + FragColor = vec4(c, gamma_in); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/pre-shaders.slang b/crt/shaders/guest/fast/pre-shaders.slang new file mode 100644 index 0000000..e68dd01 --- /dev/null +++ b/crt/shaders/guest/fast/pre-shaders.slang @@ -0,0 +1,349 @@ +#version 450 + +/* + CRT Advanced color altering + + Copyright (C) 2019-2021 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 + 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 TNTC; + float LS; + float LUTLOW, LUTBR; + float CP, CS; + float BP; + float WP; + float wp_saturation; + float vigstr; + float vigdef; + float sega_fix; + float pre_bb; +} params; + +#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter CS " Display Gamut: sRGB, Modern, DCI, Adobe, Rec.2020" 0.0 0.0 4.0 1.0 + +#pragma parameter CP " CRT Profile: EBU | P22 | SMPTE-C | Philips | Trin." 0.0 -1.0 5.0 1.0 + +#define CP params.CP +#define CS params.CS + +#pragma parameter TNTC " LUT Colors: Trin. | invTrin. | 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 +#define LS params.LS + +#define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons + +#define LUTBR 1.0 // "Fix LUT Brightness" from 0.0 to 1.0 + +#pragma parameter WP " Color Temperature %" 0.0 -100.0 100.0 5.0 + +#pragma parameter wp_saturation " Saturation Adjustment" 1.0 0.0 2.0 0.05 + +#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01 + +#define WP params.WP +#define wp_saturation params.wp_saturation + +#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0 + +#pragma parameter BP " Raise Black Level" 0.0 0.0 25.0 1.0 +#define BP params.BP + +#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.025 + +#pragma parameter vigdef " Vignette Definition" 7.0 0.4 15.0 0.2 + + +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; +layout(set = 0, binding = 3) uniform sampler2D SamplerLUT1; +layout(set = 0, binding = 4) uniform sampler2D SamplerLUT2; +layout(set = 0, binding = 5) uniform sampler2D SamplerLUT3; +layout(set = 0, binding = 6) uniform sampler2D SamplerLUT4; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + + +// Color profile matrices + +const mat3 Profile0 = +mat3( + 0.412391, 0.212639, 0.019331, + 0.357584, 0.715169, 0.119195, + 0.180481, 0.072192, 0.950532 +); + +const mat3 Profile1 = +mat3( + 0.430554, 0.222004, 0.020182, + 0.341550, 0.706655, 0.129553, + 0.178352, 0.071341, 0.939322 +); + +const mat3 Profile2 = +mat3( + 0.396686, 0.210299, 0.006131, + 0.372504, 0.713766, 0.115356, + 0.181266, 0.075936, 0.967571 +); + +const mat3 Profile3 = +mat3( + 0.393521, 0.212376, 0.018739, + 0.365258, 0.701060, 0.111934, + 0.191677, 0.086564, 0.958385 +); + +const mat3 Profile4 = +mat3( + 0.392258, 0.209410, 0.016061, + 0.351135, 0.725680, 0.093636, + 0.166603, 0.064910, 0.850324 +); + +const mat3 Profile5 = +mat3( + 0.377923, 0.195679, 0.010514, + 0.317366, 0.722319, 0.097826, + 0.207738, 0.082002, 1.076960 +); + +const mat3 ToSRGB = +mat3( + 3.240970, -0.969244, 0.055630, +-1.537383, 1.875968, -0.203977, +-0.498611, 0.041555, 1.056972 +); + +const mat3 ToModern = +mat3( + 2.791723, -0.894766, 0.041678, +-1.173165, 1.815586, -0.130886, +-0.440973, 0.032000, 1.002034 +); + +const mat3 ToDCI = +mat3( + 2.493497, -0.829489, 0.035846, +-0.931384, 1.762664, -0.076172, +-0.402711, 0.023625, 0.956885 +); + +const mat3 ToAdobe = +mat3( + 2.041588, -0.969244, 0.013444, +-0.565007, 1.875968, -0.11836, +-0.344731, 0.041555, 1.015175 +); + +const mat3 ToREC = +mat3( + 1.716651, -0.666684, 0.017640, +-0.355671, 1.616481, -0.042771, +-0.253366, 0.015769, 0.942103 +); + +// Color temperature matrices + +const mat3 D65_to_D55 = mat3 ( + 0.4850339153, 0.2500956126, 0.0227359648, + 0.3488957224, 0.6977914447, 0.1162985741, + 0.1302823568, 0.0521129427, 0.6861537456); + + +const mat3 D65_to_D93 = mat3 ( + 0.3683017655, 0.1899055978, 0.0172641453, + 0.3555467892, 0.7110935785, 0.1185155964, + 0.2475020592, 0.0990008237, 1.3035108450); + + +vec3 fix_lut(vec3 lutcolor, vec3 ref) +{ + float r = length(ref); + float l = length(lutcolor); + float m = max(max(ref.r,ref.g),ref.b); + ref = normalize(lutcolor + 0.0000001) * mix(r, l, pow(m,1.25)); + return mix(lutcolor, ref, LUTBR); +} + +vec2 ctransform (vec2 inputc) +{ + return vec2( inputc.x * sqrt(1.0 - 0.5*inputc.y*inputc.y), inputc.y * sqrt(1.0 - 0.5*inputc.x*inputc.x)); +} + +float vignette (vec2 coords) +{ + vec2 ccoords = ctransform(2.0*(coords-0.5)); + ccoords = ccoords * ccoords; + float vstr = sqrt(ccoords.x+ccoords.y); + vstr = pow(vstr, params.vigdef); + return max(mix(1.0, 1.0-vstr, params.vigstr), 0.0); +} + +void main() +{ + vec4 imgColor = COMPAT_TEXTURE(Source, vTexCoord.xy); + + float w = float ((imgColor.r + imgColor.g + imgColor.b) < 1.5/255.0); + float bp = w * BP/255.0; + + imgColor.rgb = imgColor.rgb * params.pre_bb; + + if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0); + + imgColor.rgb = min(imgColor.rgb, 1.0); + + vec3 color = imgColor.rgb; + + if (int(TNTC) == 0) + { + color.rgb = imgColor.rgb; + } + else + { + float lutlow = LUTLOW/255.0; float invLS = 1.0/LS; + vec3 lut_ref = imgColor.rgb + lutlow*(1.0 - pow(imgColor.rgb, 0.333.xxx)); + float lutb = lut_ref.b * (1.0-0.5*invLS); + lut_ref.rg = lut_ref.rg * (1.0-invLS) + 0.5*invLS; + float tile1 = ceil (lutb * (LS-1.0)); + float tile0 = max(tile1 - 1.0, 0.0); + float f = fract(lutb * (LS-1.0)); if (f == 0.0) f = 1.0; + vec2 coord0 = vec2(tile0 + lut_ref.r, lut_ref.g)*vec2(invLS, 1.0); + vec2 coord1 = vec2(tile1 + lut_ref.r, lut_ref.g)*vec2(invLS, 1.0); + vec4 color1, color2, res; + + if (int(TNTC) == 1) + { + color1 = COMPAT_TEXTURE(SamplerLUT1, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT1, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 2) + { + color1 = COMPAT_TEXTURE(SamplerLUT2, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT2, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 3) + { + color1 = COMPAT_TEXTURE(SamplerLUT3, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT3, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 4) + { + color1 = COMPAT_TEXTURE(SamplerLUT4, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT4, coord1); + res = mix(color1, color2, f); + } + + if (imgColor.r == 0.0) res.r = 0.0; + if (imgColor.g == 0.0) res.g = 0.0; + if (imgColor.b == 0.0) res.b = 0.0; + + res.rgb = fix_lut (res.rgb, imgColor.rgb); + + color = mix(imgColor.rgb, res.rgb, min(TNTC,1.0)); + } + + vec3 c = clamp(color, 0.0, 1.0); + + float p; + mat3 m_out; + + if (CS == 0.0) { p = 2.2; m_out = ToSRGB; } else + if (CS == 1.0) { p = 2.2; m_out = ToModern; } else + if (CS == 2.0) { p = 2.6; m_out = ToDCI; } else + if (CS == 3.0) { p = 2.2; m_out = ToAdobe; } else + if (CS == 4.0) { p = 2.4; m_out = ToREC; } + + color = pow(c, vec3(p)); + + mat3 m_in = Profile0; + + if (CP == 0.0) { m_in = Profile0; } else + if (CP == 1.0) { m_in = Profile1; } else + if (CP == 2.0) { m_in = Profile2; } else + if (CP == 3.0) { m_in = Profile3; } else + if (CP == 4.0) { m_in = Profile4; } else + if (CP == 5.0) { m_in = Profile5; } + + color = m_in*color; + color = m_out*color; + + color = clamp(color, 0.0, 1.0); + + color = pow(color, vec3(1.0/p)); + + if (CP == -1.0) color = c; + + vec3 scolor1 = normalize(pow(color + 0.000000001, vec3(wp_saturation)))*length(color); + float luma = dot(color, vec3(0.2126, 0.7152, 0.0722)); + vec3 scolor2 = mix(vec3(luma), color, wp_saturation); + color = (wp_saturation > 1.0) ? scolor1 : scolor2; + + p = 2.2; + + color = pow(color, vec3(p)); + + color = clamp(color, 0.0, 1.0); + + vec3 warmer = D65_to_D55*color; + warmer = ToSRGB*warmer; + + vec3 cooler = D65_to_D93*color; + cooler = ToSRGB*cooler; + + float m = abs(WP)/100.0; + + vec3 comp = (WP < 0.0) ? cooler : warmer; + + color = mix(color, comp, m); + color = pow(max(color, 0.0), vec3(1.0/p)); + + color = color + bp; + + FragColor = vec4(color, vignette(vTexCoord.xy)); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/pre-shadersf.slang b/crt/shaders/guest/fast/pre-shadersf.slang new file mode 100644 index 0000000..bc2ebe7 --- /dev/null +++ b/crt/shaders/guest/fast/pre-shadersf.slang @@ -0,0 +1,265 @@ +#version 450 + +/* + CRT Advanced color altering + + Copyright (C) 2019-2021 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 + 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 TNTC; + float LS; + float LUTLOW, LUTBR; + float WP; + float wp_saturation; + float BP; + float vigstr; + float vigdef; + float sega_fix; + float pre_bb; +} params; + +#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter TNTC " LUT Colors: Trin. | invTrin. | 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 +#define LS params.LS + +#define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons + +#define LUTBR 1.0 // "Fix LUT Brightness" from 0.0 to 1.0 + +#pragma parameter WP " Color Temperature %" 0.0 -100.0 100.0 5.0 +#pragma parameter wp_saturation " Saturation Adjustment" 1.0 0.0 2.0 0.05 +#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01 + +#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0 + +#pragma parameter BP " Raise Black Level" 0.0 0.0 25.0 1.0 + +#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.025 + +#pragma parameter vigdef " Vignette Definition" 7.0 0.4 15.0 0.2 + + +#define WP params.WP +#define wp_saturation params.wp_saturation +#define BP params.BP + + +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; + +#define gl_FragCoord (vTexCoord * params.OutputSize.xy) + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.00001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D SamplerLUT1; +layout(set = 0, binding = 4) uniform sampler2D SamplerLUT2; +layout(set = 0, binding = 5) uniform sampler2D SamplerLUT3; +layout(set = 0, binding = 6) uniform sampler2D SamplerLUT4; +layout(set = 0, binding = 7) uniform sampler2D OriginalHistory0; +layout(set = 0, binding = 8) uniform sampler2D OriginalHistory1; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + + +// Color profile matrices + +const mat3 ToSRGB = +mat3( + 3.240970, -0.969244, 0.055630, +-1.537383, 1.875968, -0.203977, +-0.498611, 0.041555, 1.056972 +); + + +// Color temperature matrices + +const mat3 D65_to_D55 = mat3 ( + 0.4850339153, 0.2500956126, 0.0227359648, + 0.3488957224, 0.6977914447, 0.1162985741, + 0.1302823568, 0.0521129427, 0.6861537456); + + +const mat3 D65_to_D93 = mat3 ( + 0.3683017655, 0.1899055978, 0.0172641453, + 0.3555467892, 0.7110935785, 0.1185155964, + 0.2475020592, 0.0990008237, 1.3035108450); + + +vec3 fix_lut(vec3 lutcolor, vec3 ref) +{ + float r = length(ref); + float l = length(lutcolor); + float m = max(max(ref.r,ref.g),ref.b); + ref = normalize(lutcolor + 0.0000001) * mix(r, l, pow(m,1.25)); + return mix(lutcolor, ref, LUTBR); +} + +vec2 ctransform (vec2 inputc) +{ + return vec2( inputc.x * sqrt(1.0 - 0.5*inputc.y*inputc.y), inputc.y * sqrt(1.0 - 0.5*inputc.x*inputc.x)); +} + +float vignette (vec2 coords) +{ + vec2 ccoords = ctransform(2.0*(coords-0.5)); + ccoords = ccoords * ccoords; + float vstr = sqrt(ccoords.x+ccoords.y); + vstr = pow(vstr, params.vigdef); + return max(mix(1.0, 1.0-vstr, params.vigstr), 0.0); +} + + +void main() +{ + vec4 imgColor = COMPAT_TEXTURE(Source, vTexCoord.xy); + + float w = float ((imgColor.r + imgColor.g + imgColor.b) < 1.5/255.0); + + float bp = w * BP/255.0; + + imgColor.rgb = imgColor.rgb * params.pre_bb; + + if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0); + + imgColor.rgb = min(imgColor.rgb, 1.0); + + vec3 color = imgColor.rgb; + + if (int(TNTC) == 0) + { + color.rgb = imgColor.rgb; + } + else + { + float lutlow = LUTLOW/255.0; float invLS = 1.0/LS; + vec3 lut_ref = imgColor.rgb + lutlow*(1.0 - pow(imgColor.rgb, 0.333.xxx)); + float lutb = lut_ref.b * (1.0-0.5*invLS); + lut_ref.rg = lut_ref.rg * (1.0-invLS) + 0.5*invLS; + float tile1 = ceil (lutb * (LS-1.0)); + float tile0 = max(tile1 - 1.0, 0.0); + float f = fract(lutb * (LS-1.0)); if (f == 0.0) f = 1.0; + vec2 coord0 = vec2(tile0 + lut_ref.r, lut_ref.g)*vec2(invLS, 1.0); + vec2 coord1 = vec2(tile1 + lut_ref.r, lut_ref.g)*vec2(invLS, 1.0); + vec4 color1, color2, res; + + if (int(TNTC) == 1) + { + color1 = COMPAT_TEXTURE(SamplerLUT1, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT1, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 2) + { + color1 = COMPAT_TEXTURE(SamplerLUT2, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT2, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 3) + { + color1 = COMPAT_TEXTURE(SamplerLUT3, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT3, coord1); + res = mix(color1, color2, f); + } + else if (int(TNTC) == 4) + { + color1 = COMPAT_TEXTURE(SamplerLUT4, coord0); + color2 = COMPAT_TEXTURE(SamplerLUT4, coord1); + res = mix(color1, color2, f); + } + + res.rgb = fix_lut (res.rgb, imgColor.rgb); + + color = mix(imgColor.rgb, res.rgb, min(TNTC,1.0)); + } + + vec3 c = clamp(color, 0.0, 1.0); + + vec3 scolor1 = normalize(pow(color + 0.000000001, vec3(wp_saturation)))*length(color); + float luma = dot(color, vec3(0.2126, 0.7152, 0.0722)); + vec3 scolor2 = mix(vec3(luma), color, wp_saturation); + color = (wp_saturation > 1.0) ? scolor1 : scolor2; + + float p = 2.2; + + color = pow(color, vec3(p)); + + color = clamp(color, 0.0, 1.0); + + vec3 warmer = D65_to_D55*color; + warmer = ToSRGB*warmer; + + vec3 cooler = D65_to_D93*color; + cooler = ToSRGB*cooler; + + float m = abs(WP)/100.0; + + vec3 comp = (WP < 0.0) ? cooler : warmer; + + color = mix(color, comp, m); + color = pow(max(color, 0.0), vec3(1.0/p)); + + color = color + bp; + + vec2 dx = vec2(params.SourceSize.z, 0.0); + vec2 x2 = 2.5 *dx; + vec2 xx = dx + dx; + vec2 x3 = x2 + dx; + vec2 pC4 = vTexCoord; + + vec3 ol3 = COMPAT_TEXTURE(OriginalHistory1, pC4 -x2).rgb; + vec3 ol2 = COMPAT_TEXTURE(OriginalHistory1, pC4 -dx).rgb; + vec3 ol1 = COMPAT_TEXTURE(OriginalHistory1, pC4 ).rgb; + vec3 or1 = COMPAT_TEXTURE(OriginalHistory1, pC4 +dx).rgb; + vec3 or2 = COMPAT_TEXTURE(OriginalHistory1, pC4 +xx).rgb; + + vec3 cl3 = COMPAT_TEXTURE(OriginalHistory0, pC4 -x2).rgb; + vec3 cl2 = COMPAT_TEXTURE(OriginalHistory0, pC4 -dx).rgb; + vec3 cl1 = COMPAT_TEXTURE(OriginalHistory0, pC4 ).rgb; + vec3 cr1 = COMPAT_TEXTURE(OriginalHistory0, pC4 +dx).rgb; + vec3 cr2 = COMPAT_TEXTURE(OriginalHistory0, pC4 +xx).rgb; + + vec3 res = abs(ol3-cl3) + abs(ol2-cl2) + abs(ol1-cl1) + abs(or1-cr1) + abs(or2-cr2); + float res1 = 1.0; + if ((res.r+res.g+res.b) == 0.0) res1 = 0.0; + FragColor = vec4(color * vignette(vTexCoord.xy), res1); +} \ No newline at end of file diff --git a/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang b/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang index 4f08010..4a52a2a 100644 --- a/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang +++ b/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang @@ -3,6 +3,7 @@ // NTSC-Adaptive // based on Themaister's NTSC shader + layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; @@ -10,14 +11,17 @@ layout(std140, set = 0, binding = 0) uniform UBO vec4 OriginalSize; vec4 SourceSize; uint FrameCount; - float quality, ntsc_sat, cust_fringing, cust_artifacting, ntsc_bright; + float quality, ntsc_sat, cust_fringing, cust_artifacting, ntsc_bright, ntsc_scale, ntsc_fields, ntsc_phase; } global; -#pragma parameter quality "Presets (Svideo=0 Composite=1 RF=2 Custom=-1)" 0.0 -1.0 2.0 1.0 -#pragma parameter ntsc_sat "Color Saturation" 1.0 0.0 2.0 0.01 -#pragma parameter ntsc_bright "Brightness" 1.0 0.0 1.5 0.01 -#pragma parameter cust_fringing "Custom Fringing Value" 0.0 0.0 5.0 0.1 -#pragma parameter cust_artifacting "Custom Artifacting Value" 0.0 0.0 5.0 0.1 +#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 3.0 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 +#pragma parameter cust_artifacting "NTSC Custom Artifacting Value" 0.0 0.0 5.0 0.1 #define PI 3.14159265 @@ -32,18 +36,29 @@ layout(location = 4) out float SATURATION; layout(location = 5) out float FRINGING; layout(location = 6) out float ARTIFACTING; layout(location = 7) out float CHROMA_MOD_FREQ; +layout(location = 8) out float MERGE; void main() { + float res = global.ntsc_scale; + float OriginalSize = global.OriginalSize.x; gl_Position = global.MVP * Position; vTexCoord = TexCoord; - pix_no = TexCoord * global.SourceSize.xy * (global.OutputSize.xy / global.SourceSize.xy); - phase = (global.OriginalSize.x > 300.0) ? 2.0 : 3.0; + if (res < 1.0) pix_no = TexCoord * global.SourceSize.xy * (res * global.OutputSize.xy / global.SourceSize.xy); else + pix_no = TexCoord * global.SourceSize.xy * ( global.OutputSize.xy / global.SourceSize.xy); + phase = (global.ntsc_phase < 1.5) ? ((OriginalSize > 300.0) ? 2.0 : 3.0) : ((global.ntsc_phase > 2.5) ? 3.0 : 2.0); + + res = max(res, 1.0); CHROMA_MOD_FREQ = (phase < 2.5) ? (4.0 * PI / 15.0) : (PI / 3.0); - ARTIFACTING = (global.quality > -0.5) ? global.quality : global.cust_artifacting; + ARTIFACTING = (global.quality > -0.5) ? global.quality * 0.5*(res+1.0) : global.cust_artifacting; FRINGING = (global.quality > -0.5) ? global.quality : global.cust_fringing; SATURATION = global.ntsc_sat; - BRIGHTNESS = global.ntsc_bright; + BRIGHTNESS = global.ntsc_bright; + pix_no.x = pix_no.x * res; + + MERGE = (int(global.quality) == 2 || phase < 2.5) ? 0.0 : 1.0; + MERGE = (int(global.quality) == -1) ? global.ntsc_fields : MERGE; + } #pragma stage fragment @@ -55,6 +70,7 @@ layout(location = 4) in float SATURATION; layout(location = 5) in float FRINGING; layout(location = 6) in float ARTIFACTING; layout(location = 7) in float CHROMA_MOD_FREQ; +layout(location = 8) in float MERGE; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D Source; @@ -85,9 +101,23 @@ void main() { vec3 col = texture(Source, vTexCoord).rgb; vec3 yiq = rgb2yiq(col); + vec3 yiq2 = yiq; - float chroma_phase = (phase < 2.5) ? PI * (mod(pix_no.y, 2.0) + mod(global.FrameCount, 2.)) : 0.6667 * PI * (mod(pix_no.y, 3.0) + mod(global.FrameCount, 2.)); + float mod1 = 2.0; + float mod2 = 3.0; +if (MERGE > 0.5) +{ + float chroma_phase2 = (phase < 2.5) ? PI * (mod(pix_no.y, mod1) + mod(global.FrameCount+1, 2.)) : 0.6667 * PI * (mod(pix_no.y, mod2) + mod(global.FrameCount+1, 2.)); + float mod_phase2 = chroma_phase2 + pix_no.x * CHROMA_MOD_FREQ; + float i_mod2 = cos(mod_phase2); + float q_mod2 = sin(mod_phase2); + yiq2.yz *= vec2(i_mod2, q_mod2); // Modulate. + yiq2 *= mix_mat; // Cross-talk. + yiq2.yz *= vec2(i_mod2, q_mod2); // Demodulate. +} + + float chroma_phase = (phase < 2.5) ? PI * (mod(pix_no.y, mod1) + mod(global.FrameCount, 2.)) : 0.6667 * PI * (mod(pix_no.y, mod2) + mod(global.FrameCount, 2.)); float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ; float i_mod = cos(mod_phase); @@ -96,5 +126,8 @@ void main() yiq.yz *= vec2(i_mod, q_mod); // Modulate. yiq *= mix_mat; // Cross-talk. yiq.yz *= vec2(i_mod, q_mod); // Demodulate. + + yiq = (MERGE < 0.5) ? yiq : 0.5*(yiq+yiq2); + FragColor = vec4(yiq, 1.0); } diff --git a/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang b/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang index 4a58cad..97b1dcd 100644 --- a/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang +++ b/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang @@ -3,6 +3,7 @@ // NTSC-Adaptive // based on Themaister's NTSC shader + layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; @@ -10,9 +11,14 @@ layout(std140, set = 0, binding = 0) uniform UBO vec4 OriginalSize; vec4 SourceSize; float linearize; + float ntsc_scale; + float ntsc_phase; + float auto_res; } global; -#pragma parameter linearize "Linearize Output Gamma" 0.0 0.0 1.0 1.0 +#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 3.0 0.05 +#pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0 +#pragma parameter linearize "NTSC Linearize Output Gamma" 0.0 0.0 1.0 1.0 #pragma stage vertex layout(location = 0) in vec4 Position; @@ -184,9 +190,11 @@ const float chroma_filter_3_phase[25] = float[25]( void main() { - float phase = (global.OriginalSize.x > 300.0) ? 2.0 : 3.0; - float one_x = global.SourceSize.z; + float res = global.ntsc_scale; + float OriginalSize = global.OriginalSize.x; + float one_x = global.SourceSize.z / res; vec3 signal = vec3(0.0); + float phase = (global.ntsc_phase < 1.5) ? ((OriginalSize > 300.0) ? 2.0 : 3.0) : ((global.ntsc_phase > 2.5) ? 3.0 : 2.0); if(phase < 2.5) { @@ -276,4 +284,4 @@ void main() FragColor = vec4(rgb, 1.0); if(global.linearize < 0.5) return; else FragColor = pow(FragColor, vec4(2.2)); -} +} diff --git a/presets/crt-guest-advanced-ntsc.slangp b/presets/crt-guest-advanced-ntsc.slangp new file mode 100644 index 0000000..a112977 --- /dev/null +++ b/presets/crt-guest-advanced-ntsc.slangp @@ -0,0 +1,134 @@ +shaders = 17 + +shader0 = ../stock.slang +filter_linear0 = false +scale_type0 = source +scale0 = 1.0 + +shader1 = ../stock.slang +filter_linear1 = false +scale_type1 = source +scale1 = 1.0 +alias1 = StockPass + +shader2 = ../crt/shaders/guest/advanced/afterglow0.slang +filter_linear2 = true +scale_type2 = source +scale2 = 1.0 +alias2 = AfterglowPass + +shader3 = ../crt/shaders/guest/advanced/pre-shaders-afterglow.slang +filter_linear3 = true +scale_type3 = source +scale3 = 1.0 +alias3 = PrePass0 + +textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" +SamplerLUT1 = ../crt/shaders/guest/advanced/lut/trinitron-lut.png +SamplerLUT1_linear = true +SamplerLUT2 = ../crt/shaders/guest/advanced/lut/inv-trinitron-lut.png +SamplerLUT2_linear = true +SamplerLUT3 = ../crt/shaders/guest/advanced/lut/nec-lut.png +SamplerLUT3_linear = true +SamplerLUT4 = ../crt/shaders/guest/advanced/lut/ntsc-lut.png +SamplerLUT4_linear = true + +# custom ntsc shaders + +shader4 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang +shader5 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang + +filter_linear4 = false +filter_linear5 = true + +scale_type_x4 = source +scale_type_y4 = source +scale_x4 = 4.0 +scale_y4 = 1.0 +frame_count_mod4 = 2 +float_framebuffer4 = true + +scale_type5 = source +scale_x5 = 0.5 +scale_y5 = 1.0 + +shader6 = ../crt/shaders/guest/advanced/custom-fast-sharpen.slang +filter_linear6 = true +scale_type6 = source +scale_x6 = 1.0 +scale_y6 = 1.0 +alias6 = NtscPass + +shader7 = ../crt/shaders/guest/advanced/convert-ntsc.slang +filter_linear7 = true +scale_type7 = source +scale_x7 = 0.5 +scale_y7 = 1.0 + +shader8 = ../stock.slang +filter_linear8 = true +scale_type8 = source +scale_x8 = 1.0 +scale_y8 = 1.0 +alias8 = PrePass +mipmap_input8 = true + +shader9 = ../crt/shaders/guest/advanced/avg-lum-ntsc.slang +filter_linear9 = true +scale_type9 = source +scale9 = 1.0 +mipmap_input9 = true +alias9 = AvgLumPass + +shader10 = ../crt/shaders/guest/advanced/linearize-ntsc.slang +filter_linear10 = true +scale_type10 = source +scale10 = 1.0 +alias10 = LinearizePass +float_framebuffer10 = true + +shader11 = ../crt/shaders/guest/advanced/gaussian_horizontal.slang +filter_linear11 = true +scale_type_x11 = absolute +scale_x11 = 640.0 +scale_type_y11 = source +scale_y11 = 1.0 +float_framebuffer11 = true + +shader12 = ../crt/shaders/guest/advanced/gaussian_vertical.slang +filter_linear12 = true +scale_type_x12 = absolute +scale_x12 = 640.0 +scale_type_y12 = absolute +scale_y12 = 480.0 +float_framebuffer12 = true +alias12 = GlowPass + +shader13 = ../crt/shaders/guest/advanced/bloom_horizontal.slang +filter_linear13 = true +scale_type_x13 = absolute +scale_x13 = 640.0 +scale_type_y13 = absolute +scale_y13 = 480.0 +float_framebuffer13 = true + +shader14 = ../crt/shaders/guest/advanced/bloom_vertical.slang +filter_linear14 = true +scale_type_x14 = absolute +scale_x14 = 640.0 +scale_type_y14 = absolute +scale_y14 = 480.0 +float_framebuffer14 = true +alias14 = BloomPass + +shader15 = ../crt/shaders/guest/advanced/crt-guest-advanced-ntsc.slang +filter_linear15 = true +scale_type15 = viewport +scale_x15 = 1.0 +scale_y15 = 1.0 + +shader16 = ../crt/shaders/guest/advanced/deconvergence.slang +filter_linear16 = true +scale_type16 = viewport +scale_x16 = 1.0 +scale_y16 = 1.0 diff --git a/presets/crt-guest-dr-venom2-hires.slangp b/presets/crt-guest-dr-venom2-hires.slangp deleted file mode 100644 index fcdc08b..0000000 --- a/presets/crt-guest-dr-venom2-hires.slangp +++ /dev/null @@ -1,64 +0,0 @@ -shaders = 8 - -shader0 = ../stock.slang -filter_linear0 = false -scale_type0 = source -scale0 = 1.0 -alias0 = StockPass - -shader1 = ../crt/shaders/guest/crt-gdv-new/afterglow0.slang -filter_linear1 = false -scale_type1 = source -scale1 = 1.0 -alias1 = AfterglowPass - -shader2 = ../crt/shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang -filter_linear2 = false -scale_type2 = source -scale2 = 1.0 -alias2 = PrePass - -textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" -SamplerLUT1 = ../crt/shaders/guest/lut/sony_trinitron1.png -SamplerLUT1_linear = true -SamplerLUT2 = ../crt/shaders/guest/lut/sony_trinitron2.png -SamplerLUT2_linear = true -SamplerLUT3 = ../crt/shaders/guest/lut/other1.png -SamplerLUT3_linear = true -SamplerLUT4 = ../crt/shaders/guest/lut/custom_lut.png -SamplerLUT4_linear = true - -shader3 = ../crt/shaders/guest/crt-gdv-new/avg-lum-ntsc.slang -filter_linear3 = true -scale_type3 = source -scale3 = 1.0 -mipmap_input3 = true -alias3 = AvgLumPass - -shader4 = ../crt/shaders/guest/crt-gdv-new/linearize-ntsc.slang -filter_linear4 = true -scale_type4 = source -scale4 = 1.0 -alias4 = LinearizePass -float_framebuffer4 = true # comment this line for max precision - -shader5 = ../crt/shaders/guest/crt-gdv-new/gaussian_horizontal.slang -filter_linear5 = true -scale_type_x5 = viewport -scale_x5 = 0.5 -scale_type_y5 = source -scale_y5 = 1.0 - -shader6 = ../crt/shaders/guest/crt-gdv-new/gaussian_vertical.slang -filter_linear6 = true -scale_type_x6 = viewport -scale_x6 = 0.5 -scale_type_y6 = viewport -scale_y6 = 0.5 -alias6 = GlowPass - -shader7 = ../crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-hires.slang -filter_linear7 = true -scale_type7 = viewport -scale_x7 = 1.0 -scale_y7 = 1.0 diff --git a/presets/crt-guest-dr-venom2-ntsc.slangp b/presets/crt-guest-dr-venom2-ntsc.slangp deleted file mode 100644 index a99533b..0000000 --- a/presets/crt-guest-dr-venom2-ntsc.slangp +++ /dev/null @@ -1,84 +0,0 @@ -shaders = 10 - -shader0 = ../stock.slang -filter_linear0 = false -scale_type0 = source -scale0 = 1.0 -alias0 = StockPass - -shader1 = ../crt/shaders/guest/crt-gdv-new/afterglow0.slang -filter_linear1 = false -scale_type1 = source -scale1 = 1.0 -alias1 = AfterglowPass - -shader2 = ../crt/shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang -filter_linear2 = false -scale_type2 = source -scale2 = 1.0 - -textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4" -SamplerLUT1 = ../crt/shaders/guest/lut/sony_trinitron1.png -SamplerLUT1_linear = true -SamplerLUT2 = ../crt/shaders/guest/lut/sony_trinitron2.png -SamplerLUT2_linear = true -SamplerLUT3 = ../crt/shaders/guest/lut/other1.png -SamplerLUT3_linear = true -SamplerLUT4 = ../crt/shaders/guest/lut/custom_lut.png -SamplerLUT4_linear = true - -shader3 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang -shader4 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang - -filter_linear3 = false -filter_linear4 = false - -scale_type_x3 = source -scale_type_y3 = source -scale_x3 = 4.0 -scale_y3 = 1.0 -frame_count_mod3 = 2 -float_framebuffer3 = true - -scale_type4 = source -scale_x4 = 0.5 -scale_y4 = 1.0 -alias4 = PrePass - -shader5 = ../crt/shaders/guest/crt-gdv-new/avg-lum-ntsc.slang -filter_linear5 = true -scale_type5 = source -scale5 = 1.0 -mipmap_input5 = true -alias5 = AvgLumPass - -shader6 = ../crt/shaders/guest/crt-gdv-new/linearize-ntsc.slang -filter_linear6 = true -scale_type6 = source -scale6 = 1.0 -alias6 = LinearizePass -float_framebuffer6 = true # comment this line for max precision - -shader7 = ../crt/shaders/guest/crt-gdv-new/gaussian_horizontal.slang -filter_linear7 = true -scale_type_x7 = viewport -scale_x7 = 0.5 -scale_type_y7 = source -scale_y7 = 1.0 - -shader8 = ../crt/shaders/guest/crt-gdv-new/gaussian_vertical.slang -filter_linear8 = true -scale_type_x8 = viewport -scale_x8 = 0.5 -scale_type_y8 = viewport -scale_y8 = 0.5 -alias8 = GlowPass - -shader9 = ../crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-ntsc.slang -filter_linear9 = true -scale_type9 = viewport -scale_x9 = 1.0 -scale_y9 = 1.0 - -parameters = "quality" -quality = 1.0