@guest.r, the glass will be implemented in your shader?
No, it’s a very fine shader though. It’s like when using the Retroarch shader interface both grade and glass can be added without much hassle. Same goes for editing the shader preset, since it’s about to replace the first stock pass or adding/replacing the last pass.
I noticed something about about the afterglow is that it seems to only show up over what was absolutely black, you can see what I mean in this pretty extreme image:
The trails disappear at the edge of the space clouds because the pixel art starts coming up from black
I think that’s actually fairly true-to-life.
Any time you use thresholds for stuff, values right on the border will look bad/unnatural. The alternative is to add the trails in linear gamma and then re-curve all of it together, which is elegant and “right” (AFAIK), but it ends up with trails from very bright pixels showing up in areas where they probably shouldn’t be visible (like dark areas that aren’t fully black). <- at least, I’ve never seen trails in those areas on my CRTs.
I believe the trails are mostly the result of the long tail of the exponential rolloff, so it would make sense that they would be drowned out by almost anything at all.
I tried to replace the first pass :
shader0 = shaders/guest/crt-gdv-new/stock.slang filter_linear0 = false scale_type0 = source scale0 = 1.0 alias0 = StockPass
with an xbr-hybrid pass:
shader0 = “…/xbr/shaders/xbr-hybrid/2xbr-hybrid-v5-gamma.slang” filter_linear0 = “false” wrap_mode0 = “clamp_to_border” mipmap_input0 = “false” alias0 = “” float_framebuffer0 = “false” srgb_framebuffer0 = “false” scale_type_x0 = “source” scale_x0 = “2.000000” scale_type_y0 = “source” scale_y0 = “1.000000”
and it failed. It’s probably an obvious error but if anyone can post a working xbr-hybrid preset, it will be much appreciated!
Ok that makes sense, what is the effect seen here where you see the last few frames?
Dunno. Could be the camera itself. That’s one of the problems with looking at pictures of CRTs: it’s hard to tell what’s from the display and what’s from the camera
Hey there.
It’s a bit complicated because the core crt pass can’t rely on it’s predecessors pixel size due of previous scalings that set it abroad. That’s why it relies on the original pixel sizes, but scaling you like to have has no effect.
Your best option is to use the ntsc preset, set both ntsc passes to stock and scalings to 1.0 and then include the xbr-hybrid as the first pass with x-scaling set to 2.0.
Ah, I see. It would break too many things. I have been using it; just wondering if maybe I shouldn’t be
That’s why is posted the shader, so you guys can use it.
Thank you for the instructions. I think I got it working now. I don’t know how to post the preset in a separate section with proper format like you guys did but I’ll just share it below in case that anyone is interested. If there’s anything wrong with the preset please let me know. Thanks!
shaders = 11
shader0 = “…/xbr/shaders/xbr-hybrid/2xbr-hybrid-v5-gamma.slang” filter_linear0 = “false” wrap_mode0 = “clamp_to_border” mipmap_input0 = “false” alias0 = “” float_framebuffer0 = “false” srgb_framebuffer0 = “false” scale_type_x0 = “source” scale_x0 = “2.000000” scale_type_y0 = “source” scale_y0 = “1.000000”
shader1 = shaders/guest/crt-gdv-new/stock.slang filter_linear1 = false scale_type1 = source scale1 = 1.0 alias1 = StockPass
shader2 = shaders/guest/crt-gdv-new/afterglow0.slang filter_linear2 = false scale_type2 = source scale2 = 1.0 alias2 = AfterglowPass
shader3 = shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang filter_linear3 = false scale_type3 = source scale3 = 1.0
textures = “SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4” SamplerLUT1 = shaders/guest/lut/sony_trinitron1.png SamplerLUT1_linear = true SamplerLUT2 = shaders/guest/lut/sony_trinitron2.png SamplerLUT2_linear = true SamplerLUT3 = shaders/guest/lut/other1.png SamplerLUT3_linear = true SamplerLUT4 = shaders/guest/lut/custom_lut.png SamplerLUT4_linear = true
shader4 = shaders/guest/crt-gdv-new/stock.slang shader5 = shaders/guest/crt-gdv-new/stock.slang
filter_linear4 = false filter_linear5 = false
scale_type_x4 = source scale_type_y4 = source scale_x4 = 1.0 scale_y4 = 1.0 frame_count_mod4 = 2 float_framebuffer4 = true
scale_type5 = source scale_x5 = 1.0 scale_y5 = 1.0 alias5 = PrePass
shader6 = shaders/guest/crt-gdv-new/avg-lum-ntsc.slang filter_linear6 = true scale_type6 = source scale6 = 1.0 mipmap_input6 = true alias6 = AvgLumPass
shader7 = shaders/guest/crt-gdv-new/linearize-ntsc.slang filter_linear7 = true scale_type7 = source scale7 = 1.0 alias7 = LinearizePass float_framebuffer7 = true
shader8 = shaders/guest/crt-gdv-new/bloom_horizontal.slang filter_linear8 = true scale_type_x8 = viewport scale_x8 = 0.5 scale_type_y8 = source scale_y8 = 1.0 float_framebuffer8 = true
shader9 = shaders/guest/crt-gdv-new/bloom_vertical.slang filter_linear9 = true scale_type_x9 = viewport scale_x9 = 0.5 scale_type_y9 = viewport scale_y9 = 0.5 float_framebuffer9 = true alias9 = GlowPass
shader10 = shaders/guest/crt-gdv-new/crt-guest-dr-venom2-ntsc.slang filter_linear10 = true scale_type10 = viewport scale_x10 = 1.0 scale_y10 = 1.0
I’m really happy with the current state of guest2. Here’s my preset in case anyone is interested. I was aiming toward a consumer preset that kept things bright (@ 4K). Works at 1080p just need to change the mask size from 2 to 1.
First, you need this to be present in \RetroArch\shaders\shaders_slang\crt\shaders\guest (call it coarse.slang)
#version 450
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float dsize;
} params;
#pragma parameter dsize "Scanline dithering size" 1.0 0.0 2.0 0.10
#define dsize params.dsize // Dithering size
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()
{
vec2 tex = vTexCoord;
vec2 pos = tex * params.OutputSize.xy;
vec2 dy = dsize*vec2(0.0, params.OutputSize.w);
float mixer = floor(mod(pos.x,2.0));
tex = mix(tex + 0.0*dy, tex - dy, mixer);
FragColor = vec4(texture(Source, tex).rgb, 1.0);
}
Now for the preset (place @ \RetroArch\shaders):
shaders = "12"
shader0 = "shaders_slang/crt/shaders/guest/crt-gdv-new/stock.slang"
filter_linear0 = "false"
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
alias0 = "StockPass"
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
scale_type_x0 = "source"
scale_x0 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "shaders_slang/crt/shaders/guest/crt-gdv-new/afterglow0.slang"
filter_linear1 = "false"
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 = "shaders_slang/crt/shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang"
filter_linear2 = "false"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = "PrePass"
float_framebuffer2 = "false"
srgb_framebuffer2 = "false"
scale_type_x2 = "source"
scale_x2 = "1.000000"
scale_type_y2 = "source"
scale_y2 = "1.000000"
shader3 = "shaders_slang/crt/shaders/guest/crt-gdv-new/avg-lum.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "true"
alias3 = "AvgLumPass"
float_framebuffer3 = "false"
srgb_framebuffer3 = "false"
scale_type_x3 = "source"
scale_x3 = "1.000000"
scale_type_y3 = "source"
scale_y3 = "1.000000"
shader4 = "shaders_slang/crt/shaders/guest/crt-gdv-new/linearize.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "false"
alias4 = "LinearizePass"
float_framebuffer4 = "true"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "1.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "shaders_slang/crt/shaders/guest/crt-gdv-new/gaussian_horizontal.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = ""
float_framebuffer5 = "true"
srgb_framebuffer5 = "false"
scale_type_x5 = "viewport"
scale_x5 = "0.500000"
scale_type_y5 = "source"
scale_y5 = "1.000000"
shader6 = "shaders_slang/crt/shaders/guest/crt-gdv-new/gaussian_vertical.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = "GlowPass"
float_framebuffer6 = "true"
srgb_framebuffer6 = "false"
scale_type_x6 = "viewport"
scale_x6 = "0.500000"
scale_type_y6 = "viewport"
scale_y6 = "0.500000"
shader7 = "shaders_slang/crt/shaders/guest/crt-gdv-new/bloom_horizontal.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = ""
float_framebuffer7 = "true"
srgb_framebuffer7 = "false"
scale_type_x7 = "source"
scale_x7 = "1.000000"
scale_type_y7 = "source"
scale_y7 = "1.000000"
shader8 = "shaders_slang/crt/shaders/guest/crt-gdv-new/bloom_vertical.slang"
filter_linear8 = "true"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "false"
alias8 = "BloomPass"
float_framebuffer8 = "true"
srgb_framebuffer8 = "false"
scale_type_x8 = "source"
scale_x8 = "1.000000"
scale_type_y8 = "source"
scale_y8 = "1.000000"
shader9 = "shaders_slang/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2.slang"
filter_linear9 = "true"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "false"
alias9 = ""
float_framebuffer9 = "false"
srgb_framebuffer9 = "false"
scale_type_x9 = "viewport"
scale_x9 = "1.000000"
scale_type_y9 = "viewport"
scale_y9 = "1.000000"
shader10 = "shaders_slang/crt/shaders/guest/crt-gdv-new/deconvergence.slang"
filter_linear10 = "true"
wrap_mode10 = "clamp_to_border"
mipmap_input10 = "false"
alias10 = ""
float_framebuffer10 = "false"
srgb_framebuffer10 = "false"
scale_type_x10 = "viewport"
scale_x10 = "1.000000"
scale_type_y10 = "viewport"
scale_y10 = "1.000000"
shader11 = "shaders_slang/crt/shaders/guest/coarse.slang"
filter_linear11 = "true"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
alias11 = ""
float_framebuffer11 = "false"
srgb_framebuffer11 = "false"
scale_type_x11 = "source"
scale_x11 = "1.000000"
scale_type_y11 = "source"
scale_y11 = "1.000000"
parameters = "bogus_afterglow;PR;PG;PB;AS;sat;bogus_color;TNTC;LS;LUTLOW;LUTBR;CP;CS;WP;wp_saturation;BP;lsmooth;GAMMA_INPUT;bogus_interlacing;inter;interm;inters;iscan;bogus_glow;SIZEH;SIGMA_H;SIZEV;SIGMA_V;SIZEHB;SIGMA_HB;SIZEVB;SIGMA_VB;bogus_brightness;glow;bloom;halation;contrastd;gamma_c;brightboost;brightboost1;bogus_scanline;gsl;scanline1;scanline2;beam_min;beam_max;beam_size;vertmask;scans;spike;bogus_filtering;h_sharp;s_sharp;smart_ei;ei_limit;sth;bogus_screen;TATE;IOS;OS;BLOOM;csize;bsize;warpX;warpY;overscanX;overscanY;bogus_masks;shadowMask;maskstr;masksize;maskDark;maskLight;mcut;mask_gamma;slotmask;slotwidth;double_slot;slotms;mclip;gamma_out;bogus_hdeconvergence;deconr;decons;cswitch;addnoise;dsize"
bogus_afterglow = "0.000000"
PR = "0.140000"
PG = "0.140000"
PB = "0.140000"
AS = "0.070000"
sat = "0.100000"
bogus_color = "0.000000"
TNTC = "0.000000"
LS = "32.000000"
LUTLOW = "5.000000"
LUTBR = "1.000000"
CP = "1.000000"
CS = "0.000000"
WP = "-100.000000"
wp_saturation = "1.000000"
BP = "0.000000"
lsmooth = "0.700000"
GAMMA_INPUT = "2.400000"
bogus_interlacing = "0.000000"
inter = "350.000000"
interm = "1.000000"
inters = "0.000000"
iscan = "0.200000"
bogus_glow = "0.000000"
SIZEH = "6.000000"
SIGMA_H = "1.200000"
SIZEV = "6.000000"
SIGMA_V = "1.200000"
SIZEHB = "4.000000"
SIGMA_HB = "0.700000"
SIZEVB = "4.000000"
SIGMA_VB = "0.700000"
bogus_brightness = "0.000000"
glow = "0.080000"
bloom = "0.300000"
halation = "0.150000"
contrastd = "0.000000"
gamma_c = "1.000000"
brightboost = "1.400000"
brightboost1 = "1.100000"
bogus_scanline = "0.000000"
gsl = "-1.000000"
scanline1 = "6.000000"
scanline2 = "8.000000"
beam_min = "1.300000"
beam_max = "1.000000"
beam_size = "0.600000"
vertmask = "0.500000"
scans = "0.600000"
spike = "1.000000"
bogus_filtering = "0.000000"
h_sharp = "4.000001"
s_sharp = "0.000000"
smart_ei = "0.000000"
ei_limit = "2.000000"
sth = "0.200000"
bogus_screen = "0.000000"
TATE = "0.000000"
IOS = "0.000000"
OS = "1.000000"
BLOOM = "0.000000"
csize = "0.000000"
bsize = "600.000000"
warpX = "0.000000"
warpY = "0.000000"
overscanX = "0.000000"
overscanY = "0.000000"
bogus_masks = "0.000000"
shadowMask = "2.000000"
maskstr = "0.300000"
masksize = "2.000000"
maskDark = "0.500000"
maskLight = "1.500000"
mcut = "1.150000"
mask_gamma = "2.400000"
slotmask = "0.000000"
slotwidth = "2.000000"
double_slot = "1.000000"
slotms = "1.000000"
mclip = "0.500000"
gamma_out = "2.400000"
bogus_hdeconvergence = "0.000000"
deconr = "0.500000"
decons = "0.500000"
cswitch = "1.000000"
addnoise = "0.200000"
dsize = "1.000000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
SamplerLUT1 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron1.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron2.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "shaders_slang/crt/shaders/guest/lut/other1.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"
SamplerLUT4 = "shaders_slang/crt/shaders/guest/lut/custom_lut.png"
SamplerLUT4_linear = "true"
SamplerLUT4_wrap_mode = "clamp_to_border"
SamplerLUT4_mipmap = "false"
I hope you enjoy it; just beat the wonderful “Mega Man X3 - Zero Project V4.1”
New Release Version (31.01.2021-r1):
Notable changes:
- deconvergence pass: deconvergence looks much nicer due mask synced offsets.
Download link:
https://mega.nz/file/x8pEib5C#xq9zus18L0UhEFTOTajsIGiq3XRSN4LC9l4zl3kAZVE
Edit:
- Nice deconvergence improvements.
- some fixes.
@guest.r @HyperspaceMadness It works finally!!! I renamed the base shader folder and I deleted the “dots” in the name, and now works like a charm all shaders!!!
Thanks!
Hi the switch deconvergence colors doesn’t work anymore with this release (my preference is to have the red deconvergence on the right, but it will always be on the left)
Also the stepping value for strength seems to be increased as I can’t make it as subtle as I had it before…
Hope both can be fixed
It was fixed right before you posted. Now you can alter all three color components offsets individually. What is maybe worse is the larger offset step for mask preservation.
OK
I had another play with the strength and maybe I can get it close to the same as it was, so main issue was indeed the switch.
Edit: I read something about some CRTs not being able to switch of the beam quickly enough such that (bright?) pixels have a small trail in the beam direction. Not sure what it’s called but what’s your take on that?
I call it ‘left to right shadowing’. Seems hard to reproduce properly. Sometimes it’s like candle in the wind on my TV. Gave it a thought many times and what bothered me was the effect inconsistency. I also think it would become an annoyance with playing games after a period of curiosity if always shadowed over black colors.
I apologize for not bringing this up earlier, but the “Glow/Bloom Pass Settings” in the NTSC version have been without their header for while now, lumping them in with the “Interlacing Options”.
With that out of the way, any plans for more masks? I find that the specific mask (and its size), when at max strength, greatly affects how the brightness settings affect the colors.
Also, I’ve been withholding an idea for while on the grounds that it might be crazy. But I shouldn’t withhold ideas like that.
Could the curvature settings theoretically be set to negative for a concave curve? I don’t know anything about slang code, but it seems simple on the surface. Or is the simplicity deceptive? Would it cause more problems than it’s worth? Would it give @HyperspaceMadness a headache?
I know it’s not accurate to real CRT displays. But I imagine the effect on side-scrollers could be amazing… at least for those of us without curved monitors.
Great work as always by the way. I’m sorry If I may come off as unreasonably discontent or crazy. It’s just that it’s not my nature to be content, and I’m the sort of fellow who tried to play an ARPG with a HOTAS setup.
Good catch. Fixed now.
You can/should use bloom/halation to handle this situation. Masks at full strength don’t look that well with ordinary displays/SDR.
It would require a special function to handle this situation. And would complicate the situation indeed. I’m in general not a fan of making the code more messy as it already is.
Anyways, thanks for the feedback, helps a lot.
Back to the shader, deconvergence pass should be complete now. Some specific handling is required since masks get smeared etc., think a good compromise is implemented together with some new feature and fixes.
New Release Version (31.01.2021-r4):
Download link:
https://mega.nz/file/Mw4DCCzS#l0t8sqRS5gJYgTKXN-9MNsW3nLA99eaq3aZwSDlWtAQ