New CRT shader from Guest + CRT Guest Advanced updates

Mask 9 on a 3050ti and a 3080 both have no mask. When I changed my laptop to run on the integrated AMD gpu mask 9 became visible.

3 Likes

This BW mask implementation was a bit weird, so i fixed it. It should now work identically with different adapters. This leaves some room for another mask and including reading about @GPDP1 's tweak i decided to include two more masks, namely magenta-green-black 3 size mask and rgb-black 4-size mask. The only downside is last two ‘4k’ mask had to have their parameter values shifted, so some presets might also change.

New Release Version (2022-01-30-r1):

Notable changes:

  • BW mask 8-9 behavior fixed, now it all works as bw mask 8.0
  • two more masks added as mask 9.0 and 10.0 (magenta-green-black and rgb-black)
  • luma coefficients with saturation adjusted
  • a scanline parameter range increased a bit
  • slotmask width parameters ‘fixing’. Now the step is 1.0, range 8.0.

Download link:

https://mega.nz/file/wgYD1CRB#t0uddoGCZYrjv8bXoyQokftdk2ggosGOI9AItwAx4ds

13 Likes

Anyone have any good reference for a slot mask CRT. I feel I’m getting close but missing something. (Pic is of my TV)

3 Likes

If you dl the latest version, then this slotmask preset might be an interesting start:

shaders = "12"
shader0 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/stock.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 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/stock.slang"
filter_linear1 = "false"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = "StockPass"
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-guest-advanced/shaders/guest/advanced/afterglow0.slang"
filter_linear2 = "false"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = "AfterglowPass"
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-guest-advanced/shaders/guest/advanced/pre-shaders-afterglow.slang"
filter_linear3 = "false"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "true"
alias3 = "PrePass"
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-guest-advanced/shaders/guest/advanced/avg-lum.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "true"
alias4 = "AvgLumPass"
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-guest-advanced/shaders/guest/advanced/linearize.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = "LinearizePass"
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-guest-advanced/shaders/guest/advanced/gaussian_horizontal.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = ""
float_framebuffer6 = "true"
srgb_framebuffer6 = "false"
scale_type_x6 = "absolute"
scale_x6 = "800"
scale_type_y6 = "source"
scale_y6 = "1.000000"
shader7 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/gaussian_vertical.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = "GlowPass"
float_framebuffer7 = "true"
srgb_framebuffer7 = "false"
scale_type_x7 = "absolute"
scale_x7 = "800"
scale_type_y7 = "absolute"
scale_y7 = "600"
shader8 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/bloom_horizontal.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 = "absolute"
scale_y8 = "600"
shader9 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/bloom_vertical.slang"
filter_linear9 = "true"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "false"
alias9 = "BloomPass"
float_framebuffer9 = "true"
srgb_framebuffer9 = "false"
scale_type_x9 = "source"
scale_x9 = "1.000000"
scale_type_y9 = "source"
scale_y9 = "1.000000"
shader10 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/crt-guest-advanced.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-guest-advanced/shaders/guest/advanced/deconvergence.slang"
filter_linear11 = "true"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
alias11 = ""
float_framebuffer11 = "false"
srgb_framebuffer11 = "false"
scale_type_x11 = "viewport"
scale_x11 = "1.000000"
scale_type_y11 = "viewport"
scale_y11 = "1.000000"
CS = "2.000000"
TNTC = "1.000000"
WP = "-75.000000"
wp_saturation = "1.150000"
SIZEHB = "3.000000"
SIGMA_HB = "0.750000"
SIZEVB = "3.000000"
SIGMA_VB = "0.750000"
bloom = "0.700000"
halation = "0.100000"
gamma_c = "1.360000"
brightboost = "1.300001"
brightboost1 = "1.250000"
gsl = "-1.000000"
scanline1 = "2.500000"
scanline2 = "14.000000"
beam_min = "1.800000"
beam_max = "0.775000"
beam_size = "0.750000"
scans = "1.650000"
scan_falloff = "0.650000"
spike = "1.500000"
h_sharp = "3.000002"
s_sharp = "1.000000"
sth = "0.300000"
csize = "0.115000"
bsize1 = "0.300000"
warpX = "0.040000"
warpY = "0.050000"
shadowMask = "10.000000"
maskstr = "1.000000"
mask_gamma = "2.399999"
slotmask = "1.000000"
slotmask1 = "1.000000"
slotwidth = "4.000000"
double_slot = "2.000000"
mclip = "0.350000"
gamma_out = "2.200000"
deconrry = "1.250000"
deconrby = "-1.250000"
decons = "1.400000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
SamplerLUT1 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/lut/trinitron-lut.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/lut/inv-trinitron-lut.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/lut/nec-lut.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"
SamplerLUT4 = "shaders_slang/crt-guest-advanced/shaders/guest/advanced/lut/ntsc-lut.png"
SamplerLUT4_linear = "true"
SamplerLUT4_wrap_mode = "clamp_to_border"
SamplerLUT4_mipmap = "false"

Screenshot:

5 Likes

Thank you for the settings. (I think name your pathing is to something custom on your computer.) Slot mask looks really nice now. Mask 12 gives me the sharpest and brightest slot mask for a BGR TV.

Now if I could only make Windows 10 HDR more reliable. It occasionally decides to turn off on it’s own and gives a nice reminder of how much clipping you get without it.

3 Likes

Btw, I assume the shader doesn’t require integer scaling, right?

1 Like

Looks great! Would love to see what it looks like at 98 - 100% mask strength!

1 Like

@guest.r @BendBombBoom I’m in love with slot masks so this post was pretty much made for me. I went ahead and whipped up my rendition and this is how it came out:

I like it but then my problems start when I use it on 480i or any interlaced content with bright screens. On dark backgrounds the shader and mask looks good such as here:

But on any bright screen the mask becomes bulky looking like here:

Is there anyway to get the mask looking how it looks on the dark image when viewing bright screens on interlaced games? I tried fiddling a few parameters here and there and the only thing that gets it looking normal again is if I disable bloom or pretty much darken the shader in other ways. If I can fix that one issue this preset can be a potential runner up to add with or replace my last post of presets that I also love.

Here’s my settings if anyone wants to try it:

shaders = "17"
shader0 = "shaders_slang/stock.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 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "shaders_slang/stock.slang"
filter_linear1 = "false"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = "StockPass"
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/advanced/afterglow0.slang"
filter_linear2 = "true"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = "AfterglowPass"
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/advanced/grade/pre-shaders-afterglow-grade.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = "PrePass0"
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/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang"
filter_linear4 = "false"
wrap_mode4 = "clamp_to_border"
frame_count_mod4 = "2"
mipmap_input4 = "false"
alias4 = ""
float_framebuffer4 = "true"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "4.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "shaders_slang/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = ""
float_framebuffer5 = "false"
srgb_framebuffer5 = "false"
scale_type_x5 = "source"
scale_x5 = "0.500000"
scale_type_y5 = "source"
scale_y5 = "1.000000"
shader6 = "shaders_slang/crt/shaders/guest/advanced/custom-fast-sharpen.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = "NtscPass"
float_framebuffer6 = "false"
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/advanced/convert-ntsc.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = ""
float_framebuffer7 = "false"
srgb_framebuffer7 = "false"
scale_type_x7 = "source"
scale_x7 = "0.500000"
scale_type_y7 = "source"
scale_y7 = "1.000000"
shader8 = "shaders_slang/stock.slang"
filter_linear8 = "true"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "true"
alias8 = "PrePass"
float_framebuffer8 = "false"
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/advanced/avg-lum-ntsc.slang"
filter_linear9 = "true"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "true"
alias9 = "AvgLumPass"
float_framebuffer9 = "false"
srgb_framebuffer9 = "false"
scale_type_x9 = "source"
scale_x9 = "1.000000"
scale_type_y9 = "source"
scale_y9 = "1.000000"
shader10 = "shaders_slang/crt/shaders/guest/advanced/linearize-ntsc.slang"
filter_linear10 = "true"
wrap_mode10 = "clamp_to_border"
mipmap_input10 = "false"
alias10 = "LinearizePass"
float_framebuffer10 = "true"
srgb_framebuffer10 = "false"
scale_type_x10 = "source"
scale_x10 = "1.000000"
scale_type_y10 = "source"
scale_y10 = "1.000000"
shader11 = "shaders_slang/crt/shaders/guest/advanced/gaussian_horizontal.slang"
filter_linear11 = "true"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
alias11 = ""
float_framebuffer11 = "true"
srgb_framebuffer11 = "false"
scale_type_x11 = "absolute"
scale_x11 = "640"
scale_type_y11 = "source"
scale_y11 = "1.000000"
shader12 = "shaders_slang/crt/shaders/guest/advanced/gaussian_vertical.slang"
filter_linear12 = "true"
wrap_mode12 = "clamp_to_border"
mipmap_input12 = "false"
alias12 = "GlowPass"
float_framebuffer12 = "true"
srgb_framebuffer12 = "false"
scale_type_x12 = "absolute"
scale_x12 = "640"
scale_type_y12 = "absolute"
scale_y12 = "480"
shader13 = "shaders_slang/crt/shaders/guest/advanced/bloom_horizontal.slang"
filter_linear13 = "true"
wrap_mode13 = "clamp_to_border"
mipmap_input13 = "false"
alias13 = ""
float_framebuffer13 = "true"
srgb_framebuffer13 = "false"
scale_type_x13 = "absolute"
scale_x13 = "640"
scale_type_y13 = "absolute"
scale_y13 = "480"
shader14 = "shaders_slang/crt/shaders/guest/advanced/bloom_vertical.slang"
filter_linear14 = "true"
wrap_mode14 = "clamp_to_border"
mipmap_input14 = "false"
alias14 = "BloomPass"
float_framebuffer14 = "true"
srgb_framebuffer14 = "false"
scale_type_x14 = "absolute"
scale_x14 = "640"
scale_type_y14 = "absolute"
scale_y14 = "480"
shader15 = "shaders_slang/crt/shaders/guest/advanced/crt-guest-advanced-ntsc.slang"
filter_linear15 = "true"
wrap_mode15 = "clamp_to_border"
mipmap_input15 = "false"
alias15 = ""
float_framebuffer15 = "false"
srgb_framebuffer15 = "false"
scale_type_x15 = "viewport"
scale_x15 = "1.000000"
scale_type_y15 = "viewport"
scale_y15 = "1.000000"
shader16 = "shaders_slang/crt/shaders/guest/advanced/deconvergence.slang"
filter_linear16 = "true"
wrap_mode16 = "clamp_to_border"
mipmap_input16 = "false"
alias16 = ""
float_framebuffer16 = "false"
srgb_framebuffer16 = "false"
scale_type_x16 = "viewport"
scale_x16 = "1.000000"
scale_type_y16 = "viewport"
scale_y16 = "1.000000"
g_signal_type = "0.000000"
wp_temperature = "8004.000000"
quality = "0.000000"
ntsc_phase = "3.000000"
GAMMA_INPUT = "2.399999"
interm = "5.000000"
bloom = "0.899999"
halation = "0.400000"
gsl = "-1.000000"
csize = "0.060000"
bsize1 = "0.300000"
warpX = "0.040000"
warpY = "0.050000"
shadowMask = "10.000000"
maskstr = "1.000000"
slotmask = "1.000000"
slotmask1 = "1.000000"
slotwidth = "4.000000"
double_slot = "2.000000"
mclip = "0.350000"
gamma_out = "2.399999"
deconrr = "0.750000"
deconrb = "-0.750000"
deconrry = "1.500000"
deconrby = "-1.500000"
decons = "-1.999998"
addnoised = "-0.300000"
noiseresd = "1.000000"
post_br = "1.200000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
SamplerLUT1 = "shaders_slang/crt/shaders/guest/advanced/lut/trinitron-lut.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt/shaders/guest/advanced/lut/inv-trinitron-lut.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "shaders_slang/crt/shaders/guest/advanced/lut/nec-lut.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"
SamplerLUT4 = "shaders_slang/crt/shaders/guest/advanced/lut/ntsc-lut.png"
SamplerLUT4_linear = "true"
SamplerLUT4_wrap_mode = "clamp_to_border"
SamplerLUT4_mipmap = "false"
7 Likes

Windows 10 HDR is confusing. Once I’ve set up retroarch to with HDR I no longer need it toggled on under the windows settings. Which is good because color sensitive images look clipped and mangled with it on.

3 Likes

You can play a bit with the “Keep Mask effect with clipping” parameter. It determines how much of the mask with bright colors is preserved after other lighting effects are added.

1 Like

New Release Version (2022-01-31-r1):

Notable changes:

  • mask 9 is now aligned with slotmask (small fix)
  • increased saturation functionality works better now
  • scanline shape parameter range adjusted, better shaping is possible now
  • slotmask shape parameter range increased - for thin slotmask effect at 4k etc.

Download link:

https://mega.nz/file/Q1BhhaCa#kku0SB6DqXA5PoSkbgZAZPsjWBUbdIbrcYhZd9hjiII

8 Likes

Thanks for the continuous improvements :slight_smile:

I’m using the shader with HDR in Windows, which according the @MajorPainTheCactus sets the color space to Rec.2020.

Does this mean that the “Display Gamut” options in your shader are no longer applicable when a user has set HDR to ON? For example when I set color space in the shader to Rec2020 I get realy desaturated results with HDR ON. Is this because the Rec2020 gets effectively applied twice in this case?

Then, what’s the recommended Display Gamut setting in your shader now with HDR=ON and using the CRT color profiles?

Also with HDR=ON should there possibly be an option to disable the clipping settings in the shaders, as brightness with HDR can extend beyond 1?

2 Likes

This is something I was curious about, @MajorPainTheCactus, if there are color values higher than 1 in the last pass, then what happens when HDR is in use?

1 Like

AFAIK, this is handled externally to the shader system. 1.0 is still the maximum, but that max value means different things through the inverse-/tonemapping algos.

3 Likes

What ‘#pragma format’ is this shader using?

If it’s the standard R8G8B8A8_UNORM then values above 1 will be clamped/saturated to 1 by the gpu.

If it’s R16G16B16A16_SFLOAT and it’s the last pass then it will skip the internal HDR shader stage.

If it’s A2B10G10R10_UNORM_PACK32 it will be clamped and the internal HDR shader stage is skipped.

Most other render target formats are not really supported by HDR but some may work (all UNORM ones I’d expect to still work)

3 Likes

I don’t know this shader at all but my guess is that HDR is not actually on for you. Desaturated image is a key telltale sign it’s not on. Do you see the white text in the menu glow white to you? If so that would say it is on and working.

I’m not sure if the following is fixable. There was a discussion about it on discord a while ago, and hunterk said it’s probably not fixable in a general way that works with everything.

The issue is that the NTSC shader makes games that constantly switch between low res and high res look very sharp and then goes back to blurry.

Prime example is “Trials of Mana” on the SNES. Whenever you talk to someone, the game renders the dialogue box in a font that has doubled horizontal resolution. The NTSC shader then makes the whole image very sharp. When you close the dialogue box, the image becomes blurry again.

Obviously this doesn’t happen on an actual CRT TV, as it doesn’t care at all about horizontal resolution. It’s completely 100% seamless. The shader however does, and as a result you get a constant switching between sharp and blurry.

Example:

http://83.212.109.87/~realnc/vid/ntsc_res_switching.mp4

1 Like

There is some good news regarding this issue. You can just use the new snes9x cores with hi-res blending disabled. The ‘optimal’ solution with shaders would do practically the same.

The video was taken with hi-res blending set to OFF :stuck_out_tongue: If I set it to “Merge”, then the problem goes away, but then the hi-res text is blurry and borderline unreadable (it’s sharp on a CRT.)

1 Like

Oh it’s definitely working, super bright it hurts my eyes :D. Also the monitor display menu tells me HDR is ON, no doubt about it.

With regard to guest’s shader I was talking about the code in the “pre-shaders-afterglow.slang” where Color Space options and CRT color profiles can be set

#pragma parameter CS "          Display Gamut: sRGB, Modern, DCI, Adobe, Rec.2020" 0.0 0.0 4.0 1.0 

#pragma parameter CP "          CRT Profile: EBU | P22 | SMPTE-C | Philips | Trin." 0.0 -1.0 5.0 1.0 

https://github.com/libretro/slang-shaders/blob/master/crt/shaders/guest/advanced/pre-shaders-afterglow.slang

I would like to know what option (0 to 4) I need to configure for “Display Gamut”, to have the CRT profiles display most accurately when I have HDR ON in RA (and it’s really ON, trust me).

As said when I set “Display Gamut” in guest-advanced shader to “4” (Rec.2020) then I get a very desaturated image. The most accurate I seem to get when I set color space to “0” (colors are normally saturated), but since this is the normal sRGB Display Gamut, I’m worrying that if I set the CRT color profiles (CP) they will clip because the COLOR SPACE in the shader is set to sRGB and not wide gamut.

1 Like