PlainOldPants's Shader Presets

The baseband chroma is still blanked like the luma signal, but lacks any sync information, so it doesn’t have any information below line rate. Even if you display a solid color, the horizontal blanking and colorburst between lines is going to make the signal periodic at line frequency.

The purpose of the high pass there is to prevent V-sync and power line energy, as well as any other possible noise, from crossing into the signal. Interference at these low frequency leads to a hum bar effect.

How are you terminating your circuits in simulation?

The way the circuits are cascaded directly into each other is fine. It does not affect the cutoff frequency. But it does change the impedance of each stage and you get resonance and a stronger roll-off. However, when you cascade a lowpass and high pass onto each other specifically, either in bandpass or bandstop configuration, the two filters don’t affect each other unless the cutoff frequencies are close (and the resistor values are far enough apart).

Cool beans. I seen your CRT shader in the CRT folders of RA. How much different is your Genesis filter from those?

The existing shader doesn’t have the NTSC composite simulation. I’m hoping to finish a sort of beta version of that next week or so.

You can probably hook up @PlainOldPants’s composite simulation with crt-beans (this is his thread, after all), but it would take some work getting the preset right.

edit: I find this https://www.reddit.com/r/crtgaming/comments/1lrv725/does_anyone_know_why_red_and_blue_usually_color/

Shouldn’t it work with RGB instead of YIQ? electron guns are RGB

anyway, Is it possible to refine and publish it? I want to try using “overdriven electron guns” effect in my presets :slight_smile:

1 Like

or maybe @PlainOldPants can publish “wearing electron guns smearing to the right” part of the patchy shader? as standalone shader that can be used in another crt shaders/presets

I was getting ready to apologize for my inactivity, until I realized my last post was only five days ago. It feels like an eternity with everything that I have going on.

I might have more to say later.

I still have no progress on this after over 3 weeks.

At first glance, it’s a simple problem: Just simulate the CRT’s colors directly, but in P3 or Rec.2020 space. While this works for simulating the signal alone, appending a CRT shader directly with it results in the phosphor mask being wrong. Because of things like glow and luminance weights, I can’t do a split prepend/append setup to defer the HDR color fix to the end. To make this make sense, I have to edit the CRT shader to output its RGB phosphors as the CRT’s phosphors’ colors. There is no other way. This will take some more effort than I first thought.

With HDR, it becomes possible to simulate CRT phosphors directly without compression. The only problematic one is the Toshiba FST Blackstripe CF2005 from 1985, whose blue phosphor is in Rec.2020 but not close to P3. Other CRTs won’t have any problems.

I don’t have any HDR monitor to test on, so I’ll have to just hope that everything looks correct on your end.

I’ve made a breakthrough in making RF noise more efficiently, to a point where it can probably be accepted into crt-advanced. Those 300 random sine waves can be replaced with just 2 manually controllable ones. Very fast. For my own shader, I’m willing to have a little bit higher performance overhead, so I loop that code section 20 times with randomization. I can post this tomorrow.

I should be able to do this tomorrow.

I don’t have a very good Genesis shader yet. I see that beans is working on simulating it more accurately. I can make a less accurate option in the meantime. Until I post that, the best option for Genesis is the one that I posted about a year ago in October.

For PSX, the “170m” 240p presets should be a good choice for now. In fact, this is probably good for most 32-bit consoles. It’s a generic preset that isn’t emulating any specific hardware, but it looks convincing to me.

I could do this and make it more efficient, but that effect was more of an eye candy, not as accurate as I would like today. I have just a bit of a hunch on how to improve it, but I don’t have 100% of the information that’s needed for accuracy with it.

5 Likes

It is also because the color carrier rate is close to the pixel clock (within 90% or 95% if I recall), resulting in a long “beat”. On NES and SNES, this is minimized by making the color carrier’s wavelength 1.5 pixels long.

As you said, capacitor aging can play a role too. I recall someone mentioning that replacing capacitors reduces the rainbow artifact. Somewhere else, I saw someone say that third party power supplies with the wrong amperage exacerbate the rainbow artifact as well, but I’m not quite inclined to believe this one.

That doesn’t explain why the rainbow banding pattern also appears on solid-color screens, with or without color. My own Genesis does this. My Genesis also has RF-like noise in the composite signal, which I only notice over video capture, and a weird issue that only occasionally happens where the scanlines start to shift horizontally slightly separately from each other. What could possibly be causing this?

I think I want to make sure this effect is simulated well enough before I finally replace the capacitors on my Genesis, assuming that the previous owner didn’t already replace them.

1 Like

I believe it’s due to coupling of the subcarrier oscillator on the RGB input (particularly blue). It reinforces the chroma subcarrier in all signals, even black and white. Since the notch filter is not perfectly aligned on the subcarrier frequency, enough gets through to the final output to be visible.

My Genesis also has RF-like noise in the composite signal, which I only notice over video capture,

You’d have to rule out the video capture device and the transmission characteristics since it isn’t apparent on the TV. If it only happens with the Genesis for this video capture device, could be an impedance mismatch requiring more amplification leading to noise. On the other hand, the TV may have noise reduction, pointing back to the Genesis. If you increase the black level, you may be able to see it.

Scanline shifting sounds like your TV having issues syncing with this type of signal.

1 Like

thanks

no problem if it not 100% accurate at start, since we dont have any shader that did that effect yet (so having something is better than nothing), and later if we got more info about it we can correct it or make another version of it

3 Likes

https://www.mediafire.com/file/qgnzkcqwsi30l4n/p68k-fast-multipass-2025-11-04.zip/file

This is a total rush job, but it adds an RF noise effect and just slightly improves the adaptive comb filter.

The noise settings will behave slightly differently depending on which .slangp you pick because they use different discrete sampling rates.

Edit: I don’t know why the comb filter is causing the noise to disappear.

Edit 2: The “Adaptive+Notch” option is unfinished and basically doesn’t work at all.

3 Likes

https://www.mediafire.com/file/5msnokq2fhxtohw/p68k-fast-multipass-2025-11-05.zip/file

This one adds HDR support and real CRT colors. The code for it is also a duct-tapey mess like with the RF noise effect.

I can’t tell for sure whether it works or not. I don’t have an HDR monitor.

If you’re using the signal shader on its own, you should set “HDR mode” to Solo. If you’re appending a CRT shader onto it, set “HDR mode” to Appendable, and append p68k-append-hdr after the CRT shader.

The Toshiba Blackstripe CF2005’s blue primary is well outside of Display P3, so colors near blue and cyan won’t look correct for this CRT. The KV-27S22 in US mode is a similar enough alternative.

Edit: This version also fixed the issue where the noise would disappear while using the comb filter.

Edit 2: Actually, the problem with the Toshiba CF2005 is worse than I thought. If you want to append with a CRT shader, you can’t use the CF2005 at all unless your display is able to display its blue primary exactly correctly. Also unfortunately, I think the Panasonic from 2000 might also be just slightly off for this same reason, but thankfully, the Panasonic blue primary is only just slightly out of bounds, not as bad as Toshiba. I recommend using the Sony US mode instead of Toshiba, and using “Video decoder/region” = 2 instead of Panasonic.

3 Likes

I’m not sure it’s working as intended, I’m getting a washed out image. Can anyone else test @Cyber?

1 Like

This might either be correct or wrong behavior.

To use it with a CRT shader, you have to put the p68k-fast-mp preset before the CRT shader, and put the p68k-append shader after the CRT shader. Then, you have to set your settings like this:

The correct result absolutely should be less saturated than normal HDR video because it’s simulating the CRT’s RGB primaries, which aren’t as deep as HDR. It’s mostly close to sRGB, but not exactly there.

If you use this with a CRT shader, and you accidentally use “Solo” instead of “Appendable”, then that’ll cause the colors to become very washed out because it’s doing the HDR correction twice. On the other hand, if you use it without a CRT shader but forget to use the “Solo” mode, you’ll get an overly deep image instead.

In the correct result, the only colors that’ll be deeper than normal sRGB (SDR) are Sony’s green, Panasonic’s red, and, if you’re lucky to have a display that supports this, Toshiba’s blue. Other than this, you’ll just have some colors that are only physically possible to display in HDR, but they won’t necessarily be that vibrant. In fact, the Sony and RCA ones have less deep reds than normal SDR video.

My main purpose of adding support for this was to avoid gamut compression headaches that degrade the image quality whenever you try to display CRT colors on sRGB displays. I could make a shader that displays standard NTSC colors that are further out in HDR space, but I don’t see much of a purpose in that because it didn’t exist at the time, except maybe in some expensive proof-of-concept displays or something like a laser projector thingy.

1 Like

Did you use it with a Scanline/Mask Shader?

What am I supposed to be testing?

I’m getting Failed to Apply everytime I try to load or apprnd one of these:

p68k-fast-mp-170m-240p-combfilter-noise.slangp

p68k-fast-mp-170m-240p.slangp

Some of the passes are loading though.

On D3D11 I was getting a D3D Compilation error along with some info about some loop.

On Vulkan, I haven’t seen any error in the log but it still Failed to load. I extracted the folder to the Shaders_Slang/p68k-fast-multipass-2025-11-05 Folder.

I did load:

ntsc-colors-crt.slangp

…switch it to Append Mode.

Then load this:

p68k-append-hdr.slangp

Without Scanlines/Mask, These settings looked good to me.

shaders = "3"
feedback_pass = "0"
shader0 = "shaders_slang/p68k-fast-multipass-2025-11-05/p68k-fast-mp-pre-color-only.slang"
alias0 = ""
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
filter_linear0 = "false"
frame_count_mod0 = "2"
float_framebuffer0 = "true"
srgb_framebuffer0 = "false"
scale_type_x0 = "source"
scale_x0 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "shaders_slang/p68k-fast-multipass-2025-11-05/p68k-fast-mp-post-color-only.slang"
alias1 = ""
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
filter_linear1 = "false"
frame_count_mod1 = "2"
float_framebuffer1 = "true"
srgb_framebuffer1 = "false"
scale_type_x1 = "source"
scale_x1 = "1.000000"
scale_type_y1 = "source"
scale_y1 = "1.000000"
shader2 = "shaders_slang/p68k-fast-multipass-2025-11-05/p68k-fast-mp-append-hdr.slang"
alias2 = ""
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
filter_linear2 = "false"
frame_count_mod2 = "2"
float_framebuffer2 = "true"
srgb_framebuffer2 = "false"
scale_type_x2 = "source"
scale_x2 = "1.000000"
scale_type_y2 = "source"
scale_y2 = "1.000000"
pf_srgb_eotf = "2.000000"
pf_videostd = "19.000000"
pf_hdr_enable = "2.000000"
pf_hdr_gamut = "2.000000"
pf_hdr_crt = "2.000000"

2 Likes

I thought this was just a glitch with ShaderGlass, not with other RetroArch versions and/or GPU drivers too. The fix is to hard-code all the for-loops to end at some maximum number of iterations so that the compiler can unroll them cleanly. I’ve gone ahead and done that now. I’ve also added in another fix to make the comb filter work in ShaderGlass, since it looks like ShaderGlass requires all passes to reference each other in sequential order without history or feedback.

I had also forgotten to linearize when correcting the colors for HDR. That’s also fixed in this version.

Let me know if this version works for you now. The previous one loads fine for me on RetroArch on Ubuntu, but whenever I feel like trying stuff with ShaderGlass on Windows, I have to do random fixes like this to make it compile. Hopefully these same fixes work on your end.

https://www.mediafire.com/file/l43j0u58sg506cn/p68k-fast-multipass-2025-11-05-fix1.zip/file

2 Likes

Here’s my test version with guest-advanced. It’s not looking right, what am I doing wrong?

shaders = "19"
feedback_pass = "0"
shader0 = "p68k-fast-multipass-2025-11-05-fix1/p68k-fast-mp-pre-color-interlace-170m.slang"
alias0 = ""
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
filter_linear0 = "false"
frame_count_mod0 = "4"
float_framebuffer0 = "true"
srgb_framebuffer0 = "false"
scale_type_x0 = "source"
scale_x0 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "p68k-fast-multipass-2025-11-05-fix1/p68k-fast-mp-encode-170m.slang"
alias1 = ""
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
filter_linear1 = "false"
frame_count_mod1 = "4"
float_framebuffer1 = "true"
srgb_framebuffer1 = "false"
scale_type_x1 = "absolute"
scale_x1 = "640"
scale_type_y1 = "source"
scale_y1 = "1.000000"
shader2 = "p68k-fast-multipass-2025-11-05-fix1/p68k-fast-mp-decode.slang"
alias2 = ""
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
filter_linear2 = "false"
frame_count_mod2 = "4"
float_framebuffer2 = "true"
srgb_framebuffer2 = "false"
scale_type_x2 = "source"
scale_x2 = "1.000000"
scale_type_y2 = "source"
scale_y2 = "1.000000"
shader3 = "p68k-fast-multipass-2025-11-05-fix1/p68k-fast-mp-comb.slang"
alias3 = ""
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
filter_linear3 = "false"
frame_count_mod3 = "4"
float_framebuffer3 = "true"
srgb_framebuffer3 = "false"
scale_type_x3 = "source"
scale_x3 = "1.000000"
scale_type_y3 = "source"
scale_y3 = "1.000000"
shader4 = "p68k-fast-multipass-2025-11-05-fix1/p68k-fast-mp-post-color-deinterlace.slang"
alias4 = ""
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "false"
filter_linear4 = "false"
frame_count_mod4 = "4"
float_framebuffer4 = "true"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "1.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "p68k-fast-multipass-2025-11-05-fix1/p68k-fast-mp-deinterlace-merge.slang"
alias5 = ""
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
filter_linear5 = "false"
frame_count_mod5 = "4"
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/advanced/stock.slang"
alias6 = ""
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
filter_linear6 = "false"
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/stock.slang"
alias7 = "StockPass"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
filter_linear7 = "false"
float_framebuffer7 = "false"
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/advanced/afterglow0.slang"
alias8 = "AfterglowPass"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "false"
filter_linear8 = "false"
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/pre-shaders-afterglow.slang"
alias9 = "PrePass"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "true"
filter_linear9 = "false"
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/avg-lum.slang"
alias10 = "AvgLumPass"
wrap_mode10 = "clamp_to_border"
mipmap_input10 = "true"
filter_linear10 = "true"
float_framebuffer10 = "false"
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/linearize.slang"
alias11 = "LinearizePass"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
filter_linear11 = "true"
float_framebuffer11 = "true"
srgb_framebuffer11 = "false"
scale_type_x11 = "source"
scale_x11 = "1.000000"
scale_type_y11 = "source"
scale_y11 = "1.000000"
shader12 = "shaders_slang/crt/shaders/guest/advanced/gaussian_horizontal.slang"
alias12 = ""
wrap_mode12 = "clamp_to_border"
mipmap_input12 = "false"
filter_linear12 = "true"
float_framebuffer12 = "true"
srgb_framebuffer12 = "false"
scale_type_x12 = "absolute"
scale_x12 = "800"
scale_type_y12 = "source"
scale_y12 = "1.000000"
shader13 = "shaders_slang/crt/shaders/guest/advanced/gaussian_vertical.slang"
alias13 = "GlowPass"
wrap_mode13 = "clamp_to_border"
mipmap_input13 = "false"
filter_linear13 = "true"
float_framebuffer13 = "true"
srgb_framebuffer13 = "false"
scale_type_x13 = "absolute"
scale_x13 = "800"
scale_type_y13 = "absolute"
scale_y13 = "600"
shader14 = "shaders_slang/crt/shaders/guest/advanced/bloom_horizontal.slang"
alias14 = ""
wrap_mode14 = "clamp_to_border"
mipmap_input14 = "false"
filter_linear14 = "true"
float_framebuffer14 = "true"
srgb_framebuffer14 = "false"
scale_type_x14 = "absolute"
scale_x14 = "800"
scale_type_y14 = "absolute"
scale_y14 = "600"
shader15 = "shaders_slang/crt/shaders/guest/advanced/bloom_vertical.slang"
alias15 = "BloomPass"
wrap_mode15 = "clamp_to_border"
mipmap_input15 = "false"
filter_linear15 = "true"
float_framebuffer15 = "true"
srgb_framebuffer15 = "false"
scale_type_x15 = "source"
scale_x15 = "1.000000"
scale_type_y15 = "source"
scale_y15 = "1.000000"
shader16 = "shaders_slang/crt/shaders/guest/advanced/crt-guest-advanced.slang"
alias16 = ""
wrap_mode16 = "clamp_to_border"
mipmap_input16 = "false"
filter_linear16 = "true"
float_framebuffer16 = "true"
srgb_framebuffer16 = "false"
scale_type_x16 = "viewport"
scale_x16 = "1.000000"
scale_type_y16 = "viewport"
scale_y16 = "1.000000"
shader17 = "shaders_slang/crt/shaders/guest/advanced/deconvergence.slang"
alias17 = ""
wrap_mode17 = "clamp_to_border"
mipmap_input17 = "false"
filter_linear17 = "true"
float_framebuffer17 = "false"
srgb_framebuffer17 = "false"
scale_type_x17 = "viewport"
scale_x17 = "1.000000"
scale_type_y17 = "viewport"
scale_y17 = "1.000000"
shader18 = "p68k-fast-multipass-2025-11-05-fix1/p68k-fast-mp-append-hdr.slang"
alias18 = ""
wrap_mode18 = "clamp_to_border"
mipmap_input18 = "false"
filter_linear18 = "false"
frame_count_mod18 = "2"
float_framebuffer18 = "true"
srgb_framebuffer18 = "false"
scale_type_x18 = "source"
scale_x18 = "1.000000"
scale_type_y18 = "source"
scale_y18 = "1.000000"
pf_hdr_enable = "2.000000"
bogus_afterglow = "1.000000"
wp_saturation = "1.200000"
gamma_out = "2.200000"
m_glow = "2.000000"
glow = "0.050000"
brightboost = "1.000000"
brightboost1 = "1.000000"
gsl = "1.000000"
scanline1 = "5.000000"
scanline2 = "40.000000"
beam_min = "1.150000"
beam_max = "1.150000"
beam_size = "0.000000"
scans = "1.000000"
h_sharp = "5.999999"
s_sharp = "1.000000"
shadowMask = "12.000000"
maskstr = "0.700000"
mcut = "1.000000"
post_br = "1.500000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
SamplerLUT1 = "shaders_slang/crt/shaders/guest/advanced/lut/trinitron-lut.png"
SamplerLUT1_mipmap = "false"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT2 = "shaders_slang/crt/shaders/guest/advanced/lut/inv-trinitron-lut.png"
SamplerLUT2_mipmap = "false"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT3 = "shaders_slang/crt/shaders/guest/advanced/lut/nec-lut.png"
SamplerLUT3_mipmap = "false"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT4 = "shaders_slang/crt/shaders/guest/advanced/lut/ntsc-lut.png"
SamplerLUT4_mipmap = "false"
SamplerLUT4_wrap_mode = "clamp_to_border"

Does this refer to something more specific than a CRT shader with scanlines and a mask?

2 Likes

No, I meant any normal CRT-Shader that doesn’t include NTSC signal emulation of course.

Why don’t you try it without the CRT-Shader and Comb Filter and see how it looks first. After that you can try adding the CRT-Shader (aka Scanlines/Mask shader) in between the NTSC Colors Shader and HDR (Decoder?) Shader.

1 Like

Even using that exact same preset, I can’t get it to look that bad on my laptop. Maybe it’s another one of those OS-dependent/driver-dependent problems, which are harder to discover and fix.

Or maybe you have some other setting on your PC or monitor that is correcting sRGB color into Display P3 color. I think that’s more likely to be the cause of the problem.

2 Likes

I’m leaning toward it being a driver/OS thing, I’ll see if I can isolate the problem later. I’m using an Nvidia 3090 Ti with the latest driver, Windows 11

I tried disabling “automatic color management” in Windows, but that didn’t solve it.

Try using it without the CRT shader, and tell me what happens. I need to have some clue as to what part of my code is OS/driver-dependent.

1 Like