diff --git a/blurs/smart-blur.slang b/blurs/smart-blur.slang index c67aa46..0b048c0 100644 --- a/blurs/smart-blur.slang +++ b/blurs/smart-blur.slang @@ -3,7 +3,8 @@ /* Hyllian Smart-Blur Shader - Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com + Copyright (C) 2011-2020 Hyllian - sergiogdb@gmail.com + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights @@ -27,11 +28,13 @@ layout(push_constant) uniform Push vec4 OriginalSize; vec4 OutputSize; uint FrameCount; + float SB_BLUR_LEVEL; float SB_RED_THRESHOLD; float SB_GREEN_THRESHOLD; float SB_BLUE_THRESHOLD; } params; +#pragma parameter SB_BLUR_LEVEL "Smart Blur Level" 0.66 0.00 1.00 0.02 #pragma parameter SB_RED_THRESHOLD "Smart Blur Red Threshold" 0.2 0.0 0.6 0.01 #pragma parameter SB_GREEN_THRESHOLD "Smart Blur Green Threshold" 0.2 0.0 0.6 0.01 #pragma parameter SB_BLUE_THRESHOLD "Smart Blur Blue Threshold" 0.2 0.0 0.6 0.01 @@ -99,9 +102,9 @@ void main() if (eq(E,F) && eq(E,H) && eq(E,I) && eq(E,B) && eq(E,C) && eq(E,A) && eq(E,D) && eq(E,G)) { - sum = (E+A+C+D+F+G+I+B+H)/9.0; - E = sum; + sum = (A+C+D+F+G+I+B+H)/8.0; + E = mix(E, sum, params.SB_BLUR_LEVEL); } FragColor = vec4(E, 1.0); -} \ No newline at end of file +} diff --git a/crt/crt-guest-dr-venom2.slangp b/crt/crt-guest-dr-venom2.slangp new file mode 100644 index 0000000..cc82eaa --- /dev/null +++ b/crt/crt-guest-dr-venom2.slangp @@ -0,0 +1,85 @@ +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/crt-hyllian-3d.slangp b/crt/crt-hyllian-3d.slangp index 0b877d9..b13bc59 100644 --- a/crt/crt-hyllian-3d.slangp +++ b/crt/crt-hyllian-3d.slangp @@ -1,4 +1,4 @@ shaders = 1 -shader0 = shaders/crt-hyllian-3d.slang +shader0 = shaders/hyllian/crt-hyllian-3d.slang filter_linear0 = true diff --git a/crt/crt-hyllian-curvature.slangp b/crt/crt-hyllian-curvature.slangp new file mode 100644 index 0000000..5530cde --- /dev/null +++ b/crt/crt-hyllian-curvature.slangp @@ -0,0 +1,4 @@ +shaders = 1 + +shader0 = shaders/hyllian/crt-hyllian-curvature.slang +filter_linear0 = false diff --git a/crt/crt-hyllian-glow.slangp b/crt/crt-hyllian-glow.slangp index 0b44c78..78106db 100644 --- a/crt/crt-hyllian-glow.slangp +++ b/crt/crt-hyllian-glow.slangp @@ -1,30 +1,79 @@ -shaders = 6 - -shader0 = shaders/glow/linearize.slang -filter_linear0 = false -srgb_framebuffer0 = true - -shader1 = shaders/crt-hyllian-glow/crt-hyllian.slang -filter_linear1 = false -scale_type1 = viewport -scale1 = 1.0 -srgb_framebuffer1 = true -alias1 = CRT_PASS - -shader2 = shaders/glow/threshold.slang -filter_linear2 = false -srgb_framebuffer2 = true - -shader3 = shaders/glow/blur_horiz.slang -mipmap_input3 = true -filter_linear3 = true -scale_type3 = source -scale3 = 0.25 -srgb_framebuffer3 = true - -shader4 = shaders/glow/blur_vert.slang -filter_linear4 = true -srgb_framebuffer4 = true - -shader5 = shaders/crt-hyllian-glow/resolve2.slang -filter_linear5 = true \ No newline at end of file +shaders = "6" +shader0 = "shaders/glow/linearize.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "true" +shader1 = "shaders/hyllian/crt-hyllian.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "CRTPass" +float_framebuffer1 = "false" +srgb_framebuffer1 = "true" +scale_type_x1 = "viewport" +scale_x1 = "1.000000" +scale_type_y1 = "viewport" +scale_y1 = "1.000000" +shader2 = "shaders/glow/threshold.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_border" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "true" +shader3 = "shaders/glow/blur_horiz.slang" +filter_linear3 = "true" +wrap_mode3 = "clamp_to_border" +mipmap_input3 = "true" +alias3 = "" +float_framebuffer3 = "false" +srgb_framebuffer3 = "true" +scale_type_x3 = "viewport" +scale_x3 = "0.200000" +scale_type_y3 = "viewport" +scale_y3 = "0.200000" +shader4 = "shaders/glow/blur_vert.slang" +filter_linear4 = "true" +wrap_mode4 = "clamp_to_border" +mipmap_input4 = "false" +alias4 = "" +float_framebuffer4 = "false" +srgb_framebuffer4 = "true" +shader5 = "shaders/glow/resolve.slang" +filter_linear5 = "true" +wrap_mode5 = "clamp_to_border" +mipmap_input5 = "false" +alias5 = "" +float_framebuffer5 = "false" +srgb_framebuffer5 = "false" +parameters = "INPUT_GAMMA;BEAM_PROFILE;HFILTER_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;HFILTER_SHARPNESS;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES;GLOW_WHITEPOINT;GLOW_ROLLOFF;BLOOM_STRENGTH;OUTPUT_GAMMA;CURVATURE;warpX;warpY;cornersize;cornersmooth;noise_amt;shadowMask;maskDark;maskLight" +INPUT_GAMMA = "2.400000" +BEAM_PROFILE = "0.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BEAM_MAX_WIDTH = "1.000000" +SCANLINES_STRENGTH = "0.580000" +COLOR_BOOST = "1.250000" +HFILTER_SHARPNESS = "1.000000" +PHOSPHOR_LAYOUT = "4.000000" +MASK_INTENSITY = "0.500000" +CRT_ANTI_RINGING = "1.000000" +InputGamma = "1.000000" +OutputGamma = "1.000000" +VSCANLINES = "0.000000" +GLOW_WHITEPOINT = "0.500000" +GLOW_ROLLOFF = "1.200000" +BLOOM_STRENGTH = "0.100000" +OUTPUT_GAMMA = "2.200000" +CURVATURE = "0.000000" +warpX = "0.031000" +warpY = "0.031000" +cornersize = "0.030000" +cornersmooth = "1000.000000" +noise_amt = "1.000000" +shadowMask = "0.000000" +maskDark = "0.500000" +maskLight = "1.500000" diff --git a/crt/crt-hyllian-multipass.slangp b/crt/crt-hyllian-multipass.slangp index 0f81106..aad902d 100644 --- a/crt/crt-hyllian-multipass.slangp +++ b/crt/crt-hyllian-multipass.slangp @@ -1,6 +1,6 @@ shaders = 2 -shader0 = shaders/crt-hyllian-multipass/crt-hyllian-pass0.slang +shader0 = shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass0.slang filter_linear0 = false srgb_framebuffer0 = true scale_type_x0 = viewport @@ -8,7 +8,7 @@ scale_type_y0 = source scale_x0 = 1.0 scale_y0 = 1.0 -shader1 = shaders/crt-hyllian-multipass/crt-hyllian-pass1.slang +shader1 = shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass1.slang filter_linear1 = false # Uncomment these lines for a sharper variation diff --git a/crt/crt-hyllian-sinc-glow.slangp b/crt/crt-hyllian-sinc-glow.slangp new file mode 100644 index 0000000..7e113cc --- /dev/null +++ b/crt/crt-hyllian-sinc-glow.slangp @@ -0,0 +1,77 @@ +shaders = "6" +shader0 = "shaders/glow/linearize.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "true" +shader1 = "shaders/hyllian/crt-hyllian-sinc.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "CRTPass" +float_framebuffer1 = "false" +srgb_framebuffer1 = "true" +scale_type_x1 = "viewport" +scale_x1 = "1.000000" +scale_type_y1 = "viewport" +scale_y1 = "1.000000" +shader2 = "shaders/glow/threshold.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_border" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "true" +shader3 = "shaders/glow/blur_horiz.slang" +filter_linear3 = "true" +wrap_mode3 = "clamp_to_border" +mipmap_input3 = "true" +alias3 = "" +float_framebuffer3 = "false" +srgb_framebuffer3 = "true" +scale_type_x3 = "viewport" +scale_x3 = "0.200000" +scale_type_y3 = "viewport" +scale_y3 = "0.200000" +shader4 = "shaders/glow/blur_vert.slang" +filter_linear4 = "true" +wrap_mode4 = "clamp_to_border" +mipmap_input4 = "false" +alias4 = "" +float_framebuffer4 = "false" +srgb_framebuffer4 = "true" +shader5 = "shaders/glow/resolve.slang" +filter_linear5 = "true" +wrap_mode5 = "clamp_to_border" +mipmap_input5 = "false" +alias5 = "" +float_framebuffer5 = "false" +srgb_framebuffer5 = "false" +parameters = "INPUT_GAMMA;BEAM_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;HFILTER_SHARPNESS;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES;GLOW_WHITEPOINT;GLOW_ROLLOFF;BLOOM_STRENGTH;OUTPUT_GAMMA;CURVATURE;warpX;warpY;cornersize;cornersmooth;noise_amt;shadowMask;maskDark;maskLight" +INPUT_GAMMA = "2.400000" +BEAM_PROFILE = "0'.000000" +BEAM_MIN_WIDTH = "0.860000" +BEAM_MAX_WIDTH = "1.000000" +SCANLINES_STRENGTH = "0.720000" +COLOR_BOOST = "1.250000" +PHOSPHOR_LAYOUT = "4.000000" +MASK_INTENSITY = "0.500000" +CRT_ANTI_RINGING = "1.000000" +InputGamma = "1.000000" +OutputGamma = "1.000000" +VSCANLINES = "0.000000" +GLOW_WHITEPOINT = "0.500000" +GLOW_ROLLOFF = "1.200000" +BLOOM_STRENGTH = "0.100000" +OUTPUT_GAMMA = "2.200000" +CURVATURE = "0.000000" +warpX = "0.031000" +warpY = "0.031000" +cornersize = "0.030000" +cornersmooth = "1000.000000" +noise_amt = "1.000000" +shadowMask = "0.000000" +maskDark = "0.500000" +maskLight = "1.500000" diff --git a/crt/crt-hyllian-sinc.slangp b/crt/crt-hyllian-sinc.slangp new file mode 100644 index 0000000..c739cf3 --- /dev/null +++ b/crt/crt-hyllian-sinc.slangp @@ -0,0 +1,4 @@ +shaders = 1 + +shader0 = shaders/hyllian/crt-hyllian-sinc.slang +filter_linear0 = false diff --git a/crt/crt-hyllian.slangp b/crt/crt-hyllian.slangp index 380e93d..4007389 100644 --- a/crt/crt-hyllian.slangp +++ b/crt/crt-hyllian.slangp @@ -1,4 +1,4 @@ shaders = 1 -shader0 = shaders/crt-hyllian.slang +shader0 = shaders/hyllian/crt-hyllian.slang filter_linear0 = false diff --git a/crt/shaders/crt-hyllian.slang b/crt/shaders/crt-hyllian.slang deleted file mode 100644 index df49c9a..0000000 --- a/crt/shaders/crt-hyllian.slang +++ /dev/null @@ -1,185 +0,0 @@ -#version 450 - -layout(push_constant) uniform Push -{ - float PHOSPHOR; - float VSCANLINES; - float InputGamma; - float OutputGamma; - float SHARPNESS; - float COLOR_BOOST; - float RED_BOOST; - float GREEN_BOOST; - float BLUE_BOOST; - float SCANLINES_STRENGTH; - float BEAM_MIN_WIDTH; - float BEAM_MAX_WIDTH; - float CRT_ANTI_RINGING; -} param; - -#pragma parameter PHOSPHOR "CRT - Phosphor ON/OFF" 1.0 0.0 1.0 1.0 -#pragma parameter VSCANLINES "CRT - Scanlines Direction" 0.0 0.0 1.0 1.0 -#pragma parameter InputGamma "CRT - Input gamma" 2.5 0.0 5.0 0.1 -#pragma parameter OutputGamma "CRT - Output Gamma" 2.2 0.0 5.0 0.1 -#pragma parameter SHARPNESS "CRT - Sharpness Hack" 1.0 1.0 5.0 1.0 -#pragma parameter COLOR_BOOST "CRT - Color Boost" 1.5 1.0 2.0 0.05 -#pragma parameter RED_BOOST "CRT - Red Boost" 1.0 1.0 2.0 0.01 -#pragma parameter GREEN_BOOST "CRT - Green Boost" 1.0 1.0 2.0 0.01 -#pragma parameter BLUE_BOOST "CRT - Blue Boost" 1.0 1.0 2.0 0.01 -#pragma parameter SCANLINES_STRENGTH "CRT - Scanline Strength" 0.50 0.0 1.0 0.02 -#pragma parameter BEAM_MIN_WIDTH "CRT - Min Beam Width" 0.86 0.0 1.0 0.02 -#pragma parameter BEAM_MAX_WIDTH "CRT - Max Beam Width" 1.0 0.0 1.0 0.02 -#pragma parameter CRT_ANTI_RINGING "CRT - Anti-Ringing" 0.8 0.0 1.0 0.1 - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; - vec4 OutputSize; - vec4 OriginalSize; - vec4 SourceSize; -} 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 = 1) in vec2 FragCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -/* - Hyllian's CRT Shader - - Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) -#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) - -// Horizontal cubic filter. - -// Some known filters use these values: - -// B = 0.0, C = 0.0 => Hermite cubic filter. -// B = 1.0, C = 0.0 => Cubic B-Spline filter. -// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. This is the default used in this shader. -// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. -// B = 0.3782, C = 0.3109 => Robidoux filter. -// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. -// B = 0.36, C = 0.28 => My best config for ringing elimination in pixel art (Hyllian). - -// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif - -// Change these params to configure the horizontal filter. -float B = 0.0; -float C = 0.5; - -mat4x4 invX = mat4x4( - (-B - 6.0*C)/6.0, (3.0*B + 12.0*C)/6.0, (-3.0*B - 6.0*C)/6.0, B/6.0, - (12.0 - 9.0*B - 6.0*C)/6.0, (-18.0 + 12.0*B + 6.0*C)/6.0, 0.0, (6.0 - 2.0*B)/6.0, - -(12.0 - 9.0*B - 6.0*C)/6.0, (18.0 - 15.0*B - 12.0*C)/6.0, (3.0*B + 6.0*C)/6.0, B/6.0, - (B + 6.0*C)/6.0, -C, 0.0, 0.0 -); - - - -void main() -{ - vec3 color; - - vec2 TextureSize = vec2(param.SHARPNESS*global.SourceSize.x, global.SourceSize.y); - - vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); - vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); - - vec2 pix_coord = vTexCoord*TextureSize + vec2(-0.5, 0.5); - - vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.0, -0.5))/TextureSize, param.VSCANLINES); - - vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); - - vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); - vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); - vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); - vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); - vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); - vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); - vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); - vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); - - // Get min/max samples - vec3 min_sample = min(min(c01, c11), min(c02, c12)); - vec3 max_sample = max(max(c01, c11), max(c02, c12)); - - mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); - mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); - - vec4 invX_Px = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0) * invX; - vec3 color0 = color_matrix0 * invX_Px; - vec3 color1 = color_matrix1 * invX_Px; - - // Anti-ringing - vec3 aux = color0; - color0 = clamp(color0, min_sample, max_sample); - color0 = mix(aux, color0, param.CRT_ANTI_RINGING); - aux = color1; - color1 = clamp(color1, min_sample, max_sample); - color1 = mix(aux, color1, param.CRT_ANTI_RINGING); - - float pos0 = fp.y; - float pos1 = 1 - fp.y; - - vec3 lum0 = mix(vec3(param.BEAM_MIN_WIDTH), vec3(param.BEAM_MAX_WIDTH), color0); - vec3 lum1 = mix(vec3(param.BEAM_MIN_WIDTH), vec3(param.BEAM_MAX_WIDTH), color1); - - vec3 d0 = clamp(pos0/(lum0 + 0.0000001), 0.0, 1.0); - vec3 d1 = clamp(pos1/(lum1 + 0.0000001), 0.0, 1.0); - - d0 = exp(-10.0*param.SCANLINES_STRENGTH*d0*d0); - d1 = exp(-10.0*param.SCANLINES_STRENGTH*d1*d1); - - color = clamp(color0*d0 + color1*d1, 0.0, 1.0); - - color *= param.COLOR_BOOST*vec3(param.RED_BOOST, param.GREEN_BOOST, param.BLUE_BOOST); - - float mod_factor = mix(vTexCoord.x * global.OutputSize.x, vTexCoord.y * global.OutputSize.y, param.VSCANLINES); - - vec3 dotMaskWeights = mix( - vec3(1.0, 0.7, 1.0), - vec3(0.7, 1.0, 0.7), - floor(mod(mod_factor, 2.0)) - ); - - color.rgb *= mix(vec3(1.0), dotMaskWeights, param.PHOSPHOR); - - color = GAMMA_OUT(color); - - FragColor = vec4(color, 1.0); -} diff --git a/crt/shaders/guest/afterglow.slang b/crt/shaders/guest/afterglow.slang index 1f34b5e..a77ed8f 100644 --- a/crt/shaders/guest/afterglow.slang +++ b/crt/shaders/guest/afterglow.slang @@ -23,24 +23,18 @@ layout(push_constant) uniform Push { - float SW, AR, PR, AG, PG, AB, PB, sat; + float AS, PR, PG, PB, sat; } params; -#pragma parameter SW "Afterglow switch ON/OFF" 1.0 0.0 1.0 1.0 -#pragma parameter AR "Afterglow Red (more is more)" 0.07 0.0 1.0 0.01 +#pragma parameter AS "Afterglow Strength" 0.07 0.0 1.0 0.01 #pragma parameter PR "Persistence Red (more is less)" 0.05 0.0 1.0 0.01 -#pragma parameter AG "Afterglow Green" 0.07 0.0 1.0 0.01 #pragma parameter PG "Persistence Green" 0.05 0.0 1.0 0.01 -#pragma parameter AB "Afterglow Blue" 0.07 0.0 1.0 0.01 #pragma parameter PB "Persistence Blue" 0.05 0.0 1.0 0.01 #pragma parameter sat "Afterglow saturation" 0.10 0.0 1.0 0.01 -#define SW params.SW -#define AR params.AR +#define AS params.AS #define PR params.PR -#define AG params.AG #define PG params.PG -#define AB params.AB #define PB params.PB #define sat params.sat @@ -86,7 +80,7 @@ layout(set = 0, binding = 8) uniform sampler2D OriginalHistory6; vec3 afterglow(float number) { - return vec3(AR, AG, AB)*exp2(-vec3(PR, PG, PB)*vec3(number*number)); + return vec3(AS)*exp2(-vec3(PR, PG, PB)*vec3(number*number)); } void main() @@ -107,5 +101,5 @@ void main() float w = 1.0; if ((color.r + color.g + color.b) > 7.0/255.0) w = 0.0; - FragColor = vec4(color + SW*w*glow,1.0); + FragColor = vec4(color + w*glow,1.0); } \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/afterglow0.slang b/crt/shaders/guest/crt-gdv-new/afterglow0.slang new file mode 100644 index 0000000..f5c3501 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/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.14 0.0 0.25 0.01 +#pragma parameter PG " Persistence Green" 0.14 0.0 0.25 0.01 +#pragma parameter PB " Persistence Blue" 0.14 0.0 0.25 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 < 3.0/255.0)) { w = 0.0; } + + vec3 result = mix( max(mix(color, accumulate, 0.74 + vec3(PR, PG, PB))- 2.0/255.0, 0.0)*(255.0/255.0), color, w); + + FragColor = vec4(result, w); +} \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/avg-lum-ntsc.slang b/crt/shaders/guest/crt-gdv-new/avg-lum-ntsc.slang new file mode 100644 index 0000000..2060f98 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/avg-lum-ntsc.slang @@ -0,0 +1,88 @@ +#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.90 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 OriginalHistory0; +layout(set = 0, binding = 3) uniform sampler2D AvgLumPassFeedback; + +#define PassPrev2Texture WhitePointPass + +void main() +{ + if (vTexCoord.x > 0.2 || vTexCoord.y > 0.2) discard; + + float m = max(log2(SourceSize.x), log2(SourceSize.y)); + m = max(m - 1.0, 1.0); + + float ltotal = 0.0; + + ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.25), m).rgb)); + ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.75), m).rgb)); + ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.25), m).rgb)); + ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.75), m).rgb)); + + ltotal*=0.25; + + ltotal = pow(0.577350269 * ltotal, 0.6); + + 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/crt-gdv-new/avg-lum.slang b/crt/shaders/guest/crt-gdv-new/avg-lum.slang new file mode 100644 index 0000000..d2b5538 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/avg-lum.slang @@ -0,0 +1,112 @@ +#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.75 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 OriginalHistory0; +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 = max(m - 1.0, 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+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.25), m).rgb)); + ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.75), m).rgb)); + ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.25), m).rgb)); + ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.75), m).rgb)); + + ltotal*=0.25; + + ltotal = pow(0.577350269 * ltotal, 0.6); + + float lhistory = texture(AvgLumPassFeedback, vec2(0.1,0.1)).a; + + ltotal = mix(ltotal, lhistory, lsmooth); + + vec3 l1 = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy ).rgb; + vec3 r1 = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy +dx ).rgb; + vec3 l2 = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy -dx ).rgb; + vec3 r2 = COMPAT_TEXTURE(OriginalHistory0, 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/crt-gdv-new/bloom_horizontal.slang b/crt/shaders/guest/crt-gdv-new/bloom_horizontal.slang new file mode 100644 index 0000000..e447629 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/bloom_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. + +*/ + +#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 SIZEHB " H. Bloom/Halation Radius" 3.0 1.0 30.0 1.0 +#define SIZEHB params.SIZEHB + +#pragma parameter SIGMA_HB " Horizontal Bloom/Halation Sigma" 0.70 0.5 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; + vec3 color = vec3(0.0); + vec2 dx = vec2(SourceSize1.z, 0.0); + + float w; + float wsum = 0.0; + vec3 pixel; + float n = -SIZEHB; + + 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 <= SIZEHB); + + color = color / wsum; + + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/bloom_vertical.slang b/crt/shaders/guest/crt-gdv-new/bloom_vertical.slang new file mode 100644 index 0000000..f18b7eb --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/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 Radius" 3.0 1.0 30.0 1.0 +#define SIZEVB params.SIZEVB + +#pragma parameter SIGMA_VB " Vertical Bloom/Halation Sigma" 0.70 0.5 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; + vec3 color = vec3(0.0); + vec2 dy = vec2(0.0, SourceSize1.w); + + float w; + float wsum = 0.0; + vec3 pixel; + float n = -SIZEVB; + + 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 <= SIZEVB); + + color = color / wsum; + + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-hires.slang b/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-hires.slang new file mode 100644 index 0000000..b56b5a7 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-hires.slang @@ -0,0 +1,729 @@ +#version 450 + +/* + CRT - Guest - Dr. Venom + + Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com + + Incorporates many good ideas and suggestions from 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 +{ + 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, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, intres, inters; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float bloom; + float mclip; + float scans; + float scansub; + float slotms; + float gamma_c; + float mask_gamma; + float gamma_out; +} global; + +#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 global.bloom // bloom 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.50 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost bright Pixels" 1.10 0.50 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 0.0 2.0 1.0 +#define gsl params.gsl // Alternate scanlines + +#pragma parameter scanline1 " Scanline beam shape low" 6.0 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline beam shape high" 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.5 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.20 +#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: 1.0:240p, 1.5...y-dowsample" 0.0 0.0 4.0 0.5 // Joint parameter with linearize_ntsc 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.07 0.01 +#define csize params.csize // corner size + +#pragma parameter bsize " Border smoothness" 600.0 100.0 600.0 25.0 +#define bsize params.bsize // border smoothness + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01 +#define warpX params.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01 +#define warpY params.warpY // Curvature Y + +#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 masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.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 mcut " Mask 5-7 Low Strength" 1.15 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 cutoff + +#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" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask // Slot Mask ON/OFF + +#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 2.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 + +#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize-ntsc pass, values must match +#define inters params.inters // interlacing effect smoothing + + +#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; + + +#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; + return exp2(-scanline*ex*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*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; + + 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 = 1.0 - slotmask*(1.0 - 0.125*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; +} + +// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature) +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY); + 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; +} + + +// Borrowed from maskstr's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5); + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize, 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 == 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); + SourceY = SourceY/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); + 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 - inters * SourceSize.w; + + 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 = color1; + + 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.y = pos.y + inters * SourceSize.w; else + 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 = color2; + + 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.0) { 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 + if (gsl == 2.0) { 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); + + 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(pow(2.0*f1 + 0.01, f2), 1.0); + float ds2 = min(pow(2.0*f2 + 0.01, f1), 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); + w3 = wf1+wf2; +} + + if (interb) + { + color = gc(0.5*(color1+color2)); + mcolor = vec3(max(max(color.r,color.g), color.b)); + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.40/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + float smask = (notate) ? SlotMask(gl_FragCoord.xy * 1.000001, mx) : SlotMask(gl_FragCoord.yx * 1.000001, mx); + + cmask*= (notate) ? Mask(gl_FragCoord.xy * 1.000001, mx) : Mask(gl_FragCoord.yx * 1.000001, 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 = min(Glow*(orig1+color), max(0.5*(colmx + orig1 - color),0.0)); + color = color + bloom*Bloom; + + color = min(color, mix(one, cmask, mclip)); + if (!interb) color = declip(color, pow(w3,0.6)); + + Glow = mix(Glow, 0.25*color, 0.7*colmx); + color = color + 0.5*glow*Glow; + + float gmo = 1.0/gamma_out; + if (interb) gmo = gmo / 0.70; + + color = pow(color, vec3(gmo)); + + FragColor = vec4(color*corner(pos0), 1.0); +} diff --git a/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-ntsc.slang b/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-ntsc.slang new file mode 100644 index 0000000..64f9b69 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2-ntsc.slang @@ -0,0 +1,729 @@ +#version 450 + +/* + CRT - Guest - Dr. Venom + + Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com + + Incorporates many good ideas and suggestions from 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 +{ + 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, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, intres, inters; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float bloom; + float mclip; + float scans; + float scansub; + float slotms; + float gamma_c; + float mask_gamma; + float gamma_out; +} global; + +#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 global.bloom // bloom 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.50 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost bright Pixels" 1.10 0.50 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 0.0 2.0 1.0 +#define gsl params.gsl // Alternate scanlines + +#pragma parameter scanline1 " Scanline beam shape low" 6.0 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline beam shape high" 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.5 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.20 +#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: 1.0:240p, 1.5...y-dowsample" 0.0 0.0 4.0 0.5 // Joint parameter with linearize_ntsc 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.07 0.01 +#define csize params.csize // corner size + +#pragma parameter bsize " Border smoothness" 600.0 100.0 600.0 25.0 +#define bsize params.bsize // border smoothness + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01 +#define warpX params.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01 +#define warpY params.warpY // Curvature Y + +#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 masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.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 mcut " Mask 5-7 Low Strength" 1.15 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 cutoff + +#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" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask // Slot Mask ON/OFF + +#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 2.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 + +#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize-ntsc pass, values must match +#define inters params.inters // interlacing effect smoothing + + +#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; + + +#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; + return exp2(-scanline*ex*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*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; + + 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 = 1.0 - slotmask*(1.0 - 0.125*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; +} + +// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature) +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY); + 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; +} + + +// Borrowed from maskstr's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5); + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize, 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 * vec4(2.0, 1.0, 0.5, 1.0); + + 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 == 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); + SourceY = SourceY/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); + 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 - inters * SourceSize.w; + + 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 = color1; + + 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.y = pos.y + inters * SourceSize.w; else + 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 = color2; + + 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.0) { 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 + if (gsl == 2.0) { 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); + + 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(pow(2.0*f1 + 0.01, f2), 1.0); + float ds2 = min(pow(2.0*f2 + 0.01, f1), 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); + w3 = wf1+wf2; +} + + if (interb) + { + color = gc(0.5*(color1+color2)); + mcolor = vec3(max(max(color.r,color.g), color.b)); + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.40/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + float smask = (notate) ? SlotMask(gl_FragCoord.xy * 1.000001, mx) : SlotMask(gl_FragCoord.yx * 1.000001, mx); + + cmask*= (notate) ? Mask(gl_FragCoord.xy * 1.000001, mx) : Mask(gl_FragCoord.yx * 1.000001, 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 = min(Glow*(orig1+color), max(0.5*(colmx + orig1 - color),0.0)); + color = color + bloom*Bloom; + + color = min(color, mix(one, cmask, mclip)); + if (!interb) color = declip(color, pow(w3,0.6)); + + Glow = mix(Glow, 0.25*color, 0.7*colmx); + color = color + 0.5*glow*Glow; + + float gmo = 1.0/gamma_out; + if (interb) gmo = gmo / 0.70; + + color = pow(color, vec3(gmo)); + + FragColor = vec4(color*corner(pos0), 1.0); +} diff --git a/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2.slang b/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2.slang new file mode 100644 index 0000000..2294b14 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2.slang @@ -0,0 +1,756 @@ +#version 450 + +/* + CRT - Guest - Dr. Venom + + Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com + + Incorporates many good ideas and suggestions from 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 +{ + 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, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, inters; +} 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; +} global; + + +#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 global.bloom // bloom effect + +#pragma parameter halation " Halation Strength" 0.0 0.0 0.5 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.50 10.0 0.05 +#define brightboost params.brightboost // adjust brightness + +#pragma parameter brightboost1 " Bright Boost bright Pixels" 1.10 0.50 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 0.0 2.0 1.0 +#define gsl params.gsl // Alternate scanlines + +#pragma parameter scanline1 " Scanline beam shape low" 6.0 0.0 20.0 0.5 +#define scanline1 params.scanline1 // scanline param, vertical sharpness + +#pragma parameter scanline2 " Scanline beam shape high" 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.5 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.20 +#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 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.07 0.01 +#define csize params.csize // corner size + +#pragma parameter bsize " Border smoothness" 600.0 100.0 600.0 25.0 +#define bsize params.bsize // border smoothness + +#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01 +#define warpX params.warpX // Curvature X + +#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01 +#define warpY params.warpY // Curvature Y + +#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 masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.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 mcut " Mask 5-7 Low Strength" 1.15 0.0 2.0 0.05 +#define mcut params.mcut // Mask 5-7 cutoff + +#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" 0.0 0.0 1.0 0.05 +#define slotmask params.slotmask // Slot Mask ON/OFF + +#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 2.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 + +#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.OriginalSize +#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; + +#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; + return exp2(-scanline*ex*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*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; + + 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 = 1.0 - slotmask*(1.0 - 0.125*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; +} + +// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature) +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY); + 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; +} + + +// Borrowed from cgwg's crt-geom, under GPL + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5); + coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x); + vec2 cdist = vec2(max(csize, 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() +{ + + 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); + + // 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); + vec2 pos = Warp(texcoord); + vec2 pos0 = Warp(TEX0.xy); + + bool notate = (TATE < 0.5); + 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 - inters * SourceSize.w; + + 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 wnorm = max(wl1, wr1); + + float twl3 = max(wl3 - sharp1, 0.0); + float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1)); float swl2 = 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 swr2 = 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); + } + + float wts = 1.0/(swl2 + rwl1 + rwr1 + swr2); + + vec3 l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, color0, ct, 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; + + sl2 = l2*l2*l2; sl2*=sl2; + sl1 = l1*l1*l1; sl1*=sl1; + sr1 = r1*r1*r1; sr1*=sr1; + sr2 = r2*r2*r2; sr2*=sr2; + + 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(rwl1, pc); twr1 = pow(rwr1, pc); + twl2 = pow(rwl2, pl); twr2 = pow(rwr2, pr); + float wmax = max(twl1, twr1); + float sharp_ei = s_sharp*pow(zero, pc)/wmax; + twl2 = max(twl2/wmax - sharp_ei, mix(-0.15, 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.15, 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); + + + vec3 gtmp = vec3(1.0/6.0); + vec3 scolor1 = color1; + + scolor1 = (sl2*swl2 + sl1*rwl1 + sr1*rwr1 + sr2*swr2)*wts; + scolor1 = pow(scolor1, gtmp); vec3 mcolor1 = scolor1; + scolor1 = min(mix(color1, scolor1, spike),1.0); + + vec3 scolor2, mcolor2; + + if (interb) pC4.y = pos.y + inters * SourceSize.w; else + 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; + + sl2 = l2*l2*l2; sl2*=sl2; + sl1 = l1*l1*l1; sl1*=sl1; + sr1 = r1*r1*r1; sr1*=sr1; + sr2 = r2*r2*r2; sr2*=sr2; + + 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(rwl1, pc); twr1 = pow(rwr1, pc); + twl2 = pow(rwl2, pl); twr2 = pow(rwr2, pr); + float wmax = max(twl1, twr1); + float sharp_ei = s_sharp*pow(zero, pc)/wmax; + twl2 = max(twl2/wmax - sharp_ei, mix(-0.15, 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.15, 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); + + scolor2 = color2; + scolor2 = (sl2*swl2 + sl1*rwl1 + sr1*rwr1 + sr2*swr2)*wts; + 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.0) { 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 + if (gsl == 2.0) { 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); + + 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(pow(2.0*f1 + 0.01, f2), 1.0); + float ds2 = min(pow(2.0*f2 + 0.01, f1), 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); + w3 = wf1+wf2; +} + + if (interb) + { + color = gc(0.5*(color1+color2)); + mcolor = vec3(max(max(color.r,color.g), color.b)); + } + + float mx = max(max(mcolor.r,mcolor.g),mcolor.b); + mx = pow(mx, 1.40/gamma_in); + + // Apply Mask + + vec3 orig1 = color; + vec3 cmask = one; + + float smask = (notate) ? SlotMask(gl_FragCoord.xy * 1.000001, mx) : SlotMask(gl_FragCoord.yx * 1.000001, mx); + + cmask*= (notate) ? Mask(gl_FragCoord.xy * 1.000001, mx) : Mask(gl_FragCoord.yx * 1.000001, 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; + + 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.6)); + + Glow = mix(Glow, 0.25*color, 0.7*colmx); + color = color + 0.5*glow*Glow; + + color = color + 0.5*(Bloom+Bloom*Bloom)*halation; + + float gmo = 1.0/gamma_out; + if (interb) gmo = gmo / 0.70; + + color = pow(color, vec3(gmo)); + + FragColor = vec4(color*corner(pos0), float(!notate)); +} diff --git a/crt/shaders/guest/crt-gdv-new/deconvergence.slang b/crt/shaders/guest/crt-gdv-new/deconvergence.slang new file mode 100644 index 0000000..32bf562 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/deconvergence.slang @@ -0,0 +1,123 @@ +#version 450 + +/* + CRT - Guest - Dr. Venom - Deconvergence pass + + 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 decons; + float cswitch; +} params; + +#pragma parameter bogus_hdeconvergence "[ HORIZONTAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0 +#pragma parameter deconr " Hor. Deconvergence Color/Range" 0.0 -12.0 12.0 0.5 +#define deconr params.deconr // Horizontal deconvergence colors range +#pragma parameter decons " Horizontal Deconvergence Strength" 0.5 0.0 1.0 0.05 +#define decons params.decons // Horizontal deconvergence colors strength +#pragma parameter cswitch " Switch Deconvergence Colors" 1.0 -1.0 1.0 2.0 +#define cswitch params.cswitch // Switch colors left/right + +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 AvgLumPass; + +#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; +} + +void main() +{ + + vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb; + vec3 result = color; + + if (abs(deconr) > 0.5) + { + float step = cswitch/1920.0; + + vec2 dx = vec2(step, 0.0); + + float shift = step * abs(deconr); + vec4 coords = vec4(shift, -shift, 0.0, -0.5*shift); + + vec2 rc = coords.rb; + vec2 gc = coords.gb; + vec2 bc = coords.rb; + + if (deconr < -0.05) { rc = coords.rb; gc = coords.ab; bc = coords.gb; } + + float TATE = round(COMPAT_TEXTURE(Source, vec2(0.5)).a); + + if (TATE > 0.5) + { + rc = -rc.yx; gc = -gc.yx, bc = -bc.yx; dx = -dx.yx; + } + + 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); + + result1 = mix(color, result1, decons); + result2 = mix(color, result2, decons); + result3 = mix(color, result3, decons); + result = (result1+result2+result3)/3.0; + result = plant(result, 0.5*(max(max(color.r,color.g),color.b)+max(max(result.r,result.g),result.b))); + } + + FragColor = vec4(result, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/gaussian_horizontal.slang b/crt/shaders/guest/crt-gdv-new/gaussian_horizontal.slang new file mode 100644 index 0000000..8e70131 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/gaussian_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. + +*/ + +#pragma format R16G16B16A16_SFLOAT + +layout(push_constant) uniform Push +{ + vec4 LinearizePassSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float SIZEH; + float SIGMA_H; +} params; + +#pragma parameter bogus_glow "[ GLOW/BLOOM PASS SETTINGS ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter SIZEH " H. Glow Radius" 5.0 1.0 30.0 1.0 +#define SIZEH params.SIZEH + +#pragma parameter SIGMA_H " Horizontal Glow Sigma" 1.25 0.5 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/crt-gdv-new/gaussian_vertical.slang b/crt/shaders/guest/crt-gdv-new/gaussian_vertical.slang new file mode 100644 index 0000000..6dc6f17 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/gaussian_vertical.slang @@ -0,0 +1,100 @@ +#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 SIZEV; + float SIGMA_V; +} params; + + +#pragma parameter SIZEV " V. Glow Radius" 5.0 1.0 30.0 1.0 +#define SIZEV params.SIZEV + +#pragma parameter SIGMA_V " Vertical Glow Sigma" 1.25 0.5 15.0 0.10 +#define SIGMA_V params.SIGMA_V + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +#define COMPAT_TEXTURE(c,d) texture(c,d) + +float invsqrsigma = 1.0/(2.0*SIGMA_V*SIGMA_V); + +float gaussian(float x) +{ + return exp(-x*x*invsqrsigma); +} + +void main() +{ + vec4 SourceSize1 = params.SourceSize; + float f = fract(SourceSize1.y * vTexCoord.y); + f = 0.5 - f; + vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw; + vec3 color = vec3(0.0); + vec2 dy = vec2(0.0, SourceSize1.w); + + float w; + float wsum = 0.0; + vec3 pixel; + float n = -SIZEV; + + do + { + pixel = COMPAT_TEXTURE(Source, tex + n*dy).rgb; + w = gaussian(n+f); + color = color + w * pixel; + wsum = wsum + w; + n = n + 1.0; + + } while (n <= SIZEV); + + color = color / wsum; + + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/linearize-ntsc.slang b/crt/shaders/guest/crt-gdv-new/linearize-ntsc.slang new file mode 100644 index 0000000..9cd1ce2 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/linearize-ntsc.slang @@ -0,0 +1,163 @@ +#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. + +*/ + +#pragma format R32G32B32A32_SFLOAT + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float decon; + float deconstr; + float GAMMA_INPUT; + float inter; + float interm; + float intres; + float inters; + float iscan; +} params; + +#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05 +#define GAMMA_INPUT params.GAMMA_INPUT + +#pragma parameter bogus_deconvergence "[ HORIZONTAL DECONVERGENCE ]:" 0.0 0.0 1.0 1.0 + +#pragma parameter decon " Horizontal Deconvergence Range" 1.0 -8.0 8.0 0.250 +#define decon params.decon // Horizontal deconvergence range + +#pragma parameter deconstr " Horizontal Deconvergence Strength" 0.0 0.0 1.0 0.05 +#define deconstr params.deconstr // Horizontal deconvergence strength + +#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0 + +#pragma parameter inter " Interlace Trigger Resolution :" 350.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 +#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 parameter intres " Internal Resolution: 1.0:240p, 1.5...y-dowsample" 0.0 0.0 4.0 0.5 // Joint parameter with main pass, values must match +#define intres params.intres // interlace resolution + +#define SourceSize params.SourceSize + +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.00001; +} + +#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; +} + + +void main() +{ + vec2 dx1 = vec2(1.0/SourceSize.x, 0.0)*decon; + vec2 dx2 = -dx1*decon; + vec2 dy = vec2(0.0, 1.0/SourceSize.y); + + vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb; + vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + dy).rgb; + + float r1 = COMPAT_TEXTURE(PrePass, vTexCoord + dx1).r; + float b1 = COMPAT_TEXTURE(PrePass, vTexCoord + dx2).b; + float r2 = COMPAT_TEXTURE(PrePass, vTexCoord + dx1 + dy).r; + float b2 = COMPAT_TEXTURE(PrePass, vTexCoord + dx2 + dy).b; + + vec3 res1 = c1; + vec3 res2 = c2; + + res1.rb = mix(c1.rb, vec2(r1,b1), deconstr); + res2.rb = mix(c2.rb, vec2(r2,b2), deconstr); + + vec3 res = res1; + float gamma_in = 1.0/GAMMA_INPUT; + float intera = 1.0; + + float yres_div = 1.0; if (intres > 1.25) yres_div = intres; + + if (inter < SourceSize.y/yres_div && interm > 0.5 && intres != 1.0) + { + intera = 0.5; + float line_no = floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)); + float frame_no = floor(mod(float(params.FrameCount),2.0)); + float ii = abs(line_no-frame_no); + + 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; + + if (interm < 3.5) + { + r = max(m1*ii, (1.0-iscan)*min(m1,m2)); + res = plant( mix(mix(res1,res2, min(mix(m1, (1.0-m2), min(m1,1.0-m1))/(d+0.00001),1.0)), res1, ii), r); + if (interm == 3.0) res = (1.0-0.5*iscan)*mix(res2, res1, ii); + intera = 0.0; + } + if (interm == 5.0) { res = mix(res2, res1, 0.5); intera = 0.5; } + + res = pow(res, vec3(GAMMA_INPUT*0.70)); + gamma_in = 1.0/(GAMMA_INPUT*0.70); + } + else res = pow(res, vec3(GAMMA_INPUT)); + + if (vTexCoord.x > 0.5) gamma_in = intera; + + FragColor = vec4(res, gamma_in); +} \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/linearize.slang b/crt/shaders/guest/crt-gdv-new/linearize.slang new file mode 100644 index 0000000..3327d5c --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/linearize.slang @@ -0,0 +1,133 @@ +#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. + +*/ + +#pragma format R32G32B32A32_SFLOAT + +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 :" 350.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 PrePass; + +#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(PrePass, vTexCoord).rgb; + vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, 1.0/params.OriginalSize.y)).rgb; + vec3 c = c1; + + float intera = 1.0; + float gamma_in = 1.0/GAMMA_INPUT; + + if (inter < params.OriginalSize.y && interm > 0.5) + { + intera = 0.5; + float line_no = floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)); + float frame_no = floor(mod(float(params.FrameCount),2.0)); + float ii = abs(line_no-frame_no); + + 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; + + if (interm < 3.5) + { + r = max(m1*ii, (1.0-iscan)*min(m1,m2)); + 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); intera = 0.5; } + + c = pow(c, vec3(GAMMA_INPUT*0.70)); + gamma_in = 1.0/(GAMMA_INPUT*0.70); + } + else c = pow(c, vec3(GAMMA_INPUT)); + + if (vTexCoord.x > 0.5) gamma_in = intera; + + FragColor = vec4(c, gamma_in); +} \ No newline at end of file diff --git a/crt/shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang b/crt/shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang new file mode 100644 index 0000000..e065f38 --- /dev/null +++ b/crt/shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang @@ -0,0 +1,316 @@ +#version 450 + +/* + CRT GDV 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; +} params; + +#pragma parameter AS " Afterglow Strength" 0.07 0.0 0.50 0.01 +#define AS params.AS + +#pragma parameter sat " Afterglow saturation" 0.10 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 TNTC " LUT Number/Colors (1.0-4.0)" 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 + +#pragma parameter LUTLOW " Fix LUT Dark - Range" 5.0 0.0 50.0 1.0 +#define LUTLOW params.LUTLOW + +#pragma parameter LUTBR " Fix LUT Brightness" 1.0 0.0 1.0 0.10 +#define LUTBR params.LUTBR + +#pragma parameter CP " CRT Color Profile" 0.0 -1.0 5.0 1.0 +#pragma parameter CS " Color Space: sRGB, DCI, Adobe, Rec.2020" 0.0 0.0 3.0 1.0 + +#define CP params.CP +#define CS params.CS + +#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 + +#define WP params.WP +#define wp_saturation params.wp_saturation + +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 ToDCI = +mat3( + 2.725394, -0.795168, 0.041242, +-1.018003, 1.689732, -0.087639, +-0.440163, 0.022647, 1.100929 +); + +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); +} + + +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; + + 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.4; m_out = ToSRGB; } else + if (CS == 1.0) { p = 2.6; m_out = ToDCI; } else + if (CS == 2.0) { p = 2.2; m_out = ToAdobe;} else + if (CS == 3.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; + + 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/fast/smoothing - kopija.slang new file mode 100644 index 0000000..6222be8 --- /dev/null +++ b/crt/shaders/guest/fast/smoothing - kopija.slang @@ -0,0 +1,84 @@ +#version 450 + +/* + Smart Smoothing Difference Shader + + Copyright (C) 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. + +*/ + +#pragma name SmoothPass + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float STH; +} 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) + +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; + +float df (vec3 A, vec3 B) +{ + 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); +} + +void main() +{ + vec2 dx = vec2(SourceSize.z, 0.0); + vec2 dy = vec2(0.0, SourceSize.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 dl = df(ct, l1); + float dr = df(ct, r1); + + float resx = dl; float resy = dr; + + FragColor = vec4(resx,resy,1.0,1.0); +} \ No newline at end of file diff --git a/crt/shaders/guest/fast/smoothing.slang b/crt/shaders/guest/fast/smoothing.slang index 6222be8..3c9d8f2 100644 --- a/crt/shaders/guest/fast/smoothing.slang +++ b/crt/shaders/guest/fast/smoothing.slang @@ -60,10 +60,8 @@ layout(set = 0, binding = 2) uniform sampler2D Source; float df (vec3 A, vec3 B) { - 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); + float diff = abs(A-B); float m = max(max(diff.r,diff.g),diff.b); + return smoothstep(0.0, 0.99, m); } void main() diff --git a/crt/shaders/guest/linearize.slang b/crt/shaders/guest/linearize.slang index c2e49ce..ca8c99d 100644 --- a/crt/shaders/guest/linearize.slang +++ b/crt/shaders/guest/linearize.slang @@ -5,7 +5,7 @@ layout(push_constant) uniform Push float GAMMA_INPUT; } params; -#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 0.1 5.0 0.05 +#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05 #define GAMMA_INPUT params.GAMMA_INPUT layout(std140, set = 0, binding = 0) uniform UBO @@ -29,10 +29,11 @@ layout(location = 0) in vec2 vTexCoord; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D AfterglowPass; -#define PassPrev3Texture AfterglowPass + #define COMPAT_TEXTURE(c,d) texture(c,d) void main() { - FragColor = pow(vec4(COMPAT_TEXTURE(PassPrev3Texture, vTexCoord)), vec4(GAMMA_INPUT)); + float gamma_in = 1.0/GAMMA_INPUT; + FragColor = vec4(pow(vec3(COMPAT_TEXTURE(AfterglowPass, vTexCoord)), vec3(GAMMA_INPUT)), gamma_in); } \ No newline at end of file diff --git a/crt/shaders/guest/lut/custom_lut.png b/crt/shaders/guest/lut/custom_lut.png new file mode 100644 index 0000000..b67e852 Binary files /dev/null and b/crt/shaders/guest/lut/custom_lut.png differ diff --git a/crt/shaders/crt-hyllian-3d.slang b/crt/shaders/hyllian/crt-hyllian-3d.slang similarity index 100% rename from crt/shaders/crt-hyllian-3d.slang rename to crt/shaders/hyllian/crt-hyllian-3d.slang diff --git a/crt/shaders/hyllian/crt-hyllian-curvature.slang b/crt/shaders/hyllian/crt-hyllian-curvature.slang new file mode 100644 index 0000000..c5caeb3 --- /dev/null +++ b/crt/shaders/hyllian/crt-hyllian-curvature.slang @@ -0,0 +1,260 @@ +#version 450 + +layout(push_constant) uniform Push +{ + float BEAM_PROFILE; + float HFILTER_PROFILE; + float BEAM_MIN_WIDTH; + float BEAM_MAX_WIDTH; + float SCANLINES_STRENGTH; + float COLOR_BOOST; + float HFILTER_SHARPNESS; + float PHOSPHOR_LAYOUT; + float MASK_INTENSITY; + float CRT_ANTI_RINGING; + float InputGamma; + float OutputGamma; + float VSCANLINES; + float CRT_CURVATURE; + float CRT_warpX; + float CRT_warpY; + float CRT_cornersize; + float CRT_cornersmooth; +} param; + +#pragma parameter BEAM_PROFILE "BEAM PROFILE (BP)" 0.0 0.0 6.0 1.0 +#pragma parameter HFILTER_PROFILE "HORIZONTAL FILTER PROFILE (HFP)" 0.0 0.0 6.0 1.0 +#pragma parameter BEAM_MIN_WIDTH " Custom [If BP=0.00] MIN BEAM WIDTH" 0.86 0.0 1.0 0.02 +#pragma parameter BEAM_MAX_WIDTH " Custom [If BP=0.00] MAX BEAM WIDTH" 1.0 0.0 1.0 0.02 +#pragma parameter SCANLINES_STRENGTH " Custom [If BP=0.00] SCANLINES STRENGTH" 0.58 0.0 1.0 0.02 +#pragma parameter COLOR_BOOST " Custom [If BP=0.00] COLOR BOOST" 1.25 1.0 2.0 0.05 +#pragma parameter HFILTER_SHARPNESS " Custom [If HFP=0.00] SHARPNESS" 1.0 0.0 1.0 0.02 +#pragma parameter PHOSPHOR_LAYOUT "PHOSPHOR LAYOUT" 4.0 0.0 19.0 1.0 +#pragma parameter MASK_INTENSITY "MASK INTENSITY" 0.5 0.0 1.0 0.1 +#pragma parameter CRT_ANTI_RINGING "ANTI RINGING" 1.0 0.0 1.0 0.1 +#pragma parameter InputGamma "INPUT GAMMA" 2.4 0.0 5.0 0.1 +#pragma parameter OutputGamma "OUTPUT GAMMA" 2.2 0.0 5.0 0.1 +#pragma parameter VSCANLINES "SCANLINES DIRECTION" 0.0 0.0 1.0 1.0 +#pragma parameter CRT_CURVATURE "CRT-Curvature" 1.0 0.0 1.0 1.0 +#pragma parameter CRT_warpX "CRT-Curvature X-Axis" 0.031 0.0 0.125 0.01 +#pragma parameter CRT_warpY "CRT-Curvature Y-Axis" 0.041 0.0 0.125 0.01 +vec2 CRT_Distortion = vec2(param.CRT_warpX, param.CRT_warpY) * 15.; +#pragma parameter CRT_cornersize "CRT-Corner Size" 0.01 0.001 1.0 0.005 +#define cornersize param.CRT_cornersize +#pragma parameter CRT_cornersmooth "CRT-Corner Smoothness" 1000.0 80.0 2000.0 100.0 +#define cornersmooth param.CRT_cornersmooth + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} 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 = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +/* + Hyllian's CRT Shader + + Copyright (C) 2011-2020 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "../../../include/subpixel_masks.h" + +#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) +#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) + + +const vec2 corner_aspect = vec2(1.0, 0.75); + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5)) + vec2(0.5, 0.5); + coord = min(coord, vec2(1.0) - coord) * corner_aspect; + vec2 cdist = vec2(cornersize); + coord = (cdist - min(coord, cdist)); + float dist = sqrt(dot(coord, coord)); + + return clamp((cdist.x - dist)*cornersmooth, 0.0, 1.0); +} + + +vec2 Warp(vec2 texCoord){ + + vec2 curvedCoords = texCoord * 2.0 - 1.0; + float curvedCoordsDistance = sqrt(curvedCoords.x*curvedCoords.x+curvedCoords.y*curvedCoords.y); + + curvedCoords = curvedCoords / curvedCoordsDistance; + + curvedCoords = curvedCoords * (1.0-pow(vec2(1.0-(curvedCoordsDistance/1.4142135623730950488016887242097)),(1.0/(1.0+CRT_Distortion*0.2)))); + + curvedCoords = curvedCoords / (1.0-pow(vec2(0.29289321881345247559915563789515),(1.0/(vec2(1.0)+CRT_Distortion*0.2)))); + + curvedCoords = curvedCoords * 0.5 + 0.5; + return curvedCoords; +} + + +// Horizontal cubic filter. +// Some known filters use these values: + +// B = 0.0, C = 0.0 => Hermite cubic filter. +// B = 1.0, C = 0.0 => Cubic B-Spline filter. +// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. This is the default used in this shader. +// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. +// B = 0.3782, C = 0.3109 => Robidoux filter. +// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. + +// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif +mat4x4 get_hfilter_profile() +{ + float bf = 1.0 - param.HFILTER_SHARPNESS; + float cf = param.HFILTER_SHARPNESS*0.5; // B+2C=1 Mitchel-Netravali recommendation line. + + if (param.HFILTER_PROFILE == 1) {bf = 0.0; cf = 0.0;} + if (param.HFILTER_PROFILE == 2) {bf = 0.0; cf = 0.5;} + if (param.HFILTER_PROFILE == 3) {bf = 0.2620; cf = 0.3690;} + if (param.HFILTER_PROFILE == 4) {bf = 1.0/3.0; cf = 1.0/3.0;} + if (param.HFILTER_PROFILE == 5) {bf = 0.3782; cf = 0.3109;} + if (param.HFILTER_PROFILE == 6) {bf = 1.0; cf = 0.0;} + + return mat4x4( (-bf - 6.0*cf)/6.0, (3.0*bf + 12.0*cf)/6.0, (-3.0*bf - 6.0*cf)/6.0, bf/6.0, + (12.0 - 9.0*bf - 6.0*cf)/6.0, (-18.0 + 12.0*bf + 6.0*cf)/6.0, 0.0, (6.0 - 2.0*bf)/6.0, + -(12.0 - 9.0*bf - 6.0*cf)/6.0, (18.0 - 15.0*bf - 12.0*cf)/6.0, (3.0*bf + 6.0*cf)/6.0, bf/6.0, + (bf + 6.0*cf)/6.0, -cf, 0.0, 0.0); + + +} + + +#define scanlines_strength (4.0*profile.x) +#define beam_min_width profile.y +#define beam_max_width profile.z +#define color_boost profile.w + +vec4 get_beam_profile() +{ + vec4 bp = vec4(param.SCANLINES_STRENGTH, param.BEAM_MIN_WIDTH, param.BEAM_MAX_WIDTH, param.COLOR_BOOST); + + if (param.BEAM_PROFILE == 1) bp = vec4(0.40, 1.00, 1.00, 1.00); // Catmull-rom +if (param.BEAM_PROFILE == 2) bp = vec4(0.72, 1.00, 1.00, 1.25); // Catmull-rom +if (param.BEAM_PROFILE == 3) bp = vec4(0.60, 0.50, 1.00, 1.25); // Hermite +if (param.BEAM_PROFILE == 4) bp = vec4(0.60, 0.72, 1.00, 1.25); // Hermite +if (param.BEAM_PROFILE == 5) bp = vec4(0.68, 0.68, 1.00, 1.25); // Hermite +if (param.BEAM_PROFILE == 6) bp = vec4(0.70, 0.50, 1.00, 1.80); // Catmull-rom + + return bp; +} + + +void main() +{ + vec4 profile = get_beam_profile(); + + vec2 TextureSize = vec2(global.SourceSize.x, global.SourceSize.y); + + vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); + vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); + + vec2 pp = vTexCoord.xy; + pp = (param.CRT_CURVATURE > 0.5) ? Warp(pp) : pp; + + + vec2 pix_coord = pp.xy*TextureSize + vec2(-0.5, 0.5); + + vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.0, -0.5))/TextureSize, param.VSCANLINES); + + vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); + + vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); + vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); + vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); + vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); + vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); + vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); + vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); + vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); + + mat4x4 invX = get_hfilter_profile(); + + mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); + mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); + + vec4 invX_Px = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0) * invX; + vec3 color0 = color_matrix0 * invX_Px; + vec3 color1 = color_matrix1 * invX_Px; + + // Get min/max samples + vec3 min_sample0 = min(c01,c02); + vec3 max_sample0 = max(c01,c02); + vec3 min_sample1 = min(c11,c12); + vec3 max_sample1 = max(c11,c12); + + // Anti-ringing + vec3 aux = color0; + color0 = clamp(color0, min_sample0, max_sample0); + color0 = mix(aux, color0, param.CRT_ANTI_RINGING); + aux = color1; + color1 = clamp(color1, min_sample1, max_sample1); + color1 = mix(aux, color1, param.CRT_ANTI_RINGING); + + float pos0 = fp.y; + float pos1 = 1 - fp.y; + + vec3 lum0 = mix(vec3(beam_min_width), vec3(beam_max_width), color0); + vec3 lum1 = mix(vec3(beam_min_width), vec3(beam_max_width), color1); + + vec3 d0 = scanlines_strength*pos0/(lum0+0.0000001); + vec3 d1 = scanlines_strength*pos1/(lum1+0.0000001); + + d0 = exp(-d0*d0); + d1 = exp(-d1*d1); + + vec3 color = color_boost*(color0*d0+color1*d1); + + vec2 mask_coords =vTexCoord.xy * global.OutputSize.xy; + + mask_coords = mix(mask_coords.xy, mask_coords.yx, param.VSCANLINES); + + color.rgb*=mask_weights(mask_coords, param.MASK_INTENSITY, int(param.PHOSPHOR_LAYOUT)); + + color = GAMMA_OUT(color); + + FragColor = vec4(color, 1.0); + + FragColor *= (param.CRT_CURVATURE > 0.5) ? corner(pp) : 1.0; +} diff --git a/crt/shaders/crt-hyllian-glow/crt-hyllian.slang b/crt/shaders/hyllian/crt-hyllian-glow/crt-hyllian.slang similarity index 100% rename from crt/shaders/crt-hyllian-glow/crt-hyllian.slang rename to crt/shaders/hyllian/crt-hyllian-glow/crt-hyllian.slang diff --git a/crt/shaders/crt-hyllian-glow/resolve2.slang b/crt/shaders/hyllian/crt-hyllian-glow/resolve2.slang similarity index 100% rename from crt/shaders/crt-hyllian-glow/resolve2.slang rename to crt/shaders/hyllian/crt-hyllian-glow/resolve2.slang diff --git a/crt/shaders/crt-hyllian-multipass/crt-hyllian-pass0.slang b/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass0.slang similarity index 100% rename from crt/shaders/crt-hyllian-multipass/crt-hyllian-pass0.slang rename to crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass0.slang diff --git a/crt/shaders/crt-hyllian-multipass/crt-hyllian-pass1.slang b/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass1.slang similarity index 100% rename from crt/shaders/crt-hyllian-multipass/crt-hyllian-pass1.slang rename to crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass1.slang diff --git a/crt/shaders/hyllian/crt-hyllian-sinc.slang b/crt/shaders/hyllian/crt-hyllian-sinc.slang new file mode 100644 index 0000000..1c55892 --- /dev/null +++ b/crt/shaders/hyllian/crt-hyllian-sinc.slang @@ -0,0 +1,197 @@ +#version 450 + +layout(push_constant) uniform Push +{ + float BEAM_PROFILE; +// float HFILTER_PROFILE; + float BEAM_MIN_WIDTH; + float BEAM_MAX_WIDTH; + float SCANLINES_STRENGTH; + float COLOR_BOOST; + float HFILTER_SHARPNESS; + float PHOSPHOR_LAYOUT; + float MASK_INTENSITY; + float CRT_ANTI_RINGING; + float InputGamma; + float OutputGamma; + float VSCANLINES; +} param; + +#pragma parameter BEAM_PROFILE "BEAM PROFILE (BP)" 0.0 0.0 3.0 1.0 +#pragma parameter BEAM_MIN_WIDTH " Custom [If BP=0.00] MIN BEAM WIDTH" 0.86 0.0 1.0 0.02 +#pragma parameter BEAM_MAX_WIDTH " Custom [If BP=0.00] MAX BEAM WIDTH" 1.0 0.0 1.0 0.02 +#pragma parameter SCANLINES_STRENGTH " Custom [If BP=0.00] SCANLINES STRENGTH" 0.72 0.0 1.0 0.02 +#pragma parameter COLOR_BOOST " Custom [If BP=0.00] COLOR BOOST" 1.25 1.0 2.0 0.05 +#pragma parameter HFILTER_SHARPNESS " Custom [If HFP=0.00] SHARPNESS" 1.0 0.0 1.0 0.02 +#pragma parameter PHOSPHOR_LAYOUT "PHOSPHOR LAYOUT" 4.0 0.0 19.0 1.0 +#pragma parameter MASK_INTENSITY "MASK INTENSITY" 0.5 0.0 1.0 0.1 +#pragma parameter CRT_ANTI_RINGING "ANTI RINGING" 1.0 0.0 1.0 0.1 +#pragma parameter InputGamma "INPUT GAMMA" 2.4 0.0 5.0 0.1 +#pragma parameter OutputGamma "OUTPUT GAMMA" 2.2 0.0 5.0 0.1 +#pragma parameter VSCANLINES "SCANLINES DIRECTION" 0.0 0.0 1.0 1.0 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} 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 = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +/* + Hyllian's CRT Shader + + Copyright (C) 2011-2020 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "../../../include/subpixel_masks.h" + +#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) +#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) + + +#define scanlines_strength (2.0*profile.x) +#define beam_min_width profile.y +#define beam_max_width profile.z +#define color_boost profile.w + +vec4 get_beam_profile() +{ + vec4 bp = vec4(param.SCANLINES_STRENGTH, param.BEAM_MIN_WIDTH, param.BEAM_MAX_WIDTH, param.COLOR_BOOST); + +if (param.BEAM_PROFILE == 1) bp = vec4(0.70, 0.58, 1.00, 1.25); +if (param.BEAM_PROFILE == 2) bp = vec4(0.70, 1.00, 1.00, 1.25); +if (param.BEAM_PROFILE == 3) bp = vec4(0.58, 1.00, 1.00, 1.25); + + return bp; +} + + +#define pi 3.1415926535897932384626433832795 +#define wa (0.5*pi) +#define wb (pi) + +vec4 resampler4(vec4 x) +{ + vec4 res; + res.x = (x.x<=0.001) ? wa*wb : sin(x.x*wa)*sin(x.x*wb)/(x.x*x.x); + res.y = (x.y<=0.001) ? wa*wb : sin(x.y*wa)*sin(x.y*wb)/(x.y*x.y); + res.z = (x.z<=0.001) ? wa*wb : sin(x.z*wa)*sin(x.z*wb)/(x.z*x.z); + res.w = (x.w<=0.001) ? wa*wb : sin(x.w*wa)*sin(x.w*wb)/(x.w*x.w); + return res; +} + +vec3 resampler3(vec3 x) +{ + vec3 res; + res.x = (x.x<=0.001) ? wa*wb : sin(x.x*wa)*sin(x.x*wb)/(x.x*x.x); + res.y = (x.y<=0.001) ? wa*wb : sin(x.y*wa)*sin(x.y*wb)/(x.y*x.y); + res.z = (x.z<=0.001) ? wa*wb : sin(x.z*wa)*sin(x.z*wb)/(x.z*x.z); + return res; +} + +void main() +{ + vec4 profile = get_beam_profile(); + + vec2 TextureSize = vec2(global.SourceSize.x, global.SourceSize.y); + + vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); + vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); + + vec2 pix_coord = vTexCoord*TextureSize + vec2(-0.5, 0.5); + + vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.0, -0.5))/TextureSize, param.VSCANLINES); + + vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); + + vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); + vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); + vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); + vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); + vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); + vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); + vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); + vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); + + mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); + mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); + + vec4 weights = resampler4(vec4(1.0+fp.x, fp.x, 1.0-fp.x, 2.0-fp.x)); + + vec3 color0 = (color_matrix0 * weights)/dot(weights, vec4(1.0)); + vec3 color1 = (color_matrix1 * weights)/dot(weights, vec4(1.0)); + + // Get min/max samples + vec3 min_sample0 = min(c01,c02); + vec3 max_sample0 = max(c01,c02); + vec3 min_sample1 = min(c11,c12); + vec3 max_sample1 = max(c11,c12); + + // Anti-ringing + vec3 aux = color0; + color0 = clamp(color0, min_sample0, max_sample0); + color0 = mix(aux, color0, param.CRT_ANTI_RINGING); + aux = color1; + color1 = clamp(color1, min_sample1, max_sample1); + color1 = mix(aux, color1, param.CRT_ANTI_RINGING); + + float pos0 = fp.y; + float pos1 = 1 - fp.y; + + vec3 lum0 = mix(vec3(beam_min_width), vec3(beam_max_width), color0); + vec3 lum1 = mix(vec3(beam_min_width), vec3(beam_max_width), color1); + + vec3 d0 = clamp(scanlines_strength*pos0/(lum0+0.0000001), 0.0, 1.0); + vec3 d1 = clamp(scanlines_strength*pos1/(lum1+0.0000001), 0.0, 1.0); + + d0 = resampler3(d0); + d1 = resampler3(d1); + + vec3 color = color_boost*(color0*d0+color1*d1)/(wa*wb); + + vec2 mask_coords = vTexCoord.xy * global.OutputSize.xy; + + mask_coords = mix(mask_coords.xy, mask_coords.yx, param.VSCANLINES); + + color.rgb*=mask_weights(mask_coords, param.MASK_INTENSITY, int(param.PHOSPHOR_LAYOUT)); + + color = GAMMA_OUT(color); + + FragColor = vec4(color, 1.0); +} diff --git a/crt/shaders/hyllian/crt-hyllian.slang b/crt/shaders/hyllian/crt-hyllian.slang new file mode 100644 index 0000000..13bfddc --- /dev/null +++ b/crt/shaders/hyllian/crt-hyllian.slang @@ -0,0 +1,214 @@ +#version 450 + +layout(push_constant) uniform Push +{ + float BEAM_PROFILE; + float HFILTER_PROFILE; + float BEAM_MIN_WIDTH; + float BEAM_MAX_WIDTH; + float SCANLINES_STRENGTH; + float COLOR_BOOST; + float HFILTER_SHARPNESS; + float PHOSPHOR_LAYOUT; + float MASK_INTENSITY; + float CRT_ANTI_RINGING; + float InputGamma; + float OutputGamma; + float VSCANLINES; +} param; + +#pragma parameter BEAM_PROFILE "BEAM PROFILE (BP)" 0.0 0.0 6.0 1.0 +#pragma parameter HFILTER_PROFILE "HORIZONTAL FILTER PROFILE (HFP)" 0.0 0.0 6.0 1.0 +#pragma parameter BEAM_MIN_WIDTH " Custom [If BP=0.00] MIN BEAM WIDTH" 0.86 0.0 1.0 0.02 +#pragma parameter BEAM_MAX_WIDTH " Custom [If BP=0.00] MAX BEAM WIDTH" 1.0 0.0 1.0 0.02 +#pragma parameter SCANLINES_STRENGTH " Custom [If BP=0.00] SCANLINES STRENGTH" 0.58 0.0 1.0 0.02 +#pragma parameter COLOR_BOOST " Custom [If BP=0.00] COLOR BOOST" 1.25 1.0 2.0 0.05 +#pragma parameter HFILTER_SHARPNESS " Custom [If HFP=0.00] SHARPNESS" 1.0 0.0 1.0 0.02 +#pragma parameter PHOSPHOR_LAYOUT "PHOSPHOR LAYOUT" 4.0 0.0 19.0 1.0 +#pragma parameter MASK_INTENSITY "MASK INTENSITY" 0.5 0.0 1.0 0.1 +#pragma parameter CRT_ANTI_RINGING "ANTI RINGING" 1.0 0.0 1.0 0.1 +#pragma parameter InputGamma "INPUT GAMMA" 2.4 0.0 5.0 0.1 +#pragma parameter OutputGamma "OUTPUT GAMMA" 2.2 0.0 5.0 0.1 +#pragma parameter VSCANLINES "SCANLINES DIRECTION" 0.0 0.0 1.0 1.0 + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} 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 = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +/* + Hyllian's CRT Shader + + Copyright (C) 2011-2020 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "../../../include/subpixel_masks.h" + +#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) +#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) + + + + +// Horizontal cubic filter. +// Some known filters use these values: + +// B = 0.0, C = 0.0 => Hermite cubic filter. +// B = 1.0, C = 0.0 => Cubic B-Spline filter. +// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. This is the default used in this shader. +// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. +// B = 0.3782, C = 0.3109 => Robidoux filter. +// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. + +// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif +mat4x4 get_hfilter_profile() +{ + float bf = 1.0 - param.HFILTER_SHARPNESS; + float cf = param.HFILTER_SHARPNESS*0.5; // B+2C=1 Mitchel-Netravali recommendation line. + + if (param.HFILTER_PROFILE == 1) {bf = 0.0; cf = 0.0;} + if (param.HFILTER_PROFILE == 2) {bf = 0.0; cf = 0.5;} + if (param.HFILTER_PROFILE == 3) {bf = 0.2620; cf = 0.3690;} + if (param.HFILTER_PROFILE == 4) {bf = 1.0/3.0; cf = 1.0/3.0;} + if (param.HFILTER_PROFILE == 5) {bf = 0.3782; cf = 0.3109;} + if (param.HFILTER_PROFILE == 6) {bf = 1.0; cf = 0.0;} + + return mat4x4( (-bf - 6.0*cf)/6.0, (3.0*bf + 12.0*cf)/6.0, (-3.0*bf - 6.0*cf)/6.0, bf/6.0, + (12.0 - 9.0*bf - 6.0*cf)/6.0, (-18.0 + 12.0*bf + 6.0*cf)/6.0, 0.0, (6.0 - 2.0*bf)/6.0, + -(12.0 - 9.0*bf - 6.0*cf)/6.0, (18.0 - 15.0*bf - 12.0*cf)/6.0, (3.0*bf + 6.0*cf)/6.0, bf/6.0, + (bf + 6.0*cf)/6.0, -cf, 0.0, 0.0); + + +} + + +#define scanlines_strength (4.0*profile.x) +#define beam_min_width profile.y +#define beam_max_width profile.z +#define color_boost profile.w + +vec4 get_beam_profile() +{ + vec4 bp = vec4(param.SCANLINES_STRENGTH, param.BEAM_MIN_WIDTH, param.BEAM_MAX_WIDTH, param.COLOR_BOOST); + + if (param.BEAM_PROFILE == 1) bp = vec4(0.40, 1.00, 1.00, 1.00); // Catmull-rom +if (param.BEAM_PROFILE == 2) bp = vec4(0.72, 1.00, 1.00, 1.25); // Catmull-rom +if (param.BEAM_PROFILE == 3) bp = vec4(0.60, 0.50, 1.00, 1.25); // Hermite +if (param.BEAM_PROFILE == 4) bp = vec4(0.60, 0.72, 1.00, 1.25); // Hermite +if (param.BEAM_PROFILE == 5) bp = vec4(0.68, 0.68, 1.00, 1.25); // Hermite +if (param.BEAM_PROFILE == 6) bp = vec4(0.70, 0.50, 1.00, 1.80); // Catmull-rom + + return bp; +} + + +void main() +{ + vec4 profile = get_beam_profile(); + + vec2 TextureSize = vec2(global.SourceSize.x, global.SourceSize.y); + + vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); + vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); + + vec2 pix_coord = vTexCoord.xy*TextureSize + vec2(-0.5, 0.5); + + vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.0, -0.5))/TextureSize, param.VSCANLINES); + + vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); + + vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); + vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); + vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); + vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); + vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); + vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); + vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); + vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); + + mat4x4 invX = get_hfilter_profile(); + + mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); + mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); + + vec4 invX_Px = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0) * invX; + vec3 color0 = color_matrix0 * invX_Px; + vec3 color1 = color_matrix1 * invX_Px; + + // Get min/max samples + vec3 min_sample0 = min(c01,c02); + vec3 max_sample0 = max(c01,c02); + vec3 min_sample1 = min(c11,c12); + vec3 max_sample1 = max(c11,c12); + + // Anti-ringing + vec3 aux = color0; + color0 = clamp(color0, min_sample0, max_sample0); + color0 = mix(aux, color0, param.CRT_ANTI_RINGING); + aux = color1; + color1 = clamp(color1, min_sample1, max_sample1); + color1 = mix(aux, color1, param.CRT_ANTI_RINGING); + + float pos0 = fp.y; + float pos1 = 1 - fp.y; + + vec3 lum0 = mix(vec3(beam_min_width), vec3(beam_max_width), color0); + vec3 lum1 = mix(vec3(beam_min_width), vec3(beam_max_width), color1); + + vec3 d0 = scanlines_strength*pos0/(lum0+0.0000001); + vec3 d1 = scanlines_strength*pos1/(lum1+0.0000001); + + d0 = exp(-d0*d0); + d1 = exp(-d1*d1); + + vec3 color = color_boost*(color0*d0+color1*d1); + + vec2 mask_coords =vTexCoord.xy * global.OutputSize.xy; + + mask_coords = mix(mask_coords.xy, mask_coords.yx, param.VSCANLINES); + + color.rgb*=mask_weights(mask_coords, param.MASK_INTENSITY, int(param.PHOSPHOR_LAYOUT)); + + color = GAMMA_OUT(color); + + FragColor = vec4(color, 1.0); +} diff --git a/crt/shaders/mame_hlsl/shaders/mame_parameters.inc b/crt/shaders/mame_hlsl/shaders/mame_parameters.inc index 435a3eb..18b3e65 100644 --- a/crt/shaders/mame_hlsl/shaders/mame_parameters.inc +++ b/crt/shaders/mame_hlsl/shaders/mame_parameters.inc @@ -146,6 +146,7 @@ layout(std140, set = 0, binding = 0) uniform UBO // float lengthratio; // float lengthscale; // float beamsmooth; + float TATE_toggle; } global; // Effect Toggles and Settings Used In Multiple Passes @@ -153,6 +154,8 @@ layout(std140, set = 0, binding = 0) uniform UBO bool NTSCSignal = bool(global.ntscsignal); #pragma parameter scanlinetoggle "Scanline Toggle" 1.0 0.0 1.0 1.0 bool ScanlineToggle = bool(global.scanlinetoggle); +#pragma parameter TATE_toggle "TATE Mode" 0.0 0.0 1.0 1.0 +bool TATE = bool(global.TATE_toggle); //#pragma parameter bloomtoggle "Bloom Enable" 0.0 0.0 1.0 1.0 //bool BloomToggle = bool(global.bloomtoggle); #pragma parameter chromatoggle "Chromaticity Toggle" 0.0 0.0 1.0 1.0 @@ -327,4 +330,4 @@ vec4 u_screen_offset = vec4(global.screenoffset_x, global.screenoffset_y, 0.,0.) vec4 u_screen_count = vec4(1.); vec4 u_screen_dims = vec4(params.OutputSize); vec4 u_quad_dims = params.FinalViewportSize; -vec4 u_time = vec4(params.FrameCount);//vec4(mod(params.FrameCount, global.time / 16.)); \ No newline at end of file +vec4 u_time = vec4(params.FrameCount);//vec4(mod(params.FrameCount, global.time / 16.)); diff --git a/crt/shaders/mame_hlsl/shaders/mame_post.slang b/crt/shaders/mame_hlsl/shaders/mame_post.slang index 7b31f99..ceb9779 100644 --- a/crt/shaders/mame_hlsl/shaders/mame_post.slang +++ b/crt/shaders/mame_hlsl/shaders/mame_post.slang @@ -128,6 +128,7 @@ void main() if (u_shadow_alpha.x > 0.0) { vec2 ShadowCoord = GetShadowCoord(v_texcoord0.xy, BaseCoord.xy); + ShadowCoord = (!TATE) ? ShadowCoord.xy : ShadowCoord.yx; vec4 ShadowColor = texture(s_shadow, ShadowCoord); vec3 ShadowMaskColor = mix(vec3(1.0, 1.0, 1.0), ShadowColor.rgb, u_shadow_alpha.xxx); @@ -161,4 +162,4 @@ void main() FragColor = vec4(BaseColor.rgb * v_color0.rgb, BaseColor.a); } -} \ No newline at end of file +} diff --git a/crt/shaders/mame_hlsl/shaders/mame_scanline.slang b/crt/shaders/mame_hlsl/shaders/mame_scanline.slang index 0e7fea8..1828cb1 100644 --- a/crt/shaders/mame_hlsl/shaders/mame_scanline.slang +++ b/crt/shaders/mame_hlsl/shaders/mame_scanline.slang @@ -91,7 +91,7 @@ void main() float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b; - float ScanCoord = BaseCoord.y; + float ScanCoord = (!TATE) ? BaseCoord.y : BaseCoord.x; ScanCoord += (global.scanline_crawl > 0.0) ? -1.* u_time.x * params.OutputSize.w * u_jitter_amount.x : 0.0; ScanCoord += u_swap_xy.x > 0.0 ? u_quad_dims.x <= u_source_dims.x * 2.0 @@ -114,4 +114,4 @@ void main() FragColor = vec4(BaseColor.rgb * v_color0.rgb, BaseColor.a); } -} \ No newline at end of file +} diff --git a/dithering/shaders/sgenpt-mix.slang b/dithering/shaders/sgenpt-mix.slang index b7120ae..d13fc93 100644 --- a/dithering/shaders/sgenpt-mix.slang +++ b/dithering/shaders/sgenpt-mix.slang @@ -1,7 +1,7 @@ #version 450 /* - SGENPT-MIX - Sega Genesis Pseudo Transparency Mixer Shader - v4 + SGENPT-MIX - Sega Genesis Pseudo Transparency Mixer Shader - v8b 2011-2020 Hyllian - sergiogdb@gmail.com @@ -32,14 +32,29 @@ layout(push_constant) uniform Push vec4 OriginalSize; vec4 OutputSize; uint FrameCount; - float SGPT_SHARPNESS; float SGPT_BLEND_OPTION; + float SGPT_BLEND_LEVEL; + float SGPT_ADJUST_VIEW; + float SGPT_LINEAR_GAMMA; } params; -#pragma parameter SGPT_SHARPNESS "SGENPT-MIX Sharpness" 1.0 0.0 1.0 0.1 -#pragma parameter SGPT_BLEND_OPTION "OFF | Transparency | Checkerboard" 1.0 0.0 2.0 1.0 -#define SGPT_SHARPNESS params.SGPT_SHARPNESS +#pragma parameter SGPT_BLEND_OPTION "0.OFF | 1.VL | 2.CB | 3.CB-S | 4.Both | 5.Both2 | 6.Both-S" 4.0 0.0 6.0 1.0 +#pragma parameter SGPT_BLEND_LEVEL "SGENPT-MIX Both Blend Level" 1.0 0.0 1.0 0.1 +#pragma parameter SGPT_ADJUST_VIEW "SGENPT-MIX Adjust View" 0.0 0.0 1.0 1.0 +#pragma parameter SGPT_LINEAR_GAMMA "SGENPT-MIX Use Linear Gamma" 1.0 0.0 1.0 1.0 #define SGPT_BLEND_OPTION params.SGPT_BLEND_OPTION +#define SGPT_BLEND_LEVEL params.SGPT_BLEND_LEVEL +#define SGPT_ADJUST_VIEW params.SGPT_ADJUST_VIEW +#define SGPT_LINEAR_GAMMA params.SGPT_LINEAR_GAMMA + +#define GAMMA_EXP (SGPT_LINEAR_GAMMA+1.0) +#define GAMMA_IN(color) pow(color, vec3(GAMMA_EXP, GAMMA_EXP, GAMMA_EXP)) +#define GAMMA_OUT(color) pow(color, vec3(1.0 / GAMMA_EXP, 1.0 / GAMMA_EXP, 1.0 / GAMMA_EXP)) + +const vec3 Y = vec3(.2126, .7152, .0722); + +vec3 min_s(vec3 central, vec3 adj1, vec3 adj2) {return min(central, max(adj1, adj2));} +vec3 max_s(vec3 central, vec3 adj1, vec3 adj2) {return max(central, min(adj1, adj2));} layout(std140, set = 0, binding = 0) uniform UBO { @@ -69,36 +84,79 @@ void main() vec2 dy = vec2(0.0, 1.0)*params.SourceSize.zw; // Reading the texels. - vec3 C = texture(Source, vTexCoord ).xyz; - vec3 L = texture(Source, vTexCoord -dx).xyz; - vec3 R = texture(Source, vTexCoord +dx).xyz; - vec3 U = texture(Source, vTexCoord -dy).xyz; - vec3 D = texture(Source, vTexCoord +dy).xyz; + vec3 C = GAMMA_IN(texture(Source, vTexCoord ).xyz); + vec3 L = GAMMA_IN(texture(Source, vTexCoord -dx).xyz); + vec3 R = GAMMA_IN(texture(Source, vTexCoord +dx).xyz); + vec3 U = GAMMA_IN(texture(Source, vTexCoord -dy).xyz); + vec3 D = GAMMA_IN(texture(Source, vTexCoord +dy).xyz); + vec3 UL = GAMMA_IN(texture(Source, vTexCoord -dx -dy).xyz); + vec3 UR = GAMMA_IN(texture(Source, vTexCoord +dx -dy).xyz); + vec3 DL = GAMMA_IN(texture(Source, vTexCoord -dx +dy).xyz); + vec3 DR = GAMMA_IN(texture(Source, vTexCoord +dx +dy).xyz); vec3 color = C; - if (SGPT_BLEND_OPTION > 0.0) + // Get min/max samples + vec3 min_sample = min_s(C, L, R); + vec3 max_sample = max_s(C, L, R); + + float diff = dot(max(max(C, L), max(C, R)) - min(min(C, L), min(C, R)), Y); + + if (SGPT_BLEND_OPTION == 1) // Only Vertical Lines { - // Get min/max samples - vec3 min_sample = min(C, max(L, R)); - vec3 max_sample = max(C, min(L, R)); + min_sample = max_s(min_sample, min_s(C, DL, DR), min_s(C, UL, UR)); + max_sample = min_s(max_sample, max_s(C, DL, DR), max_s(C, UL, UR)); - color = 0.5*C + 0.25*(L + R); + diff *= (1.0 - SGPT_BLEND_LEVEL); - if (SGPT_BLEND_OPTION > 1.0) - { - // Get min/max samples - min_sample = max(min_sample, min(C, max(U, D))); - max_sample = min(max_sample, max(C, min(U, D))); + color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); + } + else if (SGPT_BLEND_OPTION == 2) // Only Checkerboard + { + min_sample = max(min_sample, min_s(C, U, D)); + max_sample = min(max_sample, max_s(C, U, D)); - color = 0.5*C + 0.125*(L + R + U + D); - } + diff *= (1.0 - SGPT_BLEND_LEVEL); - // Sharpness control - vec3 aux = color; - color = clamp(color, min_sample, max_sample); - color = mix(aux, color, SGPT_SHARPNESS); + color = 0.5*( 1.0 + diff )*C + 0.125*( 1.0 - diff )*(L + R + U + D); + } + else if (SGPT_BLEND_OPTION == 3) // Only Checkerboard - Soft + { + min_sample = min_s(min_sample, U, D); + max_sample = max_s(max_sample, U, D); + + diff *= (1.0 - SGPT_BLEND_LEVEL); + + color = 0.5*( 1.0 + diff )*C + 0.125*( 1.0 - diff )*(L + R + U + D); + } + else if (SGPT_BLEND_OPTION == 4) // VL-CB + { + diff *= (1.0 - SGPT_BLEND_LEVEL); + + color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); + } + else if (SGPT_BLEND_OPTION == 5) // VL-CB-2 + { + min_sample = min_s(min_sample, U, D); + max_sample = max_s(max_sample, U, D); + + diff *= (1.0 - SGPT_BLEND_LEVEL); + + color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); + } + else if (SGPT_BLEND_OPTION == 6) // VL-CB-Soft + { + min_sample = min(min_sample, min(min_s(D, DL, DR), min_s(U, UL, UR))); + max_sample = max(max_sample, max(max_s(D, DL, DR), max_s(U, UL, UR))); + + diff *= (1.0 - SGPT_BLEND_LEVEL); + + color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); } - FragColor = vec4(color, 1.0); + color = clamp(color, min_sample, max_sample); + + color = mix(color, vec3(dot(abs(C-color), vec3(1.0, 1.0, 1.0))), SGPT_ADJUST_VIEW); + + FragColor = vec4(GAMMA_OUT(color), 1.0); } diff --git a/presets/crt-guest-dr-venom2-hires.slangp b/presets/crt-guest-dr-venom2-hires.slangp new file mode 100644 index 0000000..fcdc08b --- /dev/null +++ b/presets/crt-guest-dr-venom2-hires.slangp @@ -0,0 +1,64 @@ +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 new file mode 100644 index 0000000..da20a9a --- /dev/null +++ b/presets/crt-guest-dr-venom2-ntsc.slangp @@ -0,0 +1,81 @@ +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 diff --git a/presets/crt-hyllian-curvature-ntsc.slangp b/presets/crt-hyllian-curvature-ntsc.slangp new file mode 100644 index 0000000..dc93893 --- /dev/null +++ b/presets/crt-hyllian-curvature-ntsc.slangp @@ -0,0 +1,100 @@ +shaders = "7" +shader0 = "../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +frame_count_mod0 = "2" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "true" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "4.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +shader1 = "../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "true" +scale_type_x1 = "source" +scale_x1 = "0.500000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "../crt/shaders/hyllian/crt-hyllian-curvature.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_border" +mipmap_input2 = "false" +alias2 = "CRTPass" +float_framebuffer2 = "false" +srgb_framebuffer2 = "true" +scale_type_x2 = "viewport" +scale_x2 = "1.000000" +scale_type_y2 = "viewport" +scale_y2 = "1.000000" +shader3 = "../crt/shaders/glow/threshold.slang" +filter_linear3 = "false" +wrap_mode3 = "clamp_to_border" +mipmap_input3 = "false" +alias3 = "" +float_framebuffer3 = "false" +srgb_framebuffer3 = "true" +shader4 = "../crt/shaders/glow/blur_horiz.slang" +filter_linear4 = "true" +wrap_mode4 = "clamp_to_border" +mipmap_input4 = "true" +alias4 = "" +float_framebuffer4 = "false" +srgb_framebuffer4 = "true" +scale_type_x4 = "viewport" +scale_x4 = "0.200000" +scale_type_y4 = "viewport" +scale_y4 = "0.200000" +shader5 = "../crt/shaders/glow/blur_vert.slang" +filter_linear5 = "true" +wrap_mode5 = "clamp_to_border" +mipmap_input5 = "false" +alias5 = "" +float_framebuffer5 = "false" +srgb_framebuffer5 = "true" +shader6 = "../crt/shaders/glow/resolve.slang" +filter_linear6 = "true" +wrap_mode6 = "clamp_to_border" +mipmap_input6 = "false" +alias6 = "" +float_framebuffer6 = "false" +srgb_framebuffer6 = "false" +parameters = "linearize;BEAM_PROFILE;HFILTER_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;HFILTER_SHARPNESS;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES;CRT_CURVATURE;CRT_warpX;CRT_warpY;CRT_cornersize;CRT_cornersmooth;GLOW_WHITEPOINT;GLOW_ROLLOFF;BLOOM_STRENGTH;OUTPUT_GAMMA;CURVATURE;warpX;warpY;cornersize;cornersmooth;noise_amt;shadowMask;maskDark;maskLight" +BEAM_PROFILE = "0.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BEAM_MAX_WIDTH = "1.000000" +SCANLINES_STRENGTH = "0.580000" +COLOR_BOOST = "1.250000" +HFILTER_SHARPNESS = "1.000000" +PHOSPHOR_LAYOUT = "4.000000" +MASK_INTENSITY = "0.500000" +CRT_ANTI_RINGING = "1.000000" +InputGamma = "1.000000" +OutputGamma = "1.000000" +VSCANLINES = "0.000000" +CRT_CURVATURE = "1.000000" +CRT_warpX = "0.031000" +CRT_warpY = "0.041000" +CRT_cornersize = "0.010000" +CRT_cornersmooth = "1000.000000" +GLOW_WHITEPOINT = "0.500000" +GLOW_ROLLOFF = "1.200000" +BLOOM_STRENGTH = "0.100000" +OUTPUT_GAMMA = "2.200000" +CURVATURE = "0.000000" +warpX = "0.031000" +warpY = "0.041000" +cornersize = "0.010000" +cornersmooth = "1000.000000" +noise_amt = "1.000000" +shadowMask = "0.000000" +maskDark = "0.500000" +maskLight = "1.500000" +linearize = "1.0" diff --git a/presets/crt-hyllian-sinc-smartblur-sgenpt.slangp b/presets/crt-hyllian-sinc-smartblur-sgenpt.slangp new file mode 100644 index 0000000..b0c34c4 --- /dev/null +++ b/presets/crt-hyllian-sinc-smartblur-sgenpt.slangp @@ -0,0 +1,63 @@ +shaders = "4" +shader0 = "../dithering/shaders/sgenpt-mix.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "2.000000" +scale_type_y0 = "source" +scale_y0 = "2.000000" +shader1 = "../blurs/smart-blur.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "false" +scale_type_x1 = "source" +scale_x1 = "1.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "../stock.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_border" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "false" +scale_type_x2 = "source" +scale_x2 = "0.500000" +scale_type_y2 = "source" +scale_y2 = "0.500000" +shader3 = "../crt/shaders/hyllian/crt-hyllian-sinc.slang" +filter_linear3 = "false" +wrap_mode3 = "clamp_to_border" +mipmap_input3 = "false" +alias3 = "" +float_framebuffer3 = "false" +srgb_framebuffer3 = "false" +parameters = "SGPT_BLEND_OPTION;SGPT_BLEND_LEVEL;SGPT_ADJUST_VIEW;SGPT_LINEAR_GAMMA;SB_BLUR_LEVEL;SB_RED_THRESHOLD;SB_GREEN_THRESHOLD;SB_BLUE_THRESHOLD;BEAM_PROFILE;HFILTER_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;HFILTER_SHARPNESS;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES" +SGPT_BLEND_OPTION = "2.000000" +SGPT_BLEND_LEVEL = "0.200000" +SGPT_ADJUST_VIEW = "0.000000" +SGPT_LINEAR_GAMMA = "1.000000" +SB_BLUR_LEVEL = "0.660000" +SB_RED_THRESHOLD = "0.200000" +SB_GREEN_THRESHOLD = "0.200000" +SB_BLUE_THRESHOLD = "0.200000" +BEAM_PROFILE = "0.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BEAM_MAX_WIDTH = "1.000000" +SCANLINES_STRENGTH = "0.720000" +COLOR_BOOST = "1.250000" +HFILTER_SHARPNESS = "1.000000" +PHOSPHOR_LAYOUT = "4.000000" +MASK_INTENSITY = "0.500000" +CRT_ANTI_RINGING = "1.000000" +InputGamma = "2.400000" +OutputGamma = "2.200000" +VSCANLINES = "0.000000" diff --git a/presets/crt-hyllian-smartblur-sgenpt.slangp b/presets/crt-hyllian-smartblur-sgenpt.slangp new file mode 100644 index 0000000..7131880 --- /dev/null +++ b/presets/crt-hyllian-smartblur-sgenpt.slangp @@ -0,0 +1,63 @@ +shaders = "4" +shader0 = "../dithering/shaders/sgenpt-mix.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "2.000000" +scale_type_y0 = "source" +scale_y0 = "2.000000" +shader1 = "../blurs/smart-blur.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "false" +scale_type_x1 = "source" +scale_x1 = "1.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "../stock.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_border" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "false" +scale_type_x2 = "source" +scale_x2 = "0.500000" +scale_type_y2 = "source" +scale_y2 = "0.500000" +shader3 = "../crt/shaders/hyllian/crt-hyllian.slang" +filter_linear3 = "false" +wrap_mode3 = "clamp_to_border" +mipmap_input3 = "false" +alias3 = "" +float_framebuffer3 = "false" +srgb_framebuffer3 = "false" +parameters = "SGPT_BLEND_OPTION;SGPT_BLEND_LEVEL;SGPT_ADJUST_VIEW;SGPT_LINEAR_GAMMA;SB_BLUR_LEVEL;SB_RED_THRESHOLD;SB_GREEN_THRESHOLD;SB_BLUE_THRESHOLD;BEAM_PROFILE;HFILTER_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;HFILTER_SHARPNESS;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES" +SGPT_BLEND_OPTION = "2.000000" +SGPT_BLEND_LEVEL = "0.200000" +SGPT_ADJUST_VIEW = "0.000000" +SGPT_LINEAR_GAMMA = "1.000000" +SB_BLUR_LEVEL = "0.660000" +SB_RED_THRESHOLD = "0.200000" +SB_GREEN_THRESHOLD = "0.200000" +SB_BLUE_THRESHOLD = "0.200000" +BEAM_PROFILE = "0.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BEAM_MAX_WIDTH = "1.000000" +SCANLINES_STRENGTH = "0.580000" +COLOR_BOOST = "1.250000" +HFILTER_SHARPNESS = "1.000000" +PHOSPHOR_LAYOUT = "4.000000" +MASK_INTENSITY = "0.500000" +CRT_ANTI_RINGING = "1.000000" +InputGamma = "2.400000" +OutputGamma = "2.200000" +VSCANLINES = "0.000000"