diff --git a/README.md b/README.md index ff87b71..d0056a9 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -# uborder \ No newline at end of file +## uborder shaders - Hyllian 2024 +
+
+#### How to install and use: +
+1) Update your Retroarch shaders online to get a vanilha version of uborder inside 'shaders_slang/bezel/'; +2) On Retroarch, choose 'FULL' aspect ratio; +3) Choose your preset and enjoy. + +Refer to https://forums.libretro.com/t/uborder-shaders/46494/23 to get info about installing extra packs. + +#### Licensing + +All presets are public domain. + +Shaders and textures are individually licensed according to their authors. diff --git a/ambient-light-crt.slangp b/ambient-light-crt.slangp new file mode 100644 index 0000000..33e640e --- /dev/null +++ b/ambient-light-crt.slangp @@ -0,0 +1,5 @@ +# If you want to use another base-preset, change the reference path here. + +#reference "base_presets/ambient-light/ambient-light-crt-nobody.slangp" +//#reference "base_presets/ambient-light/ambient-light-crt-geom.slangp" + diff --git a/base_presets/ambient-light/ambient-light-crt-nobody.slangp b/base_presets/ambient-light/ambient-light-crt-nobody.slangp new file mode 100644 index 0000000..3b28e83 --- /dev/null +++ b/base_presets/ambient-light/ambient-light-crt-nobody.slangp @@ -0,0 +1,63 @@ +# ambient-light + +shaders = "5" + +feedback_pass = "0" +shader0 = "../../shaders/support_shaders/feedback.slang" +filter_linear0 = "true" +scale_type0 = "source" +scale0 = "1.000000" + +shader1 = "../../shaders/support_shaders/ambient-light.slang" +filter_linear1 = "true" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "true" +alias1 = "BORDER" +scale_type1 = "source" +scale1 = "4.000000" + +shader2 = "../../shaders/support_shaders/original.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_border" +mipmap_input2 = "false" +alias2 = "OriginalFake" +float_framebuffer2 = "false" +srgb_framebuffer2 = "false" +scale_type_x2 = "source" +scale_x2 = "0.250000" +scale_type_y2 = "source" +scale_y2 = "0.250000" + +shader3 = "../../shaders/content_shaders/crt-nobody.slang" +filter_linear3 = "false" +wrap_mode3 = "clamp_to_border" +mipmap_input3 = "false" +alias3 = "CRTPass" +float_framebuffer3 = "false" +srgb_framebuffer3 = "false" +scale_type_x3 = "viewport" +scale_x3 = "1.000000" +scale_type_y3 = "viewport" +scale_y3 = "1.000000" + +shader4 = "../../shaders/uborder.slang" +filter_linear4 = "true" +wrap_mode4 = "clamp_to_border" +mipmap_input4 = "false" +alias4 = "" +float_framebuffer4 = "false" +srgb_framebuffer4 = "false" +scale_type_x4 = "viewport" +scale_x4 = "1.000000" +scale_type_y4 = "viewport" +scale_y4 = "1.000000" + + +mixfactor = "0.950000" +AG_effect = "1.300000" +geom_curvature = "1.000000" +geom_R = "4.000000" +geom_d = "1.000000" +geom_cornersize = "0.016000" +geom_cornersmooth = "280.000000" +ub_border_top = "0.000000" diff --git a/base_presets/uborder-reflections/uborder-reflections-crt-nobody.slangp b/base_presets/uborder-reflections/uborder-reflections-crt-nobody.slangp new file mode 100644 index 0000000..636e7c1 --- /dev/null +++ b/base_presets/uborder-reflections/uborder-reflections-crt-nobody.slangp @@ -0,0 +1,60 @@ +# uborder-reflections + +shaders = "3" + +shader0 = "../../shaders/content_shaders/crt-nobody.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "CRTPass" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "viewport" +scale_x0 = "1.000000" +scale_type_y0 = "viewport" +scale_y0 = "1.000000" + +shader1 = "../../shaders/support_shaders/noshame-blur.slang" +filter_linear1 = "true" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "true" +alias1 = "BlurPass" +float_framebuffer1 = "false" +srgb_framebuffer1 = "false" +scale_type_x1 = "viewport" +scale_x1 = "0.250000" +scale_type_y1 = "viewport" +scale_y1 = "0.250000" + +shader2 = "../../shaders/uborder-reflections.slang" +filter_linear2 = "true" +wrap_mode2 = "clamp_to_border" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "false" +scale_type_x2 = "viewport" +scale_x2 = "1.000000" +scale_type_y2 = "viewport" +scale_y2 = "1.000000" + + + +textures = "BORDER" +BORDER = "../../textures/borders/default.jpg" + +box_scale = "2.980000" +in_res_x = "326.000000" +geom_center_y = "0.010000" +geom_curvature = "1.000000" +geom_R = "2.000000" +geom_cornersize = "0.011000" +geom_cornersmooth = "280.000000" +CN_VIG_TOGGLE = "1.000000" +CN_VIG_EXP = "0.080000" +reflection_strength = "0.250000" +frame_w = "0.495000" +frame_h = "0.654000" +bezel_w = "0.017000" +bezel_h = "0.014000" +bezel_center_y = "0.005000" diff --git a/base_presets/uborder/uborder-crt-nobody.slangp b/base_presets/uborder/uborder-crt-nobody.slangp new file mode 100644 index 0000000..99ecf89 --- /dev/null +++ b/base_presets/uborder/uborder-crt-nobody.slangp @@ -0,0 +1,52 @@ +# uborder-crt-nobody + +shaders = "2" + +shader0 = "../../shaders/content_shaders/crt-nobody.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "CRTPass" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "viewport" +scale_x0 = "1.000000" +scale_type_y0 = "viewport" +scale_y0 = "1.000000" + +shader1 = "../../shaders/uborder.slang" +filter_linear1 = "true" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "false" +scale_type_x1 = "viewport" +scale_x1 = "1.000000" +scale_type_y1 = "viewport" +scale_y1 = "1.000000" + +textures = "BORDER" +BORDER = "../../textures/borders/default.jpg" + +#geom_curvature = "1.000000" +#geom_R = "5.000000" +#geom_d = "1.500000" +#geom_cornersize = "0.006000" +#geom_cornersmooth = "180.000000" +#box_scale = "3.420000" +#geom_center_x = "-0.011000" +#geom_center_y = "-0.082000" +#CN_VIG_EXP = "0.080000" +#CN_VIG_TOGGLE = "1.000000" + +ub_border_top = "0.000000" +box_scale = "2.980000" +in_res_x = "326.000000" +geom_center_y = "0.010000" +geom_curvature = "1.000000" +geom_R = "2.000000" +geom_cornersize = "0.011000" +geom_cornersmooth = "280.000000" +CN_VIG_TOGGLE = "1.000000" +CN_VIG_EXP = "0.080000" diff --git a/shaders/content_shaders/crt-nobody.slang b/shaders/content_shaders/crt-nobody.slang new file mode 100644 index 0000000..5f3cbcb --- /dev/null +++ b/shaders/content_shaders/crt-nobody.slang @@ -0,0 +1,382 @@ +#version 450 + +/* + Hyllian's crt-nobody Shader - tweaked to work with borders and curvature + + Copyright (C) 2011-2024 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. +*/ + +layout(push_constant) uniform Push +{ + float CN_VSCANLINES; + float CN_BEAM_MIN_WIDTH; + float CN_BEAM_MAX_WIDTH; + float CN_SCAN_SIZE; + float CN_BRIGHTBOOST; + float CN_VIG_TOGGLE; + float CN_VIG_BASE; + float CN_VIG_EXP; + float CN_InputGamma; + float CN_OutputGamma; + float geom_d; + float geom_R; + float geom_cornersize; + float geom_cornersmooth; + float geom_x_tilt; + float geom_y_tilt; + float geom_overscan_x; + float geom_overscan_y; + float geom_center_x; + float geom_center_y; + float geom_inner_center_x; + float geom_inner_center_y; + float geom_curvature; + float geom_invert_aspect; + float box_scale; + float in_res_x; + float in_res_y; +} params; + +#pragma parameter frame_nonono "FRAME:" 0.0 0.0 1.0 1.0 +#pragma parameter box_scale " Image Scale" 4.0 1.0 10.0 0.02 +#pragma parameter in_res_x " Viewport Size X" 320.0 100.0 600.0 1.0 +#pragma parameter in_res_y " Viewport Size Y" 240.0 64.0 512.0 1.0 +#pragma parameter geom_center_x " Center X" 0.0 -1.0 1.0 0.001 +#pragma parameter geom_center_y " Center Y" 0.0 -1.0 1.0 0.01 + +#pragma parameter geom_nonono "GEOM'S CURVATURE:" 0.0 0.0 1.0 1.0 +#pragma parameter geom_curvature " Curvature Toggle" 0.0 0.0 1.0 1.0 +#pragma parameter geom_R " Curvature Radius" 2.0 0.3 10.0 0.1 +#pragma parameter geom_d " Distance" 1.5 0.1 3.0 0.1 +#pragma parameter geom_invert_aspect " Curvature Aspect Inversion" 0.0 0.0 1.0 1.0 +#pragma parameter geom_cornersize " Corner Size" 0.006 0.006 1.0 0.005 +#pragma parameter geom_cornersmooth " Corner Smoothness" 400.0 80.0 2000.0 100.0 +#pragma parameter geom_x_tilt " Horizontal Tilt" 0.0 -0.5 0.5 0.01 +#pragma parameter geom_y_tilt " Vertical Tilt" 0.0 -0.5 0.5 0.01 +#pragma parameter geom_inner_center_x " Inner Center X" 0.0 -1.0 1.0 0.001 +#pragma parameter geom_inner_center_y " Inner Center Y" 0.0 -1.0 1.0 0.001 +#pragma parameter geom_overscan_x " Horiz. Overscan %" 100.0 -125.0 125.0 0.5 +#pragma parameter geom_overscan_y " Vert. Overscan %" 100.0 -125.0 125.0 0.5 + +#pragma parameter CN_NONONO "CRT-NOBODY:" 0.0 0.0 1.0 1.0 +#pragma parameter CN_VSCANLINES " Vertical Scanlines" 0.0 0.0 1.0 1.0 +#pragma parameter CN_BEAM_MIN_WIDTH " Min Beam Width" 0.80 0.0 1.0 0.01 +#pragma parameter CN_BEAM_MAX_WIDTH " Max Beam Width" 1.0 0.0 1.0 0.01 +#pragma parameter CN_SCAN_SIZE " Scanlines Thickness" 0.86 0.0 1.0 0.01 +#pragma parameter CN_BRIGHTBOOST " Brightness Boost" 1.0 0.5 1.5 0.01 +#pragma parameter CN_VIG_TOGGLE " Vignette Toggle" 0.0 0.0 1.0 1.0 +#pragma parameter CN_VIG_BASE " Vignette Range" 16.0 2.0 100.0 2.0 +#pragma parameter CN_VIG_EXP " Vignette Strength" 0.16 0.0 2.0 0.02 +#pragma parameter CN_InputGamma " Input Gamma" 2.4 0.0 4.0 0.1 +#pragma parameter CN_OutputGamma " Output Gamma" 2.2 0.0 3.0 0.1 + + +#define CN_VSCANLINES params.CN_VSCANLINES +#define CN_BEAM_MIN_WIDTH params.CN_BEAM_MIN_WIDTH +#define CN_BEAM_MAX_WIDTH params.CN_BEAM_MAX_WIDTH +#define CN_SCAN_SIZE params.CN_SCAN_SIZE +#define CN_BRIGHTBOOST params.CN_BRIGHTBOOST +#define CN_InputGamma params.CN_InputGamma +#define CN_OutputGamma params.CN_OutputGamma + +#define GAMMA_IN(color) CN_BRIGHTBOOST*pow(color, vec3(CN_InputGamma)) +#define GAMMA_OUT(color) pow(color, vec3(1.0 / CN_OutputGamma)) + +#define PIX_SIZE 1.111111 + +#define CN_OFFSET 0.5 +#define CN_SCAN_OFFSET 0.0 + + +float pix_sizex = mix(PIX_SIZE, CN_SCAN_SIZE, CN_VSCANLINES); +float scan_sizey = mix(CN_SCAN_SIZE, PIX_SIZE, CN_VSCANLINES); + +layout(std140, set = 0, binding = 0) uniform UBO +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + mat4 MVP; +} global; + +// Macros. +#define FIX(c) max(abs(c), 1e-5); +#define PI 3.141592653589 + + +// aspect ratio +vec2 aspect = vec2(params.geom_invert_aspect > 0.5 ? (0.75, 1.0) : (1.0, 0.75)); +vec2 overscan = vec2(1.01, 1.01); + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec2 sinangle; +layout(location = 2) out vec2 cosangle; +layout(location = 3) out vec3 stretch; +layout(location = 4) out float R_d_cx_cy; +layout(location = 5) out float d2; +layout(location = 6) out vec4 intl_profile; + +vec4 get_interlace_profile() +{ + vec4 int_p = vec4(global.SourceSize.y, global.SourceSize.w, CN_OFFSET, CN_SCAN_OFFSET); + + if ((global.SourceSize.y > 288.5) && (global.SourceSize.y < 576.5)) + { + float field_offset = mod(global.FrameCount, 2.0); + + int_p.xy *= vec2(0.5, 2.0); + int_p.zw += 0.5*vec2(field_offset - 0.5, field_offset); + } + + return int_p; +} + +/* + Geom code - a modified Geom code without CRT features made to provide + curvature/warping/oversampling features. + + Adapted by Hyllian (2024). +*/ + +/* + Copyright (C) 2010-2012 cgwg, Themaister and DOLLS + + 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. + + (cgwg gave their consent to have the original version of this shader + distributed under the GPL in this message: + + http://board.byuu.org/viewtopic.php?p=26075#p26075 + + "Feel free to distribute my shaders under the GPL. After all, the + barrel distortion code was taken from the Curvature shader, which is + under the GPL." + ) + This shader variant is pre-configured with screen curvature +*/ + + +float intersect(vec2 xy) +{ + float A = dot(xy,xy) + params.geom_d*params.geom_d; + float B = 2.0 * (params.geom_R * (dot(xy,sinangle) - params.geom_d * cosangle.x * cosangle.y) - params.geom_d * params.geom_d); + float C = params.geom_d*params.geom_d + 2.0*params.geom_R*params.geom_d*cosangle.x*cosangle.y; + + return (-B-sqrt(B*B-4.0*A*C))/(2.0*A); +} + +vec2 bkwtrans(vec2 xy) +{ + float c = intersect(xy); + vec2 point = (vec2(c, c)*xy - vec2(-params.geom_R, -params.geom_R)*sinangle) / vec2(params.geom_R, params.geom_R); + vec2 poc = point/cosangle; + + vec2 tang = sinangle/cosangle; + float A = dot(tang, tang) + 1.0; + float B = -2.0*dot(poc, tang); + float C = dot(poc, poc) - 1.0; + + float a = (-B + sqrt(B*B - 4.0*A*C))/(2.0*A); + vec2 uv = (point - a*sinangle)/cosangle; + float r = FIX(params.geom_R*acos(a)); + + return uv*r/sin(r/params.geom_R); +} + +vec2 fwtrans(vec2 uv) +{ + float r = FIX(sqrt(dot(uv,uv))); + uv *= sin(r/params.geom_R)/r; + float x = 1.0-cos(r/params.geom_R); + float D = params.geom_d/params.geom_R + x*cosangle.x*cosangle.y+dot(uv,sinangle); + + return params.geom_d*(uv*cosangle-x*sinangle)/D; +} + +vec3 maxscale() +{ + vec2 c = bkwtrans( -params.geom_R * sinangle / (1.0 + params.geom_R / params.geom_d * cosangle.x * cosangle.y) ); + vec2 a = vec2(0.5,0.5) * aspect; + + vec2 lo = vec2(fwtrans(vec2(-a.x, c.y)).x, + fwtrans(vec2( c.x, -a.y)).y)/aspect; + + vec2 hi = vec2(fwtrans(vec2(+a.x, c.y)).x, + fwtrans(vec2( c.x, +a.y)).y)/aspect; + + return vec3( (hi + lo) * aspect * 0.5, max(hi.x - lo.x, hi.y - lo.y) ); +} + +void main() +{ + gl_Position = global.MVP * Position; + + vec2 corrected_size = vec2(params.in_res_x, params.in_res_y) * params.box_scale; + vec2 scale = vec2(1920.0, 1080.0) / corrected_size; + vec2 middle = vec2(params.geom_center_x, params.geom_center_y) + vec2(0.5, 0.5); + vec2 diff = TexCoord.xy - middle; + vTexCoord = middle + diff * scale; + + // Precalculate a bunch of useful values we'll need in the fragment + // shader. + sinangle = sin(vec2(params.geom_x_tilt, params.geom_y_tilt)); + cosangle = cos(vec2(params.geom_x_tilt, params.geom_y_tilt)); + stretch = maxscale(); + + d2 = params.geom_d * params.geom_d; + R_d_cx_cy = params.geom_R * params.geom_d * cosangle.x * cosangle.y; + + intl_profile = get_interlace_profile(); +} + + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 sinangle; +layout(location = 2) in vec2 cosangle; +layout(location = 3) in vec3 stretch; +layout(location = 4) in float R_d_cx_cy; +layout(location = 5) in float d2; +layout(location = 6) in vec4 intl_profile; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +vec2 transform(vec2 coord) +{ + coord = (coord - vec2(0.5, 0.5) - vec2(params.geom_inner_center_x, params.geom_inner_center_y)) * aspect * stretch.z + stretch.xy; + // coord = (coord - vec2(0.5, 0.5)) * aspect * stretch.z + stretch.xy; + + float A = dot(coord, coord) + d2; + float B = 2.0 * ( params.geom_R * dot(coord, sinangle) - R_d_cx_cy - d2); + float C = d2 + 2.0 * R_d_cx_cy; + + float c = (-B - sqrt(B*B - 4.0*A*C)) / (2.0*A); + + vec2 point = (vec2(c, c) * coord - vec2(-params.geom_R, -params.geom_R) * sinangle) / vec2(params.geom_R, params.geom_R); + vec2 poc = point / cosangle; + + vec2 tang = sinangle / cosangle; + A = dot(tang, tang) + 1.0; + B = -2.0 * dot(poc, tang); + C = dot(poc, poc) - 1.0; + + float a = (-B + sqrt(B*B - 4.0*A*C))/(2.0*A); + vec2 uv = (point - a*sinangle)/cosangle; + float r = FIX(params.geom_R*acos(a)); + + vec2 bkw = uv*r/sin(r/params.geom_R); + + return (bkw / vec2(params.geom_overscan_x / 100.0, params.geom_overscan_y / 100.0)/aspect + vec2(0.5, 0.5)); +} + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5, 0.5) + vec2(params.geom_inner_center_x, params.geom_inner_center_y)) * vec2(params.geom_overscan_x / 100.0, params.geom_overscan_y / 100.0) + vec2(0.5, 0.5); + + // coord = (coord - vec2(0.5, 0.5)) * vec2(params.geom_overscan_x / 100.0, params.geom_overscan_y / 100.0) + vec2(0.5, 0.5); + + coord = min(coord, vec2(1.0) - coord) * aspect; + vec2 cdist = vec2(params.geom_cornersize); + coord = (cdist - min(coord, cdist)); + float dist = sqrt(dot(coord, coord)); + + return clamp((cdist.x - dist)*params.geom_cornersmooth, 0.0, 1.0); +} + + +vec2 wgt(vec2 size) +{ + size = clamp(size, -1.0, 1.0); + + size = 1.0 - size * size; + + return size * size * size; +} + + + +float vignette(vec2 uv) +{ + float vignette = uv.x * uv.y * ( 1.0 - uv.x ) * ( 1.0 - uv.y ); + + return clamp( pow( params.CN_VIG_BASE * vignette, params.CN_VIG_EXP ), 0.0, 1.0 ); +} + + + + +void main() +{ + vec2 uv = vTexCoord; + float cval = 1.0; + + if (params.geom_curvature > 0.5) + { + uv = transform(uv); + } + else + { + uv -= vec2(params.geom_inner_center_x, params.geom_inner_center_y); + } + + cval = corner(uv) * step(0.0, fract(uv.y)); // Discard off limit pixels + + float vig = (params.CN_VIG_TOGGLE > 0.5) ? vignette(uv) : 1.0; + + vec4 TextureSize = vec4(global.SourceSize.x, intl_profile.x, global.SourceSize.z, intl_profile.y); + vec2 cn_offset = vec2(CN_OFFSET , intl_profile.z); + vec2 scan_off = vec2(CN_SCAN_OFFSET, intl_profile.w); + + vec2 pix_coord = uv * TextureSize.xy - scan_off; + vec2 tc = (floor(pix_coord) + cn_offset) * TextureSize.zw; // tc = texel coord + vec2 pos = fract(pix_coord) - cn_offset; // pos = pixel position + vec2 dir = sign(pos); // dir = pixel direction + pos = abs(pos); + + vec2 g1 = dir * vec2(TextureSize.z, 0); + vec2 g2 = dir * vec2( 0, TextureSize.w); + + mat2x3 AB = mat2x3(clamp(GAMMA_IN(texture(Source, tc ).xyz), 0.0, 1.0), clamp(GAMMA_IN(texture(Source, tc +g1 ).xyz), 0.0, 1.0)); + mat2x3 CD = mat2x3(clamp(GAMMA_IN(texture(Source, tc +g2).xyz), 0.0, 1.0), clamp(GAMMA_IN(texture(Source, tc +g1+g2).xyz), 0.0, 1.0)); + + vec2 wx = wgt(vec2(pos.x, 1.0-pos.x) / pix_sizex); + + mat2x3 c = mat2x3(AB * wx, CD * wx); + + float c0max = max(c[0].r, max(c[0].g, c[0].b)); + float c1max = max(c[1].r, max(c[1].g, c[1].b)); + + float lum0 = mix(CN_BEAM_MIN_WIDTH, CN_BEAM_MAX_WIDTH, c0max); + float lum1 = mix(CN_BEAM_MIN_WIDTH, CN_BEAM_MAX_WIDTH, c1max); + + vec2 ssy = mix(vec2(scan_sizey * lum0, scan_sizey * lum1), vec2(scan_sizey), CN_VSCANLINES); + + vec3 color = vig * (c * wgt(vec2(pos.y, 1.0-pos.y) / ssy)); + + FragColor = vec4(GAMMA_OUT(color) * vec3(cval), cval); +} diff --git a/shaders/support_shaders/ambient-light.slang b/shaders/support_shaders/ambient-light.slang new file mode 100644 index 0000000..77d6f02 --- /dev/null +++ b/shaders/support_shaders/ambient-light.slang @@ -0,0 +1,50 @@ +#version 450 + +/* ambient-light shader + + Based on ambient-glow. + +*/ + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float AG_effect; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma parameter AG_NONONO "AMBIENT-LIGHT:" 1.0 0.0 1.0 1.0 +#pragma parameter AG_effect " Glow Brightness" 1.0 0.1 3.0 0.1 + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + vec4 background; + vec4 color = texture(Source, vTexCoord, 10.0) * 1.25 + 0.125; // use mipmapping to get an average of the entire screen + + background = clamp(color * color * params.AG_effect, 0.0, 1.0); + + FragColor = background; +} diff --git a/shaders/support_shaders/feedback.slang b/shaders/support_shaders/feedback.slang new file mode 100644 index 0000000..cc80c8c --- /dev/null +++ b/shaders/support_shaders/feedback.slang @@ -0,0 +1,42 @@ +#version 450 + +layout(push_constant) uniform Push +{ + float mixfactor; +} param; + +#pragma parameter feed_nonono "FEEDBACK:" 0.0 0.0 1.0 1.0 +#pragma parameter mixfactor " Motionblur Fadeout" 0.75 0.0 1.0 0.01 + +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 = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D PassFeedback0; + +void main() +{ + vec3 current = texture(Source, vTexCoord).rgb; + vec3 fdback = texture(PassFeedback0, vTexCoord).rgb; + + FragColor = vec4(mix(current, fdback, param.mixfactor), 1.0); +} diff --git a/shaders/support_shaders/noshame-blur.slang b/shaders/support_shaders/noshame-blur.slang new file mode 100644 index 0000000..ccacb1c --- /dev/null +++ b/shaders/support_shaders/noshame-blur.slang @@ -0,0 +1,35 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + FragColor = vec4(textureLod(Source, vTexCoord, 4.0).rgb, 1.0); +} diff --git a/shaders/support_shaders/original.slang b/shaders/support_shaders/original.slang new file mode 100644 index 0000000..689d085 --- /dev/null +++ b/shaders/support_shaders/original.slang @@ -0,0 +1,43 @@ +#version 450 + +/* original.slang shader + + Based on stock.slang shader. Instead of a passthrough + shader, this one retrieve original input. + + +*/ + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Original; + +void main() +{ + FragColor = vec4(texture(Original, vTexCoord).rgb, 1.0); +} diff --git a/shaders/uborder-reflections.slang b/shaders/uborder-reflections.slang new file mode 100644 index 0000000..35e80f8 --- /dev/null +++ b/shaders/uborder-reflections.slang @@ -0,0 +1,121 @@ +#version 450 + +/* uborder-reflections shader + +*/ + + +layout(push_constant) uniform Push +{ + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + uint FrameCount; + float bezel_w, bezel_h; + float bezel_w_hlen, bezel_h_wlen; + float frame_w, frame_h; + float bezel_center_x; + float bezel_center_y; + float reflection_strength; + float reflection_scr_distance_x; + float reflection_scr_distance_y; + float AdjustView; + float ub_border_top; +} params; + +#pragma parameter border_nonono "BORDER:" 0.0 0.0 1.0 1.0 +#pragma parameter ub_border_top " On top: [ Frame | Border ]" 0.0 0.0 1.0 1.0 + +#pragma parameter RF_NONONO "REFLECTIONS:" 0.0 0.0 1.0 1.0 +#pragma parameter AdjustView " Reflection Adjust View" 0.0 0.0 1.0 1.0 +#pragma parameter reflection_strength " Reflection Strengh" 0.25 0.0 1.0 0.01 +#pragma parameter frame_w " Reflection Frame Width" 0.67 0.0 1.0 0.001 +#pragma parameter frame_h " Reflection Frame Height" 0.87 0.0 1.0 0.001 +#pragma parameter bezel_w " Vertical Bezel Thickness" 0.02 0.0 1.0 0.001 +#pragma parameter bezel_h " Horizontal Bezel Thickness" 0.02 0.0 1.0 0.001 +#pragma parameter bezel_center_x " Vertical Bezel Center" 0.0 -0.5 0.5 0.001 +#pragma parameter bezel_center_y " Horizontal Bezel Center" 0.0 -0.5 0.5 0.001 +#pragma parameter reflection_scr_distance_x " Bezel Reflection Screen Distance X" 0.00 0.0 0.04 0.001 +#pragma parameter reflection_scr_distance_y " Bezel Reflection Screen Distance Y" 0.00 0.0 0.04 0.001 + +#define bezel_w params.bezel_w +#define bezel_h params.bezel_h +#define frame_w params.frame_w +#define frame_h params.frame_h +#define bezel_center_x params.bezel_center_x +#define bezel_center_y params.bezel_center_y +#define reflection_strength params.reflection_strength +#define reflection_scr_distance_x params.reflection_scr_distance_x +#define reflection_scr_distance_y params.reflection_scr_distance_y + +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.xy; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D CRTPass; +layout(set = 0, binding = 3) uniform sampler2D BORDER; +layout(set = 0, binding = 4) uniform sampler2D BlurPass; + + +void main() +{ + vec4 border = texture(BORDER, vTexCoord); + + vec2 uv = vTexCoord.xy - vec2(bezel_center_x, bezel_center_y); + + vec4 frame = texture(CRTPass, vTexCoord.xy); + + vec2 c_frame = vec2(frame_w, frame_h); + + vec2 ouv = uv; + + vec4 reflex; + + if((abs(uv.x-0.5) >= (0.5*c_frame.x) && abs(uv.x-0.5) <= (0.5*c_frame.x+bezel_w)) && abs(uv.y-0.5) <= (0.5*c_frame.y+bezel_h)) + { + uv.x = (uv.x >= 0.50) ? 1.0 + c_frame.x - uv.x + reflection_scr_distance_x : 1.0 - c_frame.x - uv.x - reflection_scr_distance_x; + + reflex.rgb = mix(texture(BlurPass, uv + vec2(bezel_center_x, bezel_center_y)).rgb, vec3(0.0, 1.0, 0.0), params.AdjustView); + + reflex.rgb = mix(reflex.rgb, frame.rgb, frame.a); + reflex.rgb *= (1.0-smoothstep(0.5*c_frame.y-0.1, 0.5*c_frame.y, abs(uv.y-0.5))); + + border.rgb = clamp(border.rgb + reflection_strength*reflex.rgb, 0.0, 1.0); + } + + + if((abs(uv.y-0.5) >= (0.5*c_frame.y) && abs(uv.y-0.5) <= (0.5*c_frame.y+bezel_h)) && abs(ouv.x-0.5) <= (0.5*c_frame.x+bezel_w)) + { + + uv.y = (uv.y >= 0.50) ? 1.0 + c_frame.y - uv.y + reflection_scr_distance_y : 1.0 - c_frame.y - uv.y - reflection_scr_distance_y; + + reflex.rgb = mix(texture(BlurPass, vec2(ouv.x, uv.y) + vec2(bezel_center_x, bezel_center_y)).rgb, vec3(0.0, 1.0, 0.0), params.AdjustView); + + reflex.rgb = mix(reflex.rgb, frame.rgb, frame.a); + reflex.rgb *= (1.0-smoothstep(0.5*c_frame.x-0.1, 0.5*c_frame.x, abs(ouv.x-0.5))); + + border.rgb = clamp(border.rgb + reflection_strength*reflex.rgb, 0.0, 1.0); + } + + FragColor = vec4(mix(mix(frame, border, border.a), frame, frame.a * (1.0-params.ub_border_top))); + +// FragColor = mix(mix(border, frame, frame.a), mix(frame, border, border.a), params.ub_border_top); + +} + diff --git a/shaders/uborder.slang b/shaders/uborder.slang new file mode 100644 index 0000000..330f04e --- /dev/null +++ b/shaders/uborder.slang @@ -0,0 +1,57 @@ +#version 450 + +/* border-final shader + + Based on ambient-glow, this shader must be used after + any other shader. It only works properly if no mask or + warp functions are used. + +*/ + + +layout(push_constant) uniform Push +{ + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + uint FrameCount; + float ub_border_top; +} params; + +#pragma parameter border_nonono "BORDER:" 0.0 0.0 1.0 1.0 +#pragma parameter ub_border_top " On top: [ Frame | Border ]" 0.0 0.0 1.0 1.0 + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord.xy = TexCoord.xy; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D CRTPass; +layout(set = 0, binding = 3) uniform sampler2D BORDER; + + +void main() +{ + vec4 border = texture( BORDER, vTexCoord); + vec4 frame = texture(CRTPass, vTexCoord); + + vec4 color = mix(mix(border, frame, frame.a), mix(frame, border, border.a), params.ub_border_top); + + FragColor = color; +} diff --git a/textures/borders/default.jpg b/textures/borders/default.jpg new file mode 100644 index 0000000..4714521 Binary files /dev/null and b/textures/borders/default.jpg differ diff --git a/uborder-reflections.slangp b/uborder-reflections.slangp new file mode 100644 index 0000000..7b68e87 --- /dev/null +++ b/uborder-reflections.slangp @@ -0,0 +1,9 @@ +# If you want to use another base-preset, change the reference path here. + +#reference "base_presets/uborder-reflections/uborder-reflections-crt-nobody.slangp" +//#reference "base_presets/uborder-reflections/uborder-reflections-crt-geom.slangp" +//#reference "base_presets/uborder-reflections/hdr/crt-sony-megatron-viewsonic-A90f+-sdr.slangp" + +# If you want to use another background texture, change the reference path here. Notice that any other extra presets called will override this background if BORDER is defined there with other backgroun. + +BORDER = "textures/borders/default.jpg" diff --git a/uborder.slangp b/uborder.slangp new file mode 100644 index 0000000..b4f90fe --- /dev/null +++ b/uborder.slangp @@ -0,0 +1,9 @@ +# If you want to use another base-preset, change the reference path here. + +#reference "base_presets/uborder/uborder-crt-nobody.slangp" +//#reference "base_presets/uborder/uborder-crt-geom.slangp" + + +# If you want to use another background texture, change the reference path here. Notice that any other extra presets called will override this background if BORDER is defined there with other backgroun. + +BORDER = "textures/borders/default.jpg"