diff --git a/crt/shaders/snes-hires-blend.slang b/crt/shaders/snes-hires-blend.slang index cea3f31..8a51c45 100644 --- a/crt/shaders/snes-hires-blend.slang +++ b/crt/shaders/snes-hires-blend.slang @@ -1,5 +1,13 @@ #version 450 +/* + SNES Hires Blend Fix + by OV2, Sp00kyFox, hunterk +Filter: Nearest +Scale: 1x +The original shader has the problem that it blends every horizontal pair of adjacent pixels where it should only blend pairwise disjointed pixel pairs instead. +*/ + layout(push_constant) uniform Push { vec4 SourceSize; @@ -26,7 +34,7 @@ void main() vec2 ps = params.SourceSize.zw; float dx = ps.x; float dy = ps.y; - t1 = vTexCoord.xxxy + vec4( -dx, 0, dx, 0); // L, C, R + t1 = vTexCoord.xxxy + vec4( -dx, 0., dx, 0.); // L, C, R } #pragma stage fragment @@ -37,14 +45,20 @@ layout(set = 0, binding = 2) uniform sampler2D Source; void main() { - // pixel location - float fp = round(fract(0.5*vTexCoord.x*params.SourceSize.x)); - - // reading the texels - vec3 l = texture(Source, t1.xw).xyz; vec3 c = texture(Source, t1.yw).xyz; - vec3 r = texture(Source, t1.zw).xyz; + vec3 final; + if (params.SourceSize.x < 500.0) final = c; + else + { + // pixel location + float fp = round(fract(0.5*vTexCoord.x*params.SourceSize.x)); - // output - FragColor = vec4((params.SourceSize.x > 500) ? (fp == 0 ? mix(c,r,0.5) : mix(c,l,0.5)) : c, 1.0); + // reading the texels + vec3 l = texture(Source, t1.xw).xyz; + vec3 r = texture(Source, t1.zw).xyz; + + // output + final = (((l.x == c.x)||(r.x == c.x))&&((l.y == c.y)||(r.y == c.y))&&((l.z == c.z)||(r.z == c.z))) ? c : (fp > 0.5 ? mix(c,r,0.5) : mix(c,l,0.5)); + } + FragColor = vec4(final, 1.0); } \ No newline at end of file diff --git a/misc/image-adjustment.slang b/misc/image-adjustment.slang index 29081e9..fae9752 100644 --- a/misc/image-adjustment.slang +++ b/misc/image-adjustment.slang @@ -4,59 +4,59 @@ layout(push_constant) uniform Push { vec4 SourceSize; uint FrameCount; - float target_gamma; - float monitor_gamma; - float overscan_percent_x; - float overscan_percent_y; - float saturation; - float contrast; - float luminance; - float black_level; - float bright_boost; - float R; - float G; - float B; - float ZOOM; - float XPOS; - float YPOS; - float TOPMASK; - float BOTMASK; - float LMASK; - float RMASK; - float GRAIN_STR; - float SHARPEN; + float ia_target_gamma; + float ia_monitor_gamma; + float ia_overscan_percent_x; + float ia_overscan_percent_y; + float ia_saturation; + float ia_contrast; + float ia_luminance; + float ia_black_level; + float ia_bright_boost; + float ia_R; + float ia_G; + float ia_B; + float ia_ZOOM; + float ia_XPOS; + float ia_YPOS; + float ia_TOPMASK; + float ia_BOTMASK; + float ia_LMASK; + float ia_RMASK; + float ia_GRAIN_STR; + float ia_SHARPEN; } registers; layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; - float FLIP_HORZ; - float FLIP_VERT; + float ia_FLIP_HORZ; + float ia_FLIP_VERT; } global; -#pragma parameter target_gamma "Target Gamma" 2.2 0.1 5.0 0.1 -#pragma parameter monitor_gamma "Monitor Gamma" 2.2 0.1 5.0 0.1 -#pragma parameter overscan_percent_x "Horizontal Overscan %" 0.0 -25.0 25.0 1.0 -#pragma parameter overscan_percent_y "Vertical Overscan %" 0.0 -25.0 25.0 1.0 -#pragma parameter saturation "Saturation" 1.0 0.0 5.0 0.1 -#pragma parameter contrast "Contrast" 1.0 0.0 10.0 0.05 -#pragma parameter luminance "Luminance" 1.0 0.0 2.0 0.1 -#pragma parameter black_level "Black Level" 0.00 -0.30 0.30 0.01 -#pragma parameter bright_boost "Brightness Boost" 0.0 -1.0 1.0 0.05 -#pragma parameter R "Red Channel" 1.0 0.0 2.0 0.05 -#pragma parameter G "Green Channel" 1.0 0.0 2.0 0.05 -#pragma parameter B "Blue Channel" 1.0 0.0 2.0 0.05 -#pragma parameter ZOOM "Zoom Factor" 1.0 0.0 4.0 0.01 -#pragma parameter XPOS "X Modifier" 0.0 -2.0 2.0 0.005 -#pragma parameter YPOS "Y Modifier" 0.0 -2.0 2.0 0.005 -#pragma parameter TOPMASK "Overscan Mask Top" 0.0 0.0 1.0 0.0025 -#pragma parameter BOTMASK "Overscan Mask Bottom" 0.0 0.0 1.0 0.0025 -#pragma parameter LMASK "Overscan Mask Left" 0.0 0.0 1.0 0.0025 -#pragma parameter RMASK "Overscan Mask Right" 0.0 0.0 1.0 0.0025 -#pragma parameter GRAIN_STR "Film Grain" 0.0 0.0 72.0 6.0 -#pragma parameter SHARPEN "Sharpen" 0.0 0.0 1.0 0.05 -#pragma parameter FLIP_HORZ "Flip Horiz Axis" 0.0 0.0 1.0 1.0 -#pragma parameter FLIP_VERT "Flip Vert Axis" 0.0 0.0 1.0 1.0 +#pragma parameter ia_target_gamma "Target Gamma" 2.2 0.1 5.0 0.1 +#pragma parameter ia_monitor_gamma "Monitor Gamma" 2.2 0.1 5.0 0.1 +#pragma parameter ia_overscan_percent_x "Horizontal Overscan %" 0.0 -25.0 25.0 1.0 +#pragma parameter ia_overscan_percent_y "Vertical Overscan %" 0.0 -25.0 25.0 1.0 +#pragma parameter ia_saturation "Saturation" 1.0 0.0 5.0 0.1 +#pragma parameter ia_contrast "Contrast" 1.0 0.0 10.0 0.05 +#pragma parameter ia_luminance "Luminance" 1.0 0.0 2.0 0.1 +#pragma parameter ia_black_level "Black Level" 0.00 -0.30 0.30 0.01 +#pragma parameter ia_bright_boost "Brightness Boost" 0.0 -1.0 1.0 0.05 +#pragma parameter ia_R "Red Channel" 1.0 0.0 2.0 0.05 +#pragma parameter ia_G "Green Channel" 1.0 0.0 2.0 0.05 +#pragma parameter ia_B "Blue Channel" 1.0 0.0 2.0 0.05 +#pragma parameter ia_ZOOM "Zoom Factor" 1.0 0.0 4.0 0.01 +#pragma parameter ia_XPOS "X Modifier" 0.0 -2.0 2.0 0.005 +#pragma parameter ia_YPOS "Y Modifier" 0.0 -2.0 2.0 0.005 +#pragma parameter ia_TOPMASK "Overscan Mask Top" 0.0 0.0 1.0 0.0025 +#pragma parameter ia_BOTMASK "Overscan Mask Bottom" 0.0 0.0 1.0 0.0025 +#pragma parameter ia_LMASK "Overscan Mask Left" 0.0 0.0 1.0 0.0025 +#pragma parameter ia_RMASK "Overscan Mask Right" 0.0 0.0 1.0 0.0025 +#pragma parameter ia_GRAIN_STR "Film Grain" 0.0 0.0 72.0 6.0 +#pragma parameter ia_SHARPEN "Sharpen" 0.0 0.0 1.0 0.05 +#pragma parameter ia_FLIP_HORZ "Flip Horiz Axis" 0.0 0.0 1.0 1.0 +#pragma parameter ia_FLIP_VERT "Flip Vert Axis" 0.0 0.0 1.0 1.0 // Image Adjustment // Author: hunterk @@ -91,12 +91,12 @@ layout(location = 0) out vec2 vTexCoord; void main() { vec4 flip_pos = Position; - if (global.FLIP_HORZ > 0.5) flip_pos.x = 1.0 - flip_pos.x; - if (global.FLIP_VERT > 0.5) flip_pos.y = 1.0 - flip_pos.y; + if (global.ia_FLIP_HORZ > 0.5) flip_pos.x = 1.0 - flip_pos.x; + if (global.ia_FLIP_VERT > 0.5) flip_pos.y = 1.0 - flip_pos.y; gl_Position = global.MVP * flip_pos; vec2 shift = vec2(0.5); - vec2 overscan_coord = ((TexCoord - shift) / registers.ZOOM) * (1.0 - vec2(registers.overscan_percent_x / 100.0, registers.overscan_percent_y / 100.0)) + shift; - vTexCoord = overscan_coord + vec2(registers.XPOS, registers.YPOS); + vec2 overscan_coord = ((TexCoord - shift) / registers.ia_ZOOM) * (1.0 - vec2(registers.ia_overscan_percent_x / 100.0, registers.ia_overscan_percent_y / 100.0)) + shift; + vTexCoord = overscan_coord + vec2(registers.ia_XPOS, registers.ia_YPOS); } #pragma stage fragment @@ -106,29 +106,29 @@ layout(set = 0, binding = 2) uniform sampler2D Source; void main() { - vec3 film_grain = filmGrain(vTexCoord, registers.GRAIN_STR); + vec3 film_grain = filmGrain(vTexCoord, registers.ia_GRAIN_STR); vec3 res = texture(Source, vTexCoord).rgb; // sample the texture - res = mix(res, sharp(Source, vTexCoord), registers.SHARPEN) + film_grain; // add film grain and sharpness - vec3 gamma = vec3(registers.monitor_gamma / registers.target_gamma); // set up ratio of display's gamma vs desired gamma + res = mix(res, sharp(Source, vTexCoord), registers.ia_SHARPEN) + film_grain; // add film grain and sharpness + vec3 gamma = vec3(registers.ia_monitor_gamma / registers.ia_target_gamma); // set up ratio of display's gamma vs desired gamma //saturation and luminance - vec3 satColor = clamp(HSVtoRGB(RGBtoHSV(res) * vec3(1.0, registers.saturation, registers.luminance)), 0.0, 1.0); + vec3 satColor = clamp(HSVtoRGB(RGBtoHSV(res) * vec3(1.0, registers.ia_saturation, registers.ia_luminance)), 0.0, 1.0); //contrast and brightness - vec3 conColor = clamp((satColor - 0.5) * registers.contrast + 0.5 + registers.bright_boost, 0.0, 1.0); + vec3 conColor = clamp((satColor - 0.5) * registers.ia_contrast + 0.5 + registers.ia_bright_boost, 0.0, 1.0); - conColor -= vec3(registers.black_level); // apply black level - conColor *= (vec3(1.0) / vec3(1.0-registers.black_level)); + conColor -= vec3(registers.ia_black_level); // apply black level + conColor *= (vec3(1.0) / vec3(1.0-registers.ia_black_level)); conColor = pow(conColor, 1.0 / vec3(gamma)); // Apply gamma correction - conColor *= vec3(registers.R, registers.G, registers.B); + conColor *= vec3(registers.ia_R, registers.ia_G, registers.ia_B); //overscan mask -if (vTexCoord.y > registers.TOPMASK && vTexCoord.y < (1.0 - registers.BOTMASK)) +if (vTexCoord.y > registers.ia_TOPMASK && vTexCoord.y < (1.0 - registers.ia_BOTMASK)) conColor = conColor; else conColor = vec3(0.0); -if (vTexCoord.x > registers.LMASK && vTexCoord.x < (1.0 - registers.RMASK)) +if (vTexCoord.x > registers.ia_LMASK && vTexCoord.x < (1.0 - registers.ia_RMASK)) conColor = conColor; else conColor = vec3(0.0);