New CRT shader from Guest + CRT Guest Advanced updates

When updating should be possible again, i would definitely like to update the standard version in the ‘crt’ directory with the new one. Dunno about the NTSC version, it’s more likable for my personal taste, but should depend on feedback/popular vote.

New versions require SLANG, so old ones would be still available trough GLSL, which is too hard to update with most features in my taste.

Brightboost got a supplement in form of ‘gamma correct’, which has nice advantages. First you don’t grow old by waiting for the parameter to increase, secondly it’s consistent with all gamma values (input == output +/- 10%) and it preserves saturation ofc. Raising output gamma in order to get darker colors brighter is not needed as a resort, in fact, you can more easily manage this in general. Brightboost reverted to old behaviour for now…

I’m guessing here a bit, but afaik clipping dulls the masks with bright colors. GDV shader preserves masks to min. 40%.

If you look at the end of the shader:

color = min(color, mix(cmask,one,0.6));

Changing 0.6 to 0.0 will preserve the masks from clipping.

There are more changes with the shaders. Scanline saturation is a bit nicer, i removed some parameters from the Afterglow shader (3), after some consideration removed the horizontal deconvergence and scanline edge darkening, which didn’t pass in too many situations. Scanline edges can be darkened easily with the scanline shape parameter, with much better consistency as saturation isn’t affected any more.

But…horizontal deconvergence (RB / BR) is implemented with the NTSC version, which is different and can deal with the concept. Looks quite nice.

There are also some small changes / tweaks which should go by unnoticed.

New (updated) version download link:

https://mega.nz/file/xw43QSbT#WsRhzB04RQXWnpODYJwxTxRVLMUhvqCJfthtKb5nlQw

Feedback is welcome… :upside_down_face:

Edit: very quick NTSC setup + a PSX game at 2x resolution:

10 Likes

First impression after a quick round of testing: very nice update!

Significant improvement in color fidelity, consistency and usability. Liking the improvement all around :heart_eyes:

But I miss a feature of the previous update :frowning: :

Can you please add back in the “Darken Scanline ‘edges’” (even if it’s a commented one in the source, to uncomment for people like me? )

I really like the default setting of scanline low high 6-8 and then a touch of the above. It’s a really nice feature to just find that sweetspot on the scanline shape personally.)

Some questions:

What’s the difference between ‘Saturation’ and ‘Scanline saturation’? Also is saturation at 1.0 “neutral” or is it adding or substracting saturation?

Thanks for the continued improvement!

1 Like

OK, it can be quite usable. :grin: I posted the updated version above.

Standard saturation (in this shader) is neutral at 1.0.

Scanline saturation is something different, but quite observable. Quickly explained from the view of the shader the darker edges of the beam are also more saturated since different weight values are produced for different valued color components. At the center of the beam they are same (approx 1.0) and they diverge from the center away. Most CRT-s scanline edges are saturated, so this should be an endorsed behavior with CRT shaders, and it also looks nicer.

But It’s hard to determine what is neutral here, similar like BW isn’t neutral and increased saturation also isn’t neutral. :wink: Former implementation had this quite unpredictable since altering scanline parameters altered this appearance. New implementation complies with the parameter value in almost all situations.

2 Likes

Tried this, but the maximum RGB intensity value for the phosphors is around 60%, that’s with something that’s supposed to be 100% white. How do we get the max value to be 100%?

Raising brightboost light/dark doesn’t seem to increase the maximum color values.

1 Like

It’s probably settings related. In general such things should not be an issue. For example, if you run the RGB mask 2, set the ‘dark’ value to 0.0, ‘light’ value to 1.0, then you should get the full range.

If you want to get the color white even with masks, then you can do the opposite and set the above value to 1.0. Trinitron masks 5,6,7 are very easily tweaked to output max values at bright pixels.

You should get something like this with the ‘1.0’ correction to the code:

Maybe i should really add a parameter though.

3 Likes

@guest.r

Honestly, I’m having a hard a time with the latest version; gray ramp looks weird. I liked the previous version without gamma correct. This one is like a whole new shader, it behaves very differently from previous versions. Any chance you could provide a link to the previous version?

I don’t want to give up on the latest version, though. Here’s what things currently look like. Suggestions?

 shaders = "12"
shader0 = "shaders_slang/misc/grade.slang"
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
alias0 = ""
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
shader1 = "shaders_slang/crt/shaders/guest/lut/lut.slang"
filter_linear1 = "false"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = ""
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/color-profiles.slang"
filter_linear2 = "true"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = ""
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/d65-d50.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = "WhitePointPass"
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/afterglow.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "false"
alias4 = "AfterglowPass"
float_framebuffer4 = "false"
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/avg-lum.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "true"
alias5 = "AvgLumPass"
float_framebuffer5 = "true"
srgb_framebuffer5 = "false"
scale_type_x5 = "source"
scale_x5 = "1.000000"
scale_type_y5 = "source"
scale_y5 = "1.000000"
shader6 = "shaders_slang/crt/shaders/guest/linearize.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = "LinearizePass"
float_framebuffer6 = "true"
srgb_framebuffer6 = "false"
scale_type_x6 = "source"
scale_x6 = "1.000000"
scale_type_y6 = "source"
scale_y6 = "1.000000"
shader7 = "shaders_slang/crt/shaders/guest/linearize_scanlines.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = "ScanPass"
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/blur_horiz2.slang"
filter_linear8 = "true"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "false"
alias8 = ""
float_framebuffer8 = "true"
srgb_framebuffer8 = "false"
scale_type_x8 = "absolute"
scale_x8 = "800"
scale_type_y8 = "source"
scale_y8 = "1.000000"
shader9 = "shaders_slang/crt/shaders/guest/blur_vert2.slang"
filter_linear9 = "true"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "false"
alias9 = "GlowPass"
float_framebuffer9 = "true"
srgb_framebuffer9 = "false"
scale_type_x9 = "absolute"
scale_x9 = "800"
scale_type_y9 = "absolute"
scale_y9 = "600"
shader10 = "shaders_slang/crt/shaders/guest/crt-guest-dr-venom2.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/misc/glass.slang"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
alias11 = ""
float_framebuffer11 = "false"
srgb_framebuffer11 = "false"
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;TNTC;CP;CS;WP;wp_saturation;AS;PR;PG;PB;sat;lsmooth;GAMMA_INPUT;SIZEH;GLOW_FALLOFF_H;SIZEV;GLOW_FALLOFF_V;glow;bloom;TATE;IOS;OS;BLOOM;gamma_c;brightboost;brightboost1;gsl;scanline1;scanline2;beam_min;beam_max;beam_size;vertmask;scans;scansub;spike;h_sharp;s_sharp;csize;bsize;warpX;warpY;shadowMask;masksize;maskDark;maskLight;CGWG;mcut;slotmask;slotwidth;double_slot;slotms;inter;interm;gamma_out;g_csize;g_bsize;g_flicker;g_shaker;g_refltog;g_reflgrain;g_reflstr;g_fresnel;g_reflblur;gz;gx;gy;gzr;gzg;gzb;goxr;goyr;goxg;goyg;goxb;goyb;TO;PH;PER;ASAT;temperature;luma_preserve;wp_red;wp_green;wp_blue"
g_gamma_in = "2.400000"
g_signal_type = "1.000000"
g_gamma_type = "1.000000"
g_crtgamut = "2.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 = "8004.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"
TNTC = "0.000000"
CP = "0.000000"
CS = "0.000000"
WP = "0.000000"
wp_saturation = "1.000000"
AS = "0.070000"
PR = "0.050000"
PG = "0.050000"
PB = "0.050000"
sat = "0.100000"
lsmooth = "0.900000"
GAMMA_INPUT = "3.499999"
SIZEH = "4.000000"
GLOW_FALLOFF_H = "0.300000"
SIZEV = "4.000000"
GLOW_FALLOFF_V = "0.300000"
glow = "0.001000"
bloom = "0.000000"
TATE = "0.000000"
IOS = "0.000000"
OS = "1.000000"
BLOOM = "0.000000"
gamma_c = "1.000000"
brightboost = "1.000006"
brightboost1 = "10.000000"
gsl = "0.000000"
scanline1 = "1.000000"
scanline2 = "40.000000"
beam_min = "2.000001"
beam_max = "1.000000"
beam_size = "1.000000"
vertmask = "0.000000"
scans = "0.700000"
scansub = "0.005000"
spike = "0.000000"
h_sharp = "3.000000"
s_sharp = "1.000000"
csize = "0.000000"
bsize = "600.000000"
warpX = "0.000000"
warpY = "0.000000"
shadowMask = "2.000000"
masksize = "1.000000"
maskDark = "0.050000"
maskLight = "0.150000"
CGWG = "0.300000"
mcut = "1.200000"
slotmask = "0.000000"
slotwidth = "3.000000"
double_slot = "1.000000"
slotms = "1.000000"
inter = "400.000000"
interm = "1.000000"
gamma_out = "3.499999"
g_csize = "0.000000"
g_bsize = "2000.000000"
g_flicker = "0.000000"
g_shaker = "0.000000"
g_refltog = "0.000000"
g_reflgrain = "0.000000"
g_reflstr = "0.000000"
g_fresnel = "0.000000"
g_reflblur = "0.000000"
gz = "1.000000"
gx = "0.000000"
gy = "0.000000"
gzr = "1.000000"
gzg = "1.000000"
gzb = "1.000000"
goxr = "0.010000"
goyr = "0.000000"
goxg = "0.000000"
goyg = "0.010000"
goxb = "0.000000"
goyb = "0.000000"
TO = "1.000000"
PH = "2.000000"
PER = "0.750000"
ASAT = "0.200000"
temperature = "6500.000000"
luma_preserve = "1.000000"
wp_red = "0.000000"
wp_green = "0.000000"
wp_blue = "0.000000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3"
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"
1 Like

No worries, the parameter settings are a bit changed with a touch of gamma correct. I’m still working on the shader and it’s going to have the default settings reverted. ‘Gamma correct’ is an useful tool though if you need it and you could mismanage the brightboost values.

Edit, checked with the repository version and the ramp ‘shading’ in the working version is the same. But it does look a bit strange on the screenshot. And the one before. :confused:

1 Like

Try a fresh start by downloading his latest version and loading up guest.r default preset, the one in the package called “crt-guest-dr-venom2.slangp”. And work from that, the gamma curve is almost correct on that one.

I know by doing this you pass on grade.slang for the moment and your previously tweaked preset. But I did the same and it’s a worthwhile exercise and doesn’t cost you much. It will also provide honest feedback on guest.r his shader without grade.slang in the mix.

1 Like

I think i know the problem. New shader version could be used with the old preset.

shader7 = "shaders_slang/crt/shaders/guest/linearize_scanlines.slang"

This pass was removed in the standard version and kept in the NTSC one.

If you use the new shader, the scanlines use reference colors with gamma 10x too high.

Some noticed it, darn. :rofl:

1 Like

What does this mean? I’m currently content with my preset after doing a lot of testing, do I then need to go over that again? :frowning:

Did you look at his preset? There are some extreme parameter settings in there (gamma in/out 3.5/3.5, bright boost dark/bright 1.00/10.00, scanline low/high 1.00/40.00, etc… ) I mean the shader parameters are in there to ‘tweak’ the shader settings to your liking, not turn them upside down, right? (Otherwise something is wrong with either one of the three scanline types?)

With your last update which is now much more color correct, and scanline types 0, 1 and 2 are also more consistent in their agressiveness (i.e. instead of turning type 0 upside down, use type 1 or 2!), I consider these kind of extreme settings now not necessary anymore. IMO etc of course :hugs:

1 Like

I mean the default settings. :grin: Your settings should work pretty the same with the next version.

Phew, okay thanks. I started to worry a bit :sweat_smile:

So this is probably nitpicking, but the above doesn’t hold for the first bar in the color bars test. See comparison below. The raw color value of this first bar is “12”, while the shader value will be stuck at “8” when the rest of the curve is fitted exactly or within ±10%.

I’m not sure if this should be fixed though, as it could well be that real CRTs power function could easily fall off more strongly as well when close to zero voltage output?

1 Like

If you run the ‘new’ shader and the one from the libretro repository, there should be basically no notable changes, maybe a better glow in the new version.

I mentioned that ‘gamma correct’ is a tool to compensate the perceptive brightness reduction when thinning the scanlines, adding regular masks and the slotmask. With brightboost you get very different results regarding the color values and gamma combinations, but you practically cannot crank up the bright boost ‘bright’ since color clipping is something to be dealt with care.

Now there is 1 more tool (gamma correct) and it can be very helpful where brightboost has issues. You can also increase the monitor backlight intensity, but i guess most users aren’t comfortable with this.

Regarding the image…it’s tricky if you compare peak beam values and don’t take the ‘average area’ brightness into account. My personal preference will always be averaged brightness of the scanline with masks, but it’s tweakable and the default settings are quite neutral.

It’s really hard to compare though, since every CRT had it’s ways to tweak the brightness and even contrast. There are also differences between TN, IPS, VA, plasma and different models. Not to mention the tweaked gamma curve of the ‘new’ or ‘old’ technology plus the settings. I recently changed my display, my old one clipped scanlines (when i turned ‘magic color’ on) and had much lower contrast, for example. I just wan’t to say that it’s a lot of fun to discuss such matters, but very hard to consider the majority of the specific curious situations to be implemented in the shader.

2 Likes

The settings seem somewhat less intuitive now, but that might be because I’m used to doing extreme things to the shader. This definitely feels like starting completely from scratch, any advice for recreating my old guest-dr-venom preset (Type 0, the one that resembled a neotec arcade monitor)?

1 Like

I think you will have better options with the new version(s). The most ‘drastic’ change is how scanlines type 1&2 correct the brightness (in a mitigated way), trinitron masks, scanline saturation (is not an issue at all). Gamma correction is an option, glow is tad slower, but nicer, brightboosts work as usual.

OK, i will change the ‘brightboost bright’ to replace Bloom and it has much more freedom now. :smiley: Works the same when below 1.0 or slightly above 1.0, but can do some nicer stuff afterwards. I’m avoiding to make the code less reliable and feedback is very welcome, so it should work out nicely.

So you can tweak the old version a bit longer and check the ‘test versions’ a bit. I hope i’ll crack some nuts regarding some effects like afterglow etc. The main shader is nearly finished though, regressions are possible, but also fixable.

2 Likes

This sounds like a good idea; I dislike how the old bloom washes out the phosphors. Do you have a link to a test version?

Question about games / cores that run at double horizontal resolution. As we talked about previously this is happening for example sometimes in PSX core and always in PUAE core when resolution is set to Automatic. Lets forget about PSX core for now, as it -dynamically- switches between these resolutions (which is difficult to create solution for).

I only focus on PUAE core, as it can be set to a fixed / predictable situation. I’ll explain below.

Because of shader picture quality I previously set PUAE core option Resolution to “Low 360px”.

So now I noticed that interlace screens don’t work well when I set the core option for video resolution from Automatic to Low 360px. But I would like interlace screens to work well.

For interlace screens to work properly I need to set the following core options:

  • Video > Resolution: Automatic
  • Video > Line Mode: Automatic

If you look closely the above conforms for the most situations to:

  • Video > Resolution: High 720px
  • Video > Line Mode: Single

and only when interlace happens it switches the second to: Video > Line Mode: double

Everything fine for interlace. But because Resolution is now set to “Automatic” it effectively is at “High 720px” for everything and then shader output is too sharp for most games, as we discussed. But I need to have this at automatic for interlace to work properly.

So now my question: your shader is interpolating 5 or 6 pixels horizontally for effects? Could you tell me what I need to adjust in the shader code to have it interpolate the double amount of pixels (for example 10-12 pixels), such that it works the same when PUAE core is set to resolution Automatic (effectively High 720px)? Since it is always at 720px, never dynamically switching like PSX core, this should work?

I then would like to keep this version / patch seperately from the normal shader, so no need to worry to add extra code to main shader. I keep it purely as a patched shader for this core, all other cores use your normal shader. Or maybe, if it would be no burden to the shader, it’s even possible to do add a switch that internally in the shader, doubles the amount of pixels it takes for horizontal interpolation effect? That would be most charming solution! I would only switch it on for PUAE core and off for all other cores, and everything would be fine.

Please tell me it is possible to create this patch to accomodate for fixed double horizontal / 720px resolution :upside_down_face:

1 Like

It’s 6 texels, increased from 5 to get better filtering with high res content and even some increase in speed related with auxiliary stuff. It’s not going to change though, because i recently managed to get the shader performance similar to the old version. And the filtering is different, would make most users angry.

But you can try the NTSC version first (has 12 texel filtering) and i can adapt it for you (without the ntsc passes). This could work out even nicer since the NTSC version has a nice horizontal deconvergence implemented. Need some feedback first lol. :crazy_face:

Edit: almost forgot, you should replace the first two ntsc passes with the stock shader and set stock scalings to 1.0.

Edit: At the beginning of the crt-guest-dr-venom2-ntsc.slang main code part this line

vec4 SourceSize = global.OriginalSize * vec4(2.0, 1.0, 0.5, 1.0);

should be replaced with:

vec4 SourceSize = global.OriginalSize;

3 Likes

Thank you this works superb! :smiley: I made a before and after screenshot comparison, and the difference is practically negligible. This is with same sharpness setting (5.20) for both situations, great!

Note: The “vec4 SourceSize” adjustment does not seem necessary, as it makes the picture at sharpness 5.20 a bit too blurry. EDIT: I think I need to test that a bit further by raising sharpness and see how it then compares.

Would it be possible to add this as a switch to your NTSC shader, or call it “RGB” mode (composite/s-video/rgb) that effectively disables the first two passes? Or does it need a separate preset?

Regardless of the above: could you maybe add the following two features from your main shader to the NTSC schader?:

  • Gamma correct
  • “Darken Scanline ‘edges’”

I guess it can’t hurt, only make things better?

EDIT: been playing around a bit more with the ntsc shader without the two ntsc passes for use with the PUAE core, and I think the default settings are looking pretty great, well done :+1:. I only changed the vertical glow radius by half, as I think the 2:1 pixel ratio also created this ratio for the glow, and with the V radius halved it looks nicely 1:1 hor/vert glow. Also interlaced screens look pretty great. All around very nice!

I’m not sure whether it would be possible, but of course the nicest thing would be if you could detect the source horizontal resolution and switch between the 6 and 12 texel interpolation accordingly (and maybe halve vert glow if in 12 texel mode), that could make it work for the dynamical resolution switching in the PSX core too?

EDIT2: did a test with the NTSC shader, replacing both NTSC passes with stock, but leaving the scaling factors for both of them as configured (4 and 0.5) and tried this on the SNES core. Just to compare with regular shader, and I have to say I like the “NTSC-stripped” quite a bit as an alternative to the regular shader. The “ntsc-stripped” one is capable of giving a softer image, without becoming blurry. Quite nifty :slight_smile: .