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>
@ -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"
|
@ -12,19 +12,19 @@ alias2 = internal2
|
||||
|
||||
shader3 = shaders/geom-deluxe/gaussy.slang
|
||||
filter_linear3 = true
|
||||
alias3 = blur
|
||||
alias3 = blur_texture
|
||||
|
||||
shader4 = shaders/geom-deluxe/crt-geom-deluxe.slang
|
||||
filter_linear4 = true
|
||||
mipmap_input4 = true
|
||||
|
||||
# comment these mask textures since we're generating them in the shader
|
||||
#textures = "aperture;slot;delta"
|
||||
#delta = shaders/geom-deluxe/masks/delta_2_4x1_rgb.png
|
||||
#delta_filter_linear = true
|
||||
#delta_repeat_mode = repeat
|
||||
#slot = shaders/geom-deluxe/masks/slot_2_5x4_bgr.png
|
||||
#slot_filter_linear = true
|
||||
#slot_repeat_mode = repeat
|
||||
#aperture = shaders/geom-deluxe/masks/aperture_2_4_rgb.png
|
||||
#aperture_filter_linear = true
|
||||
#aperture_repeat_mode = repeat
|
||||
textures = "aperture;slot;delta"
|
||||
delta = shaders/geom-deluxe/masks/delta_2_4x1_rgb.png
|
||||
delta_filter_linear = true
|
||||
delta_repeat_mode = repeat
|
||||
slot = shaders/geom-deluxe/masks/slot_2_5x4_bgr.png
|
||||
slot_filter_linear = true
|
||||
slot_repeat_mode = repeat
|
||||
aperture = shaders/geom-deluxe/masks/aperture_2_4_rgb.png
|
||||
aperture_filter_linear = true
|
||||
aperture_repeat_mode = repeat
|
||||
|
@ -19,8 +19,8 @@ shader2 = shaders/glow/gauss_horiz.slang
|
||||
filter_linear2 = false
|
||||
scale_type_x2 = viewport
|
||||
scale_type_y2 = source
|
||||
scale_x = 1.0
|
||||
scale_y = 1.0
|
||||
scale_x2 = 1.0
|
||||
scale_y2 = 1.0
|
||||
srgb_framebuffer2 = true
|
||||
|
||||
shader3 = shaders/glow/gauss_vert.slang
|
||||
|
@ -8,8 +8,8 @@ shader1 = shaders/glow/lanczos_horiz.slang
|
||||
filter_linear1 = false
|
||||
scale_type_x1 = viewport
|
||||
scale_type_y1 = source
|
||||
scale_x = 1.0
|
||||
scale_y = 1.0
|
||||
scale_x1 = 1.0
|
||||
scale_y1 = 1.0
|
||||
srgb_framebuffer1 = true
|
||||
|
||||
shader2 = shaders/glow/gauss_vert.slang
|
||||
|
@ -15,5 +15,5 @@ float_framebuffer1 = true
|
||||
|
||||
shader2 = shaders/gtu-v050/pass3.slang
|
||||
scale_type2 = viewport
|
||||
scale_2 = 1.0
|
||||
filter_linear2 = false
|
||||
scale2 = 1.0
|
||||
filter_linear2 = false
|
||||
|
@ -15,8 +15,9 @@
|
||||
#include "../../../include/subpixel_masks.h"
|
||||
|
||||
#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_tex_size1 vec2(global.OutputSize.xy * global.SourceSize.zw)
|
||||
|
||||
// Comment the next line to disable interpolation in linear gamma (and gain speed).
|
||||
#define LINEAR_PROCESSING
|
||||
@ -125,20 +126,36 @@ layout(location = 4) in vec2 v_one;
|
||||
layout(location = 5) in vec2 ilfac;
|
||||
layout(location = 6) in vec2 TextureSize;
|
||||
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;
|
||||
// comment these out, as we're using generated masks instead of LUTs
|
||||
//layout(set = 0, binding = 4) uniform sampler2D aperture;
|
||||
//layout(set = 0, binding = 5) uniform sampler2D slot;
|
||||
//layout(set = 0, binding = 6) uniform sampler2D delta;
|
||||
|
||||
#define blur_texture blur
|
||||
layout(set = 0, binding = 4) uniform sampler2D aperture;
|
||||
layout(set = 0, binding = 5) uniform sampler2D slot;
|
||||
layout(set = 0, binding = 6) uniform sampler2D delta;
|
||||
layout(set = 0, binding = 7) uniform sampler2D phosphor;
|
||||
|
||||
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
|
||||
# define TEX2D(c) pow(texture(internal1, (c)), vec4(CRTgamma))
|
||||
#else
|
||||
# define TEX2D(c) texture(internal1, (c))
|
||||
col = pow(col, vec4(CRTgamma.x));
|
||||
#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)
|
||||
{
|
||||
@ -239,9 +256,15 @@ void main()
|
||||
xy = transform(v_texCoord, v_stretch, v_sinangle, v_cosangle);
|
||||
else
|
||||
xy = (v_texCoord-vec2(0.5))/overscan.xy+vec2(0.5);
|
||||
vec2 xy0 = 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
|
||||
// currently rendering, which pixel are we currently rendering?
|
||||
|
||||
@ -305,20 +328,46 @@ void main()
|
||||
vec3 mul_res = (col * weights + col2 * weights2).rgb;
|
||||
|
||||
// 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);
|
||||
|
||||
// include factor of rbloom:
|
||||
|
||||
// (probably imperceptible) brightness reduction when raster grows
|
||||
// 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
|
||||
// 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
|
||||
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);
|
||||
|
||||
// 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(mul_res*mask, col.a);
|
||||
FragColor = vec4(cout, col.a);
|
||||
}
|
||||
|
@ -1,8 +1,31 @@
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
float phosphor_power, phosphor_amplitude, CRTgamma, width, aspect_x, aspect_y, d, R, angle_x, angle_y,
|
||||
aperture_strength, halation, curvature, cornersize, cornersmooth, overscan_x, overscan_y,
|
||||
monitorgamma, mask_type, SHARPER, scanline_weight, geom_lum, interlace_detect;
|
||||
float phosphor_power;
|
||||
float phosphor_amplitude;
|
||||
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;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO
|
||||
@ -11,16 +34,19 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
vec4 internal1Size;
|
||||
vec4 FinalViewportSize;
|
||||
vec4 internal1Size;
|
||||
mat4 MVP;
|
||||
} 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_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_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 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
|
||||
@ -50,12 +76,16 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
#define monitorgamma params.monitorgamma
|
||||
#define halation params.halation
|
||||
#define aperture_strength params.aperture_strength
|
||||
#define aperture_brightboost params.aperture_brightboost
|
||||
#define geom_lum params.geom_lum
|
||||
#define scanline_weight params.scanline_weight
|
||||
#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 angle = vec2(params.angle_x, params.angle_y);
|
||||
vec2 overscan = vec2(params.overscan_x, params.overscan_y);
|
||||
int mask_picker = int(params.mask_type);
|
||||
vec4 blurwidth = vec4(width);
|
||||
|
||||
const float gamma = 2.2;
|
||||
|
BIN
crt/shaders/geom-deluxe/masks/aperture_1_2_bgr.png
Normal file → Executable file
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
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
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
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
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
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
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
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
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
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
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
Before Width: | Height: | Size: 180 B After Width: | Height: | Size: 109 B |
@ -35,7 +35,7 @@ filter_linear5 = true
|
||||
scale_type5 = source
|
||||
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"
|
||||
SCALE = "0.6667"
|
||||
OUT_X = "1600.0"
|
||||
|
@ -33,7 +33,7 @@ alias4 = "PASS4"
|
||||
shader5 = shader-files/gb-pass-5.slang
|
||||
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"
|
||||
SCALE = "1.0"
|
||||
OUT_X = "2400.0"
|
||||
|
@ -33,7 +33,7 @@ alias4 = "PASS4"
|
||||
shader5 = shader-files/gb-pass-5.slang
|
||||
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"
|
||||
SCALE = "1.0"
|
||||
OUT_X = "3200.0"
|
||||
|
@ -33,7 +33,7 @@ alias4 = "PASS4"
|
||||
shader5 = shader-files/gb-pass-5.slang
|
||||
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"
|
||||
SCALE = "1.25"
|
||||
OUT_X = "4000.0"
|
||||
|
@ -33,7 +33,7 @@ alias4 = "PASS4"
|
||||
shader5 = shader-files/gb-pass-5.slang
|
||||
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"
|
||||
SCALE = "1.5"
|
||||
OUT_X = "4800.0"
|
||||
|
@ -10,6 +10,8 @@ How to use it:
|
||||
Multiply your image by the vec3 output:
|
||||
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.
|
||||
gl_FragCoord (the "vec2 coord" input). In the case of slang shaders, we use
|
||||
(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 cyan = vec3(off, on, on );
|
||||
vec3 black = vec3(off, off, off);
|
||||
vec3 white = vec3(on, on, on );
|
||||
int w, z = 0;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -11,14 +11,14 @@ float_framebuffer0 = true
|
||||
|
||||
shader1 = shaders/gtu-famicom/lowPass.slang
|
||||
scale_type1 = source
|
||||
scale_1 = 1.0
|
||||
scale1 = 1.0
|
||||
filter_linear1 = false
|
||||
frame_count_mod1 = 32
|
||||
float_framebuffer1 = true
|
||||
|
||||
shader2 = shaders/gtu-famicom/combFilter.slang
|
||||
scale_type2 = source
|
||||
scale_2 = 1.0
|
||||
scale2 = 1.0
|
||||
filter_linear2 = false
|
||||
frame_count_mod2 = 2
|
||||
float_framebuffer2 = true
|
||||
@ -43,4 +43,4 @@ textures = nestable
|
||||
nestable = shaders/gtu-famicom/NesTable.png
|
||||
nestable_linear = false
|
||||
nestable_mipmap = false
|
||||
nestable_wrap_mode = clamp_to_border
|
||||
nestable_wrap_mode = clamp_to_border
|
||||
|
@ -6,7 +6,7 @@ wrap_mode0 = "clamp_to_border"
|
||||
mipmap_input0 = "false"
|
||||
alias0 = "ORIG_LINEARIZED"
|
||||
float_framebuffer0 = "false"
|
||||
srgb_framebuffer0 = "0"
|
||||
srgb_framebuffer0 = "false"
|
||||
scale_type_x0 = "viewport"
|
||||
scale_x0 = "1.000000"
|
||||
scale_type_y0 = "source"
|
||||
@ -18,4 +18,4 @@ nes_lut_wrap_mode = "repeat"
|
||||
nes_lut_mipmap = "false"
|
||||
|
||||
textures = "nes_lut"
|
||||
nes_lut = resources/nes_lut.png
|
||||
nes_lut = resources/nes_lut.png
|
||||
|