PlainOldPants's Shader Presets

Very nice evolution in speed! I didn’t test much. I have only one thing at first that bothered me: it’s very dark! I only tested the snes preset, and had to increase the contrast to 1.0 to get something playable.

I’ve seen the Contrast at 1.0 only works using Device 1. For Devices from 2 to 9, if you increase Contrast above 0.50, the reds clamp someway. So, you ends up with a very dark picture.

Is there a way to control the red push as the first version? It may be accurate, but I can’t remember it was so red when I played in the 80’s or 90’s, or even now in my CRTs (even on composite cables).

Overall, it looks very analogical, real and alive. Congrats!

EDIT: Nevermind the red push thing. I just found the param that desaturate the reds!

EDIT2: Here’s a useful preset I’ve got running with crt-hyllian-new-mask. I had to descrease saturation and increase contrast plus tweaking the red push param to decrease clipping:

preset patchy-new-crt-hyllian-new-mask
shaders = "6"
feedback_pass = "0"
shader0 = "shaders_slang/ntsc/shaders/patchy-ntsc/p68k-fast/p68k-fast.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_slang/crt-hyllian-new-mask/shaders/support/multiLUT-linear.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-hyllian-new-mask/shaders/crt-hyllian-base.slang"
filter_linear2 = "false"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = "CRTPass"
float_framebuffer2 = "true"
srgb_framebuffer2 = "false"
scale_type_x2 = "viewport"
scale_x2 = "1.000000"
scale_type_y2 = "viewport"
scale_y2 = "1.000000"
shader3 = "shaders_slang/crt-hyllian-new-mask/shaders/support/glow/threshold.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = ""
float_framebuffer3 = "true"
srgb_framebuffer3 = "false"
shader4 = "shaders_slang/crt-hyllian-new-mask/shaders/support/glow/blur_horiz.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "true"
alias4 = ""
float_framebuffer4 = "true"
srgb_framebuffer4 = "false"
scale_type_x4 = "viewport"
scale_x4 = "0.200000"
scale_type_y4 = "viewport"
scale_y4 = "1.000000"
shader5 = "shaders_slang/crt-hyllian-new-mask/shaders/support/glow/blur-glow-mask-geom.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 = "1.000000"
scale_type_y5 = "viewport"
scale_y5 = "1.000000"
pf_console = "1.000000"
pf_contrast = "1.000000"
pf_color = "0.800000"
pf_connection = "1.000000"
pf_clipping = "2.000000"
pf_signalfringing = "1.000000"
pf_signalartifacting = "1.000000"
pf_videostd = "4.000000"
LUT_selector_param = "0.000000"
BEAM_MIN_WIDTH = "0.720000"
SCANLINES_STRENGTH = "0.860000"
MASK_STRENGTH = "1.000000"
BRIGHTBOOST = "1.000000"
GLOW_ENABLE = "0.000000"
textures = "SamplerLUT1;SamplerLUT2"
SamplerLUT1 = "shaders_slang/crt-hyllian-new-mask/shaders/support/LUT/Sony_Wega_29FA310_no_gamma-v2.png"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt-hyllian-new-mask/shaders/support/LUT/Sony_Wega_29FA310_no_gamma.png"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
2 Likes

I need to point out, the “red push” is not just some red color enhancer, but it’s the CRT’s way of approximating the NTSC standard from 1953 while compensating for using a bluer white than the standard. The default settings are calibrated against that, so that’s why you have to turn down saturation and adjust tint to make SNES games look anything like they’re supposed to, since those are often made for plain RGB. For NES, on the other hand, I would assume most games want standard NTSC settings.

Or maybe you’re from a PAL region, where (as far as I know for now) they fixed this problem a long time ago. In NTSC regions, SMPTE-170M only fixes this sometimes, but apparently CRT manufacturers never got the memo here. My Panasonic CRT from 2000 still has this “red push” over all 3 of its composite inputs, and the only bypass is YPbPr component.

I can say for sure that all settings in this are either 1. based on video standards, 2. based on my real CRTs, 3. based on real video decoder chips and their brand’s known phosphors, or 4. otherwise made as an educated guess. It’s accurate.

2 Likes

I just added in a simple hack to more easily darken over-saturated reds without needing to desaturate as much, in case that helps you. https://www.mediafire.com/file/u0c981wllep9a2q/patchy68k-1pass-2025-05-29-r2.zip/file

Also I see that you’re applying 2.4 gamma in this, but my shader already does gamma. You should change the gamma in my shader instead, unless you know what you’re doing.

I’ll do a fix soon to make it possible to skip gamma and/or NTSC color.

Edit: Here’s a version that can skip gamma and NTSC color. You can’t just set my shader’s gamma to 2.2; you have to enable “Skip all gamma correction”. To skip NTSC color, make sure you pick “Dummy” and not “SMPTE C”. https://www.mediafire.com/file/qlwkoqs77hdx1nb/patchy68k-1pass-2025-05-29-r3.zip/file I’ve realized that this shader does a poor job with double-resolution SNES games. I suggest prepending a SNES hi-res blending shader for now.

3 Likes

Thanks. I’m still learning how to integrate your shaders with others. That was a first approach. I know it has room for improvements. Thanks for the tips, I’ll test tomorrow that new version.

One thing I’d like to know about fringing: does it only manifests if you move the screen? I don’t remember very well if in real crt those artifacts change fase even if you pause the game.

2 Likes

The fringing artifacts are constantly there, but on most consoles, they are quickly flickering between two different offsets. Because of that, while holding still, artifacts visually cancel themselves out a little bit, and they become more jarring while moving.

For an example, I suggest looking up the cave in Battletoads on the NES. This particular NES game switches between 3 offsets instead of the usual 2, but it’s still a neat example of this effect. I know Game Grumps played it on original hardware at least once.

A few consoles, such as the Genesis/MegaDrive and Master System, have the phase constantly at one offset, so the artifacts don’t cancel themselves out while holding still.

Speaking of fringing, you should try adjusting the sharpness setting too. I’ve improved it over patchy-ntsc.

1 Like

2 Likes

The new params are great, thanks. One thing I noticed in the r3 version is that it offset the source someway and cut part of it horizontally.

1 Like

The version that I just uploaded fixes that and add a bunch of generic 2-phase and 1-phase options, but unfortunately, there’s a bit more performance overhead on this one. At least, I’m including a “speedup” version which slightly helps with that, but on that version, you have to manually fix the Color (Saturation) setting. The code is getting pretty messy and can use some optimization.

About that bug, it was a mistake with how the shader tries to automatically detect cropped/uncropped overscan and compensate for it. Notice how all the presets since r2 (or r3, I don’t remember) all have hardcoded absolute horizontal resolutions, unlike r1 which was a simple 2x multiplier. That way, you can set the horizontal resolution to whatever you want, and the shader will automatically either add pillarboxes or cut off the edges.

If you don’t want that behavior, you can instead change “absolute” to “source” and do 2.0x or 1.3333x, depending on which one you pick. (For the 2-phase or 3-phase ones, those multipliers are wrong. Instead, look at the “custom” settings at the bottom, and divide pixelSize by sampleSize to get the correct multiplier.)

Just be careful because the SNES can output either 256px or 512px, and making the resolution constantly 2x is going to cause 512px games to lag. The overscan compensation on top of that was just so that everything would stay in integer ratios for the shader to function right, but I guess it might also be a helpful feature for making presets, just maybe.

I’m curious, can anyone here from an NTSC region testify if they actually had this cursed brown Battletoads as a kid? (I’m pretty sure this doesn’t happen in PAL.)

I would guess many adjusted their TV’s tint setting to make it green, but if you did that, TV over the air would start looking messed up. For a lot of retro gaming, you might set your TV’s settings differently depending on whether you were playing video games or watching TV, and you wouldn’t know why it worked that way.

3 Likes

I don’t see anything wrong with the picture but I’m going on very old and unreliable memories.

What does the “uncursed” version look like for comparison?

2 Likes

Standard 1953 NTSC colorimetry: (This is closer to the CXA2025AS palette’s representation of this, unless you’re on Nestopia where they have their own CXA2025AS palettes)

Uncorrected: (This is more like FirebrandX’s palettes and Wavebeam)

I assume the second one is the intended result, since this game was developed in Europe by Rare.

Notice how even if you have the brown ground, there are strips of green in it

2 Likes

This wasn’t a thing at all.

Normal kids didn’t adjust their sets or tint for Retrogaming. We just played our games. There was no reference to tell us we weren’t seeing the right colours.

I know I used to adjust brightness to get better black levels though and I might have adjusted the colour to make things nice and vivid but I wouldn’t have known to adjust tint to get BattleToads colours corrected and definitely were not adjusting tint between gaming and regular TV watching.

Back then we used NTSC colour bars when TV signed off and eyeballing to get colours to look right.

A good reference might be a BattleToads review on Nintendo Power, E.G.M. or GamePro.

3 Likes

I thought this might be the case. This makes me glad that I’ve worked so hard over these months to figure out the decoder’s intended settings based on the broadcast standards. The default settings have the tint and color settings for broadcast, and the brightness for the game to become approximately 2.2 gamma.

The problem is with 16-bit onward, where some games become just obviously wrong, even if you have no reference for how it should look. That’s why my posts about “white trash” have those color test charts: You can’t tell if it’s calibrated/matched, but there are certain colors where you have a general idea of what they should look like and can tell if they’re messed up badly beyond a certain threshold. (I should also clarify, that post has the tint and color settings set to make the test chart results become as acceptably close as possible.)

The main question that’s unanswered for me is how you dealt with bright red at the time. Perhaps it’s not a problem for NES, but definitely elsewhere. On this old PR, I included a game that takes advantage of MegaDrive rainbow banding while also having oversaturated reds: https://github.com/libretro/slang-shaders/pull/627 Hyllian posted just a day ago that they don’t remember having red saturated that much, and the preset in that post has it down to 80%. Did you guys watch TV with 80% saturation on TVs that had an on-screen display?

About the games looking obviously wrong when your TV is set for standard NTSC, I’m wanting to share screenshots of that, but for some reason, everything suddenly just looks good for some reason. I could’ve sworn I saw some games getting screwed up badly when I tried these same color filters with Chthon’s color correction (particularly when using my reverse-engineered US 9300K color settings), but now that I’m trying again with my NTSC composite video filtering added on top of that, I’m having trouble finding games that look wrong. I thought for sure Moto Racer 2 looked absolutely horrible with standard NTSC color correction, but I’m starting to think now that the game is meant to have NTSC correction.

As I’ve said before, I grew up in the 2000s (in other words, Generation Z), so CRTs were only still around for a brief part of my life. I distinctly remember Crash Bandicoot being a deep red on those CRTs, not this lighter red that we see in emulation and the PS4 remakes, which points to the CRT not having been adjusted specifically for games. Still today, I generally play PS1 games with my CRT’s default settings (which are based on standard NTSC), or sometimes with color turned down a bit. NES and Genesis absolutely benefit from lower saturation on that CRT.

Can I just say, the PS4 Crash remakes are just… gross. All those goofy cartoonish death animations suddenly become like a realistic horror film, with some Baldi’s Basics style weirdness thrown in. I wanted to remember Crash Bandicoot, not KidPix Deluxe 4 Home Edition.

3 Likes

Even as a kid, I’ve always calibrated (by eye) my parent’s TVs to a neutral color position. And that worked for movies and games. If the set hadn’t the knob to adjust the tint, my only option was to desaturate all colors to some safe position.

4 Likes

Since we were discussing calibration, I’ve worked on this alternative multi-pass shader that more faithfully implements the NTSC video standard. The idea was to look up YouTube videos, watch them through the WindowCast core, and try my best to calibrate the tint and color dials by eye. The original video is converted into NTSC color, filtered with the standard filter characteristics before modulating, lowpassed under 4.2 MHz as if broadcast over air, demodulated with only narrowband filtering, and finally corrected back to sRGB in the same way a consumer CRT corrects NTSC color. All that’s missing right now is interlacing.

What I didn’t expect to come out of this was a substantial improvement in performance. What the heck just happened? https://www.mediafire.com/file/fdvi71hyi4bi3bs/p68k-fast-multipass-2025-06-12.zip/file SNES and mostly-standard 240p are supported well in the “multipass” subfolder, along with an incomplete NES implementation. If you’re looking for accuracy on NES, you should instead look inside the “presets” subfolder in this zip, and use the NES options in there, which have also been updated slightly.

I’m just very happy that this has unexpectedly happened. I’ll make a more serious, more complete post later.

P.S.: The way to disable gamma correction has changed. Simply change the CRT EOTF type from BT.1886 to the power law. These two things are default, but also make sure that the power is 2.2 and that the output sRGB EOTF is also a 2.2 power law. I’ve said before, but I suggest increasing sharpness a little, especially if using the 170m 240p preset which will have less artifacts.

P.P.S.: Some comments in the source code of the multipass shader are just blatantly wrong. There’s no need for the resolution to divide 2560 evenly, and there is no automatic letterboxing or cropping. Arbitrary cropped overscan compensation works completely different from that: It is now an optional feature which is handled similarly to Maister NTSC or NTSC Adaptive, with an added feature to detect if the resolution has been scaled by an arbitrary integer.

4 Likes

This is an update to the fast multi-pass shader, now featuring an adaptive comb filter. I’m definitely proud of what I have so far. The problem is that it only gives good results when using baseband (I) filtering on chroma.

This is not to be confused with the very sloppy, unfinished one that I posted here in the crt-beans thread a couple days ago. That one is something at least, but the one here is better. The main big improvement is that the lower 2.2-ish MHz of the signal are now completely untouched by the comb filter, so that neighboring scanlines aren’t blurred together nearly as much as before.

Download: https://www.mediafire.com/file/9owq702yarm8h5j/p68k-fast-multipass-2025-09-24.zip/file

Updated version, 2025-09-26: https://www.mediafire.com/file/9qv5fl2bhkxry4h/p68k-fast-multipass-2025-09-26.zip/file - Added a new setting, “Comb filter sharpness”, to sharpen edges more. The default setting of 1.0 does nothing. I recommend changing it to 1.5.

After hours of experimentation and trial-and-error, I’ve settled on a very simple implementation. Originally, I tried swapping in a notch filter at the exact right times, or only comb-filtering just enough to hide the color carrier, as well as trying to include some kind of controllable sharpness setting for the user, but ultimately, it looked far better to forcibly comb-filter every single line, even in cases where it would seem more mathematically sound to not comb-filter that line.

There is a known issue: It looks horrible if you use narrowband (Q) filtering on chroma.

Here are some screenshots to show how this comb filter looks. I don’t know if any NTSC shaders for RetroArch have such a clean adaptive comb filter yet. Even when I’ve messed with the one in cgwg-famicom-geom, I didn’t get this kind of result.

Original unfiltered image:

Comb filter:

Notch and lowpass filters:

The adaptive comb filter makes a big difference.

10 Likes

This is great! Have you successfully combined this with any CRT shaders? So far I’ve been mostly unsuccessful… I can get it to work but I’m fairly certain that it’s not looking as intended.

1 Like

The reason why it’s looking wrong is probably because those CRT shaders tend to make their own changes to the color, whether it’s on purpose or on accident. The most common purposeful change is from gamma, and the most common accidental one is from shortcutting the scanlines.

I’m short on time to try out all the major CRT shader presets, but just for now, I was able to get plain crt-royale to look right. To make it work, you just have to change both gammas to 2.2. I also like to set “Halation Weight”, “Diffusion Weight”, and “Bloom - Underestimate Levels” all to 0.

While you’re at it, you might feel like disabling the NTSC color simulation in my shader, or changing it between different kinds of color corrections. The setting for that is called “Video decoder/region”, and you can set it to 0 to turn off the color filter entirely.

Another option that isn’t being talked about enough is https://github.com/ChthonVII/chthons_color_correction , which does CRT simulation without compromising on color accuracy and overall screen brightness. It performs a color corrective LUT, scanlines, an aperture grille mask, and glow, while keeping 95% brightness and not messing up the colors. For me personally, it’s too much for my computer to handle.

Speaking of gamma, I’ve been unsure about how to handle gamma lately. When I measured my RCA ColorTrak from 1989 using my X-Rite i1Display 2 colorimeter, it came out pretty close to a 2.2 power curve, even when I had my contrast and brightness both set to the exact settings that I like. It’s too far from BT.1886, so I’ve become hesitant about using BT.1886 from now on. Another factor could be from how these 1980s CRTs have such light gray screens even when powered off, whereas later CRTs like my Panasonic from 2000 (and my Toshiba from 1995, if memory serves) tend to show a deep black instead. Perhaps the BT.1886 standard is based on later CRTs, or based directly on the phosphor luminance or the electron gun’s output, while my i1Display 2 might be assuming a slightly higher black level to account for the viewing environment and/or gray-ish screen.

I’ve seen that modern displays tend to aim for a 2.2 power law instead of the piecewise sRGB standard EOTF, and that the original sRGB proposal from 1996 says that CRTs at the time are all aiming for a 2.2 power law as well. There’s also the fact that all 3 of my CRT TVs are doing approximate corrections for 1953 NTSC primaries, and that the 1953 NTSC standard specifies a 2.2 power law. Since this is the best information I have right now, I’ve decided to stick to a 2.2 power law on everything, both for the CRT EOTF and for the sRGB OETF.

3 Likes

Thanks for your explanation- this is what I was suspecting was going on.

Looking forward to trying this!

2 Likes

At least viable crt-guest-advanced shaders include some closed, mostly neautral gamma loops within used buffer accuracy - by defaul settings. The most notable difference from using the default Retroarch linear or nearest scaler is that horizontal filtering is done in linear space and that if used, mask and scanlines tend to decrease overall image brightness by design. They can be setup for more brightness etc. Royale has some big brightness boosts in it’s default preset. I think it makes a difference.

Vanilla:

Linear upscaling:

guest-hd:

From “shortcutting the scanlines”, i think it’s correct crt behaviour since electron guns only recieved one “shot per scanline”. They weren’t done in multipass for each gun afaik, regarding vertical positions within single scanline.

Otherwise great work, keep it on!

3 Likes

Is this shader written to be HDR aware? Should we be avoiding HDR with this?

1 Like