update crt-geom-deluxe to add brightness compensation; add bright pix… (#170)

* update crt-geom-deluxe to add brightness compensation; add bright pixel counts to subpixel masks; delete extraneous preset

* forgot to update geom-deluxe preset

* fix various preset spec nits

* try to mellow out the raster bloom

Co-authored-by: hunterk <hunter_kaller@yahoo.com>
This commit is contained in:
hizzlekizzle 2021-03-01 15:11:53 -06:00 committed by GitHub
parent ba36486cb2
commit 12fdb6562f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 455 additions and 257 deletions

View File

@ -1,204 +0,0 @@
*****************************************************************
Guest-dr-venom-maxDR
A PVM/BVM-style preset for guest-dr-venom created with the goal of maximizing the dynamic range of the image.
For best results, increase your LCD backlight to 100%. Color settings may need to be adjusted per-system or per-game; see the shader notes within grade.slang for suggestions. Color temp may also need to be adjusted depending on the color temp of your display.
Preset created by Nesguy at Libretro forums (https://forums.libretro.com/). Feedback and suggestions are welcome :)
*****************************************************************
shaders = "8"
shader0 = "../misc/grade.slang"
filter_linear0 = "true"
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
alias0 = "WhitePointPass"
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
scale_type_x0 = "source"
scale_x0 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "../crt/shaders/guest/afterglow.slang"
filter_linear1 = "true"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = "AfterglowPass"
float_framebuffer1 = "false"
srgb_framebuffer1 = "false"
scale_type_x1 = "source"
scale_x1 = "1.000000"
scale_type_y1 = "source"
scale_y1 = "1.000000"
shader2 = "../crt/shaders/guest/avg-lum.slang"
filter_linear2 = "true"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "true"
alias2 = "AvgLumPass"
float_framebuffer2 = "true"
srgb_framebuffer2 = "false"
scale_type_x2 = "source"
scale_x2 = "1.000000"
scale_type_y2 = "source"
scale_y2 = "1.000000"
shader3 = "../crt/shaders/guest/linearize.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = "LinearizePass"
float_framebuffer3 = "true"
srgb_framebuffer3 = "false"
scale_type_x3 = "source"
scale_x3 = "1.000000"
scale_type_y3 = "source"
scale_y3 = "1.000000"
shader4 = "../crt/shaders/guest/blur_horiz.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "false"
alias4 = ""
float_framebuffer4 = "true"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "1.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "../crt/shaders/guest/blur_vert.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = "GlowPass"
float_framebuffer5 = "true"
srgb_framebuffer5 = "false"
scale_type_x5 = "source"
scale_x5 = "1.000000"
scale_type_y5 = "source"
scale_y5 = "1.000000"
shader6 = "../crt/shaders/guest/linearize_scanlines.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = ""
float_framebuffer6 = "true"
srgb_framebuffer6 = "false"
scale_type_x6 = "source"
scale_x6 = "1.000000"
scale_type_y6 = "source"
scale_y6 = "1.000000"
shader7 = "../crt/shaders/guest/crt-guest-dr-venom.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = ""
float_framebuffer7 = "false"
srgb_framebuffer7 = "false"
scale_type_x7 = "viewport"
scale_x7 = "1.000000"
scale_type_y7 = "viewport"
scale_y7 = "1.000000"
parameters = "g_gamma_in;g_signal_type;g_gamma_type;g_crtgamut;g_space_out;g_hue_degrees;g_I_SHIFT;g_Q_SHIFT;g_I_MUL;g_Q_MUL;g_lum_fix;g_vignette;g_vstr;g_vpower;g_lum;g_cntrst;g_mid;wp_temperature;g_sat;g_vibr;g_satr;g_satg;g_satb;g_lift;blr;blg;blb;wlr;wlg;wlb;rg;rb;gr;gb;br;bg;LUT_Size1;LUT1_toggle;LUT_Size2;LUT2_toggle;SW;AR;PR;AG;PG;AB;PB;sat;lsmooth;GAMMA_INPUT;TAPSH;GLOW_FALLOFF_H;TAPSV;GLOW_FALLOFF_V;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;slotms;mcut;maskDark;maskLight;CGWG;gamma_out;spike;inter;interm;bloom;scans"
g_gamma_in = "2.500001"
g_signal_type = "0.000000"
g_gamma_type = "1.000000"
g_crtgamut = "0.000000"
g_space_out = "0.000000"
g_hue_degrees = "0.000000"
g_I_SHIFT = "0.000000"
g_Q_SHIFT = "0.000000"
g_I_MUL = "1.000000"
g_Q_MUL = "1.000000"
g_lum_fix = "0.000000"
g_vignette = "0.000000"
g_vstr = "40.000000"
g_vpower = "0.200000"
g_lum = "0.000000"
g_cntrst = "0.000000"
g_mid = "0.500000"
wp_temperature = "6505.000000"
g_sat = "0.000000"
g_vibr = "0.000000"
g_satr = "0.000000"
g_satg = "0.000000"
g_satb = "0.000000"
g_lift = "0.000000"
blr = "0.000000"
blg = "0.000000"
blb = "0.000000"
wlr = "1.000000"
wlg = "1.000000"
wlb = "1.000000"
rg = "0.000000"
rb = "0.000000"
gr = "0.000000"
gb = "0.000000"
br = "0.000000"
bg = "0.000000"
LUT_Size1 = "16.000000"
LUT1_toggle = "0.000000"
LUT_Size2 = "64.000000"
LUT2_toggle = "0.000000"
SW = "1.000000"
AR = "0.070000"
PR = "0.050000"
AG = "0.070000"
PG = "0.050000"
AB = "0.070000"
PB = "0.050000"
sat = "0.100000"
lsmooth = "0.900000"
GAMMA_INPUT = "3.499997"
TAPSH = "4.000000"
GLOW_FALLOFF_H = "0.300000"
TAPSV = "4.000000"
GLOW_FALLOFF_V = "0.300000"
TATE = "0.000000"
IOS = "0.000000"
OS = "1.000000"
BLOOM = "0.000000"
brightboost = "0.500000"
brightboost1 = "3.250000"
gsl = "2.000000"
scanline1 = "1.000000"
scanline2 = "100.000000"
beam_min = "1.000000"
beam_max = "0.800000"
beam_size = "0.000000"
h_sharp = "3.000000"
s_sharp = "1.000000"
csize = "0.000000"
bsize = "600.000000"
warpX = "0.000000"
warpY = "0.000000"
glow = "0.000000"
shadowMask = "0.000000"
masksize = "1.000000"
vertmask = "0.000000"
slotmask = "0.000000"
slotwidth = "2.000000"
double_slot = "1.000000"
slotms = "1.000000"
mcut = "0.250000"
maskDark = "0.500000"
maskLight = "1.500000"
CGWG = "0.650000"
gamma_out = "3.500000"
spike = "1.000000"
inter = "400.000000"
interm = "1.000000"
bloom = "0.000000"
scans = "1.000000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3"
SamplerLUT1 = "../crt/shaders/guest/lut/sony_trinitron1.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "../crt/shaders/guest/lut/sony_trinitron2.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "../crt/shaders/guest/lut/other1.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"

View File

@ -12,19 +12,19 @@ alias2 = internal2
shader3 = shaders/geom-deluxe/gaussy.slang shader3 = shaders/geom-deluxe/gaussy.slang
filter_linear3 = true filter_linear3 = true
alias3 = blur alias3 = blur_texture
shader4 = shaders/geom-deluxe/crt-geom-deluxe.slang shader4 = shaders/geom-deluxe/crt-geom-deluxe.slang
filter_linear4 = true filter_linear4 = true
mipmap_input4 = true
# comment these mask textures since we're generating them in the shader textures = "aperture;slot;delta"
#textures = "aperture;slot;delta" delta = shaders/geom-deluxe/masks/delta_2_4x1_rgb.png
#delta = shaders/geom-deluxe/masks/delta_2_4x1_rgb.png delta_filter_linear = true
#delta_filter_linear = true delta_repeat_mode = repeat
#delta_repeat_mode = repeat slot = shaders/geom-deluxe/masks/slot_2_5x4_bgr.png
#slot = shaders/geom-deluxe/masks/slot_2_5x4_bgr.png slot_filter_linear = true
#slot_filter_linear = true slot_repeat_mode = repeat
#slot_repeat_mode = repeat aperture = shaders/geom-deluxe/masks/aperture_2_4_rgb.png
#aperture = shaders/geom-deluxe/masks/aperture_2_4_rgb.png aperture_filter_linear = true
#aperture_filter_linear = true aperture_repeat_mode = repeat
#aperture_repeat_mode = repeat

View File

@ -19,8 +19,8 @@ shader2 = shaders/glow/gauss_horiz.slang
filter_linear2 = false filter_linear2 = false
scale_type_x2 = viewport scale_type_x2 = viewport
scale_type_y2 = source scale_type_y2 = source
scale_x = 1.0 scale_x2 = 1.0
scale_y = 1.0 scale_y2 = 1.0
srgb_framebuffer2 = true srgb_framebuffer2 = true
shader3 = shaders/glow/gauss_vert.slang shader3 = shaders/glow/gauss_vert.slang

View File

@ -8,8 +8,8 @@ shader1 = shaders/glow/lanczos_horiz.slang
filter_linear1 = false filter_linear1 = false
scale_type_x1 = viewport scale_type_x1 = viewport
scale_type_y1 = source scale_type_y1 = source
scale_x = 1.0 scale_x1 = 1.0
scale_y = 1.0 scale_y1 = 1.0
srgb_framebuffer1 = true srgb_framebuffer1 = true
shader2 = shaders/glow/gauss_vert.slang shader2 = shaders/glow/gauss_vert.slang

View File

@ -15,5 +15,5 @@ float_framebuffer1 = true
shader2 = shaders/gtu-v050/pass3.slang shader2 = shaders/gtu-v050/pass3.slang
scale_type2 = viewport scale_type2 = viewport
scale_2 = 1.0 scale2 = 1.0
filter_linear2 = false filter_linear2 = false

View File

@ -15,8 +15,9 @@
#include "../../../include/subpixel_masks.h" #include "../../../include/subpixel_masks.h"
#define u_tex_size0 global.SourceSize.xy #define u_tex_size0 global.SourceSize.xy
#define u_tex_size1 global.internal1Size.xy //#define u_tex_size1 global.internal1Size.xy
#define u_quad_dims global.OutputSize.xy #define u_quad_dims global.OutputSize.xy
#define u_tex_size1 vec2(global.OutputSize.xy * global.SourceSize.zw)
// Comment the next line to disable interpolation in linear gamma (and gain speed). // Comment the next line to disable interpolation in linear gamma (and gain speed).
#define LINEAR_PROCESSING #define LINEAR_PROCESSING
@ -125,20 +126,36 @@ layout(location = 4) in vec2 v_one;
layout(location = 5) in vec2 ilfac; layout(location = 5) in vec2 ilfac;
layout(location = 6) in vec2 TextureSize; layout(location = 6) in vec2 TextureSize;
layout(location = 0) out vec4 FragColor; layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D blur; layout(set = 0, binding = 2) uniform sampler2D blur_texture;
layout(set = 0, binding = 3) uniform sampler2D internal1; layout(set = 0, binding = 3) uniform sampler2D internal1;
// comment these out, as we're using generated masks instead of LUTs // comment these out, as we're using generated masks instead of LUTs
//layout(set = 0, binding = 4) uniform sampler2D aperture; layout(set = 0, binding = 4) uniform sampler2D aperture;
//layout(set = 0, binding = 5) uniform sampler2D slot; layout(set = 0, binding = 5) uniform sampler2D slot;
//layout(set = 0, binding = 6) uniform sampler2D delta; layout(set = 0, binding = 6) uniform sampler2D delta;
layout(set = 0, binding = 7) uniform sampler2D phosphor;
#define blur_texture blur
vec4 TEX2D(vec2 c)
{
vec2 underscan = step(0.0,c) * step(0.0,vec2(1.0)-c);
vec4 col = texture(internal1, c) * vec4(underscan.x*underscan.y);
#ifdef LINEAR_PROCESSING #ifdef LINEAR_PROCESSING
# define TEX2D(c) pow(texture(internal1, (c)), vec4(CRTgamma)) col = pow(col, vec4(CRTgamma.x));
#else
# define TEX2D(c) texture(internal1, (c))
#endif #endif
return col;
}
vec3 texblur(vec2 c)
{
vec3 col = pow(texture(blur_texture,c).rgb, vec3(CRTgamma.x));
// taper the blur texture outside its border with a gaussian
float w = blurwidth.x / 320.0;
c = min(c, vec2(1.0)-c) * aspect.xy * vec2(1.0/w);
vec2 e2c = exp(-c*c);
// approximation of erf gives smooth step
// (convolution of gaussian with step)
c = (step(0.0,c)-vec2(0.5)) * sqrt(vec2(1.0)-e2c) * (vec2(1.0) + vec2(0.1749)*e2c) + vec2(0.5);
return col * vec3( c.x * c.y );
}
float intersect(vec2 xy , vec2 sinangle, vec2 cosangle) float intersect(vec2 xy , vec2 sinangle, vec2 cosangle)
{ {
@ -239,9 +256,15 @@ void main()
xy = transform(v_texCoord, v_stretch, v_sinangle, v_cosangle); xy = transform(v_texCoord, v_stretch, v_sinangle, v_cosangle);
else else
xy = (v_texCoord-vec2(0.5))/overscan.xy+vec2(0.5); xy = (v_texCoord-vec2(0.5))/overscan.xy+vec2(0.5);
vec2 xy0 = xy;
float cval = corner(xy); float cval = corner(xy);
// extract average brightness from the mipmap texture
float avgbright = dot(textureLod(blur_texture, vec2(1.,1.), 9.0).rgb,vec3(1.0))/3.0;
float rbloom = 1.0 - rasterbloom.x * ( avgbright - 0.5 );
// expand the screen when average brightness is higher
xy = (xy - vec2(0.5)) * rbloom + vec2(0.5);
vec2 xy0 = xy;
// Of all the pixels that are mapped onto the texel we are // Of all the pixels that are mapped onto the texel we are
// currently rendering, which pixel are we currently rendering? // currently rendering, which pixel are we currently rendering?
@ -305,20 +328,46 @@ void main()
vec3 mul_res = (col * weights + col2 * weights2).rgb; vec3 mul_res = (col * weights + col2 * weights2).rgb;
// halation and corners // halation and corners
vec3 blur = pow(texture(blur_texture,xy0).rgb, vec3(CRTgamma.x)); vec3 blur = texblur(xy0);
mul_res = mix(mul_res, blur, halation.x) * vec3(cval); mul_res = mix(mul_res, blur, halation.x) * vec3(cval);
// include factor of rbloom:
// (probably imperceptible) brightness reduction when raster grows
// Convert the image gamma for display on our output device. // Convert the image gamma for display on our output device.
mul_res = pow(mul_res, vec3(1.0 / monitorgamma.x)); mul_res = mix(mul_res, blur, halation.x) * vec3(cval*rbloom);
// Shadow mask // Shadow mask
// original code; just makes a giant phosphor here // original code; just makes a giant phosphor here
// xy = v_texCoord.xy * u_quad_dims.xy / u_tex_size1.xy; xy = fract(v_texCoord.xy * u_quad_dims.xy / u_tex_size1.xy);
// gl_FragCoord; tied to physical pixel size // gl_FragCoord; tied to physical pixel size
xy = v_texCoord.xy * global.OutputSize.xy; //xy = fract(v_texCoord*global.internal1Size.xy);
vec3 mask = mask_weights(xy, aperture_strength.x, mask_picker); vec4 mask = vec4(1.0);
// if (mask_picker == 1) mask = texture(aperture, xy);
// else if (mask_picker == 2) mask = texture(slot, xy);
// else if (mask_picker == 3) mask = texture(delta, xy);
FragColor = vec4(mul_res*mask, col.a); // use subpixel mask code instead of LUTs
float alpha;
mask = vec4(mask_weights_alpha(v_texCoord.xy * global.OutputSize.xy, 1., mask_picker, alpha), 1.0);
mask.a = alpha;
// count of total bright pixels is encoded in the mask's alpha channel
float nbright = 255.0 - 255.0*mask.a;
// fraction of bright pixels in the mask
float fbright = nbright / ( u_tex_size1.x * u_tex_size1.y );
// average darkening factor of the mask
float aperture_average = mix(1.0-aperture_strength.x*(1.0-aperture_brightboost.x), 1.0, fbright);
// colour of dark mask pixels
vec3 clow = vec3(1.0-aperture_strength.x) * mul_res + vec3(aperture_strength.x*(aperture_brightboost.x)) * mul_res * mul_res;
float ifbright = 1.0 / fbright;
// colour of bright mask pixels
vec3 chi = vec3(ifbright*aperture_average) * mul_res - vec3(ifbright - 1.0) * clow;
vec3 cout = mix(clow,chi,mask.rgb); // mask texture selects dark vs bright
// Convert the image gamma for display on our output device.
cout = pow(cout, vec3(1.0 / monitorgamma.x));
FragColor = vec4(cout, col.a);
} }

View File

@ -1,8 +1,31 @@
layout(push_constant) uniform Push layout(push_constant) uniform Push
{ {
float phosphor_power, phosphor_amplitude, CRTgamma, width, aspect_x, aspect_y, d, R, angle_x, angle_y, float phosphor_power;
aperture_strength, halation, curvature, cornersize, cornersmooth, overscan_x, overscan_y, float phosphor_amplitude;
monitorgamma, mask_type, SHARPER, scanline_weight, geom_lum, interlace_detect; float CRTgamma;
float width;
float aspect_x;
float aspect_y;
float d;
float R;
float angle_x;
float angle_y;
float aperture_strength;
float aperture_brightboost;
float halation;
float curvature;
float cornersize;
float cornersmooth;
float overscan_x;
float overscan_y;
float monitorgamma;
float mask_type;
float SHARPER;
float scanline_weight;
float geom_lum;
float interlace_detect;
float rasterbloom_smooth;
float rasterbloom;
} params; } params;
layout(std140, set = 0, binding = 0) uniform UBO layout(std140, set = 0, binding = 0) uniform UBO
@ -16,11 +39,14 @@ layout(std140, set = 0, binding = 0) uniform UBO
mat4 MVP; mat4 MVP;
} global; } global;
#pragma parameter mask_type "Mask (aperture, delta, slot)" 1.0 1.0 19.0 1.0 #pragma parameter mask_type "Mask Pattern" 1.0 1.0 20.0 1.0
#pragma parameter aperture_strength "Shadow mask strength" 0.4 0.0 1.0 0.05 #pragma parameter aperture_strength "Shadow mask strength" 0.4 0.0 1.0 0.05
#pragma parameter aperture_brightboost "Shadow mask brightness boost" 0.4 0.0 1.0 0.05
#pragma parameter phosphor_power "Phosphor decay power" 1.2 0.5 3.0 0.05 #pragma parameter phosphor_power "Phosphor decay power" 1.2 0.5 3.0 0.05
#pragma parameter phosphor_amplitude "Phosphor persistence amplitude" 0.04 0.0 0.2 0.01 #pragma parameter phosphor_amplitude "Phosphor persistence amplitude" 0.04 0.0 0.2 0.01
#pragma parameter CRTgamma "Gamma of simulated CRT" 2.4 0.7 4.0 0.05 #pragma parameter CRTgamma "Gamma of simulated CRT" 2.4 0.7 4.0 0.05
//#pragma parameter rasterbloom_smooth "Raster bloom temporal smoothing" 0.5 0.0 0.99 0.01
#pragma parameter rasterbloom "Raster bloom amplitude" 0.1 0.0 1.0 0.01
#pragma parameter halation "Halation amplitude" 0.1 0.0 0.3 0.01 #pragma parameter halation "Halation amplitude" 0.1 0.0 0.3 0.01
#pragma parameter width "Halation blur width" 2.0 0.1 4.0 0.1 #pragma parameter width "Halation blur width" 2.0 0.1 4.0 0.1
#pragma parameter curvature "Enable Curvature" 1.0 0.0 1.0 1.0 #pragma parameter curvature "Enable Curvature" 1.0 0.0 1.0 1.0
@ -50,12 +76,16 @@ layout(std140, set = 0, binding = 0) uniform UBO
#define monitorgamma params.monitorgamma #define monitorgamma params.monitorgamma
#define halation params.halation #define halation params.halation
#define aperture_strength params.aperture_strength #define aperture_strength params.aperture_strength
#define aperture_brightboost params.aperture_brightboost
#define geom_lum params.geom_lum #define geom_lum params.geom_lum
#define scanline_weight params.scanline_weight #define scanline_weight params.scanline_weight
#define interlace_detect params.interlace_detect #define interlace_detect params.interlace_detect
//#define rasterbloom_smooth params.rasterbloom_smooth
#define rasterbloom (params.rasterbloom / 10.0)
vec2 aspect = vec2(params.aspect_x, params.aspect_y); vec2 aspect = vec2(params.aspect_x, params.aspect_y);
vec2 angle = vec2(params.angle_x, params.angle_y); vec2 angle = vec2(params.angle_x, params.angle_y);
vec2 overscan = vec2(params.overscan_x, params.overscan_y); vec2 overscan = vec2(params.overscan_x, params.overscan_y);
int mask_picker = int(params.mask_type); int mask_picker = int(params.mask_type);
vec4 blurwidth = vec4(width);
const float gamma = 2.2; const float gamma = 2.2;

BIN
crt/shaders/geom-deluxe/masks/aperture_1_2_bgr.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

After

Width:  |  Height:  |  Size: 74 B

BIN
crt/shaders/geom-deluxe/masks/aperture_1_4_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 78 B

BIN
crt/shaders/geom-deluxe/masks/aperture_2_4_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 78 B

BIN
crt/shaders/geom-deluxe/masks/aperture_2_5_bgr.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 82 B

BIN
crt/shaders/geom-deluxe/masks/aperture_3_6_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 82 B

BIN
crt/shaders/geom-deluxe/masks/delta_1_2x1_bgr.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 83 B

BIN
crt/shaders/geom-deluxe/masks/delta_1_4x1_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 87 B

BIN
crt/shaders/geom-deluxe/masks/delta_2_4x1_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

After

Width:  |  Height:  |  Size: 86 B

BIN
crt/shaders/geom-deluxe/masks/delta_2_4x2_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

After

Width:  |  Height:  |  Size: 91 B

BIN
crt/shaders/geom-deluxe/masks/slot_2_4x4_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 99 B

BIN
crt/shaders/geom-deluxe/masks/slot_2_5x4_bgr.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

After

Width:  |  Height:  |  Size: 107 B

BIN
crt/shaders/geom-deluxe/masks/slot_3_7x6_rgb.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

After

Width:  |  Height:  |  Size: 109 B

View File

@ -35,7 +35,7 @@ filter_linear5 = true
scale_type5 = source scale_type5 = source
scale5 = 1.0 scale5 = 1.0
parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x" parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x;shadow_opacity"
video_scale = "3.0" video_scale = "3.0"
SCALE = "0.6667" SCALE = "0.6667"
OUT_X = "1600.0" OUT_X = "1600.0"

View File

@ -33,7 +33,7 @@ alias4 = "PASS4"
shader5 = shader-files/gb-pass-5.slang shader5 = shader-files/gb-pass-5.slang
filter_linear5 = true filter_linear5 = true
parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x" parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x;shadow_opacity"
video_scale = "3.0" video_scale = "3.0"
SCALE = "1.0" SCALE = "1.0"
OUT_X = "2400.0" OUT_X = "2400.0"

View File

@ -33,7 +33,7 @@ alias4 = "PASS4"
shader5 = shader-files/gb-pass-5.slang shader5 = shader-files/gb-pass-5.slang
filter_linear5 = true filter_linear5 = true
parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x" parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x;shadow_opacity"
video_scale = "4.0" video_scale = "4.0"
SCALE = "1.0" SCALE = "1.0"
OUT_X = "3200.0" OUT_X = "3200.0"

View File

@ -33,7 +33,7 @@ alias4 = "PASS4"
shader5 = shader-files/gb-pass-5.slang shader5 = shader-files/gb-pass-5.slang
filter_linear5 = true filter_linear5 = true
parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x" parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x;shadow_opacity"
video_scale = "4.0" video_scale = "4.0"
SCALE = "1.25" SCALE = "1.25"
OUT_X = "4000.0" OUT_X = "4000.0"

View File

@ -33,7 +33,7 @@ alias4 = "PASS4"
shader5 = shader-files/gb-pass-5.slang shader5 = shader-files/gb-pass-5.slang
filter_linear5 = true filter_linear5 = true
parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x" parameters = "video_scale;SCALE;OUT_X;OUT_Y;baseline_alpha;grey_balance;adjacent_texel_alpha_blending;contrast;screen_light;pixel_opacity;shadow_offset_x;shadow_opacity"
video_scale = "4.0" video_scale = "4.0"
SCALE = "1.5" SCALE = "1.5"
OUT_X = "4800.0" OUT_X = "4800.0"

View File

@ -10,6 +10,8 @@ How to use it:
Multiply your image by the vec3 output: Multiply your image by the vec3 output:
FragColor.rgb *= mask_weights(gl_FragCoord.xy, 1.0, 1); FragColor.rgb *= mask_weights(gl_FragCoord.xy, 1.0, 1);
In the vec3 version, the alpha channel stores the number of lit subpixels per pixel for use in brightness-loss compensation efforts.
The function needs to be tiled across the screen using the physical pixels, e.g. The function needs to be tiled across the screen using the physical pixels, e.g.
gl_FragCoord (the "vec2 coord" input). In the case of slang shaders, we use gl_FragCoord (the "vec2 coord" input). In the case of slang shaders, we use
(vTexCoord.st * OutputSize.xy). (vTexCoord.st * OutputSize.xy).
@ -37,6 +39,7 @@ vec3 mask_weights(vec2 coord, float mask_intensity, int phosphor_layout){
vec3 yellow = vec3(on, on, off); vec3 yellow = vec3(on, on, off);
vec3 cyan = vec3(off, on, on ); vec3 cyan = vec3(off, on, on );
vec3 black = vec3(off, off, off); vec3 black = vec3(off, off, off);
vec3 white = vec3(on, on, on );
int w, z = 0; int w, z = 0;
// This pattern is used by a few layouts, so we'll define it here // This pattern is used by a few layouts, so we'll define it here
@ -287,5 +290,325 @@ vec3 mask_weights(vec2 coord, float mask_intensity, int phosphor_layout){
return weights; return weights;
} }
else if(phosphor_layout == 20){
// TATE slot mask for RGB layouts; this is not realistic obviously, but it looks nice and avoids chromatic aberration
vec3 tatemask[4][4] = {
{green, magenta, green, magenta},
{black, blue, green, red},
{green, magenta, green, magenta},
{green, red, black, blue}
};
w = int(floor(mod(coord.y, 4.0)));
z = int(floor(mod(coord.x, 4.0)));
weights = tatemask[w][z];
return weights;
}
else return weights;
}
vec3 mask_weights_alpha(vec2 coord, float mask_intensity, int phosphor_layout, out float alpha){
vec3 weights = vec3(1.,1.,1.);
float on = 1.;
float off = 1.-mask_intensity;
vec3 red = vec3(on, off, off);// 1
vec3 green = vec3(off, on, off);// 1
vec3 blue = vec3(off, off, on );// 1
vec3 magenta = vec3(on, off, on );// 2
vec3 yellow = vec3(on, on, off);// 2
vec3 cyan = vec3(off, on, on );// 2
vec3 black = vec3(off, off, off);// 0
vec3 white = vec3(on, on, on );// 3
int w, z = 0;
alpha = 1.;
// This pattern is used by a few layouts, so we'll define it here
vec3 aperture_weights = mix(magenta, green, floor(mod(coord.x, 2.0)));
if(phosphor_layout == 0) return weights;
else if(phosphor_layout == 1){
// classic aperture for RGB panels; good for 1080p, too small for 4K+
// aka aperture_1_2_bgr
weights.rgb = aperture_weights;
alpha = 3./6.;
return weights;
}
else if(phosphor_layout == 2){
// 2x2 shadow mask for RGB panels; good for 1080p, too small for 4K+
// aka delta_1_2x1_bgr
vec3 inverse_aperture = mix(green, magenta, floor(mod(coord.x, 2.0)));
weights = mix(aperture_weights, inverse_aperture, floor(mod(coord.y, 2.0)));
alpha = 6./12.;
return weights;
}
else if(phosphor_layout == 3){
// slot mask for RGB panels; looks okay at 1080p, looks better at 4K
vec3 slotmask[3][4] = {
{magenta, green, black, black},
{magenta, green, magenta, green},
{black, black, magenta, green}
};
// find the vertical index
w = int(floor(mod(coord.y, 3.0)));
// find the horizontal index
z = int(floor(mod(coord.x, 4.0)));
// use the indexes to find which color to apply to the current pixel
weights = slotmask[w][z];
alpha = 12./36.;
return weights;
}
else if(phosphor_layout == 4){
// classic aperture for RBG panels; good for 1080p, too small for 4K+
weights = mix(yellow, blue, floor(mod(coord.x, 2.0)));
alpha = 3./6.;
return weights;
}
else if(phosphor_layout == 5){
// 2x2 shadow mask for RBG panels; good for 1080p, too small for 4K+
vec3 inverse_aperture = mix(blue, yellow, floor(mod(coord.x, 2.0)));
weights = mix(mix(yellow, blue, floor(mod(coord.x, 2.0))), inverse_aperture, floor(mod(coord.y, 2.0)));
alpha = 6./12.;
return weights;
}
else if(phosphor_layout == 6){
// aperture_1_4_rgb; good for simulating lower
vec3 ap4[4] = vec3[](red, green, blue, black);
z = int(floor(mod(coord.x, 4.0)));
weights = ap4[z];
alpha = 3./12.;
return weights;
}
else if(phosphor_layout == 7){
// aperture_2_5_bgr
vec3 ap3[5] = vec3[](red, magenta, blue, green, green);
z = int(floor(mod(coord.x, 5.0)));
weights = ap3[z];
alpha = 6./15.;
return weights;
}
else if(phosphor_layout == 8){
// aperture_3_6_rgb
vec3 big_ap[7] = vec3[](red, red, yellow, green, cyan, blue, blue);
w = int(floor(mod(coord.x, 7.)));
weights = big_ap[w];
alpha = 8./18.;
return weights;
}
else if(phosphor_layout == 9){
// reduced TVL aperture for RGB panels
// aperture_2_4_rgb
vec3 big_ap_rgb[4] = vec3[](red, yellow, cyan, blue);
w = int(floor(mod(coord.x, 4.)));
weights = big_ap_rgb[w];
alpha = 6./12.;
return weights;
}
else if(phosphor_layout == 10){
// reduced TVL aperture for RBG panels
vec3 big_ap_rbg[4] = vec3[](red, magenta, cyan, green);
w = int(floor(mod(coord.x, 4.)));
weights = big_ap_rbg[w];
alpha = 6./12.;
return weights;
}
else if(phosphor_layout == 11){
// delta_1_4x1_rgb; dunno why this is called 4x1 when it's obviously 4x2 /shrug
vec3 delta1[2][4] = {
{red, green, blue, black},
{blue, black, red, green}
};
w = int(floor(mod(coord.y, 2.0)));
z = int(floor(mod(coord.x, 4.0)));
weights = delta1[w][z];
alpha = 6./24.;
return weights;
}
else if(phosphor_layout == 12){
// delta_2_4x1_rgb
vec3 delta[2][4] = {
{red, yellow, cyan, blue},
{cyan, blue, red, yellow}
};
w = int(floor(mod(coord.y, 2.0)));
z = int(floor(mod(coord.x, 4.0)));
weights = delta[w][z];
alpha = 12./24.;
return weights;
}
else if(phosphor_layout == 13){
// delta_2_4x2_rgb
vec3 delta[4][4] = {
{red, yellow, cyan, blue},
{red, yellow, cyan, blue},
{cyan, blue, red, yellow},
{cyan, blue, red, yellow}
};
w = int(floor(mod(coord.y, 4.0)));
z = int(floor(mod(coord.x, 4.0)));
weights = delta[w][z];
alpha = 24./48.;
return weights;
}
else if(phosphor_layout == 14){
// slot mask for RGB panels; too low-pitch for 1080p, looks okay at 4K, but wants 8K+
vec3 slotmask[3][6] = {
{magenta, green, black, black, black, black},
{magenta, green, black, magenta, green, black},
{black, black, black, magenta, green, black}
};
w = int(floor(mod(coord.y, 3.0)));
z = int(floor(mod(coord.x, 6.0)));
weights = slotmask[w][z];
alpha = 12./54.;
return weights;
}
else if(phosphor_layout == 15){
// slot_2_4x4_rgb
vec3 slot2[4][8] = {
{red, yellow, cyan, blue, red, yellow, cyan, blue },
{red, yellow, cyan, blue, black, black, black, black},
{red, yellow, cyan, blue, red, yellow, cyan, blue },
{black, black, black, black, red, yellow, cyan, blue }
};
w = int(floor(mod(coord.y, 4.0)));
z = int(floor(mod(coord.x, 8.0)));
weights = slot2[w][z];
alpha = 36./96.;
return weights;
}
else if(phosphor_layout == 16){
// slot mask for RBG panels; too low-pitch for 1080p, looks okay at 4K, but wants 8K+
vec3 slotmask[3][4] = {
{yellow, blue, black, black},
{yellow, blue, yellow, blue},
{black, black, yellow, blue}
};
w = int(floor(mod(coord.y, 3.0)));
z = int(floor(mod(coord.x, 4.0)));
weights = slotmask[w][z];
alpha = 14./36.;
return weights;
}
else if(phosphor_layout == 17){
// slot_2_5x4_bgr
vec3 slot2[4][10] = {
{red, magenta, blue, green, green, red, magenta, blue, green, green},
{black, blue, blue, green, green, red, red, black, black, black},
{red, magenta, blue, green, green, red, magenta, blue, green, green},
{red, red, black, black, black, black, blue, blue, green, green}
};
w = int(floor(mod(coord.y, 4.0)));
z = int(floor(mod(coord.x, 10.0)));
weights = slot2[w][z];
alpha = 36./120.;
return weights;
}
else if(phosphor_layout == 18){
// same as above but for RBG panels
vec3 slot2[4][10] = {
{red, yellow, green, blue, blue, red, yellow, green, blue, blue },
{black, green, green, blue, blue, red, red, black, black, black},
{red, yellow, green, blue, blue, red, yellow, green, blue, blue },
{red, red, black, black, black, black, green, green, blue, blue }
};
w = int(floor(mod(coord.y, 4.0)));
z = int(floor(mod(coord.x, 10.0)));
weights = slot2[w][z];
alpha = 36./120.;
return weights;
}
else if(phosphor_layout == 19){
// slot_3_7x6_rgb
vec3 slot[6][14] = {
{red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue},
{red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue},
{red, red, yellow, green, cyan, blue, blue, black, black, black, black, black, black, black},
{red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue},
{red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue},
{black, black, black, black, black, black, black, black, red, red, yellow, green, cyan, blue}
};
w = int(floor(mod(coord.y, 6.0)));
z = int(floor(mod(coord.x, 14.0)));
weights = slot[w][z];
alpha = 89./252.; // 49+(2*20)
return weights;
}
else if(phosphor_layout == 20){
// TATE slot mask for RGB layouts; this is not realistic obviously, but it looks nice and avoids chromatic aberration
vec3 tatemask[4][4] = {
{green, magenta, green, magenta},
{black, blue, green, red},
{green, magenta, green, magenta},
{green, red, black, blue}
};
w = int(floor(mod(coord.y, 4.0)));
z = int(floor(mod(coord.x, 4.0)));
weights = tatemask[w][z];
alpha = 18./48.;
return weights;
}
else return weights; else return weights;
} }

View File

@ -11,14 +11,14 @@ float_framebuffer0 = true
shader1 = shaders/gtu-famicom/lowPass.slang shader1 = shaders/gtu-famicom/lowPass.slang
scale_type1 = source scale_type1 = source
scale_1 = 1.0 scale1 = 1.0
filter_linear1 = false filter_linear1 = false
frame_count_mod1 = 32 frame_count_mod1 = 32
float_framebuffer1 = true float_framebuffer1 = true
shader2 = shaders/gtu-famicom/combFilter.slang shader2 = shaders/gtu-famicom/combFilter.slang
scale_type2 = source scale_type2 = source
scale_2 = 1.0 scale2 = 1.0
filter_linear2 = false filter_linear2 = false
frame_count_mod2 = 2 frame_count_mod2 = 2
float_framebuffer2 = true float_framebuffer2 = true

View File

@ -6,7 +6,7 @@ wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false" mipmap_input0 = "false"
alias0 = "ORIG_LINEARIZED" alias0 = "ORIG_LINEARIZED"
float_framebuffer0 = "false" float_framebuffer0 = "false"
srgb_framebuffer0 = "0" srgb_framebuffer0 = "false"
scale_type_x0 = "viewport" scale_type_x0 = "viewport"
scale_x0 = "1.000000" scale_x0 = "1.000000"
scale_type_y0 = "source" scale_type_y0 = "source"