PlainOldPants's Shader Presets

Thank you a lot. I saw a couple from The No Swear Gamer and didn’t know whether it was an original SMS or a Genesis, but those other 2 are probably original SMS consoles. They look like they’re the same as the Genesis’ video signal, except, comparing these two videos https://www.youtube.com/watch?v=creDKP43oCI https://www.youtube.com/watch?v=qLWZoEgjNnU the SMS and Genesis have different colors.

@Hyllian I’m questioning your memory a little bit. All of these videos have the Genesis “1-phase” pattern.

I did a quick search and found a PC-Engine video: https://www.youtube.com/watch?v=-sCRJ8ZhoUk It is a “2-phase” pattern.

For PS1, I’m not even going to look up videos. I’m just going to capture my real hardware.

I won’t start working on this stuff just yet. I have other things I need to dedicate more time to at the moment. All I’ll do for now is that tiny 3-phase fix and Grade’s SMS non-linear blue lift. After those things, one more thing in addition to trying to match these consoles is copying cgwg-famicom-geom’s adaptive comb filter.

(Edit: I’m already forgetting the color gamut conversions that I discussed with Chthon last month. The plan is to bake the entire color grading process into an LUT, including the demodulator settings, the gamma, and the phosphor gamut. It’ll be a big jump in quality, but… at that point, someone may as well get a CRT-compatible (!) colorimeter and just sample an entire LUT that way.)

2 Likes

Dunno if useful, but have you seen the composite filter/output comparisons over at the CRTdatabase with the Genesis related tables? For some reason, the original article where the Retrotink’s Notch filter is featured doesn’t seem to be there anymore, (here archived) but there are now explicit comb filter search values there, the filter pictures/tables are still available for Panasonic-ct-20sl15 and Panasonic-ct-20sl14j Edit: They info has now also been taken out from the Panasonic CRT articles.

1 Like

I can’t say my memory is correct. In fact, I doubt I can recover all these details from 30 years ago. :stuck_out_tongue: You have a point.

BTW, dunno if it’s helpful, some schematics you can find here. There are some for sega systems and others for nes and atari clones made in Brazil.

1 Like

You sure the answer is not 42?

Hey there, hello boss. Sorry, haven’t made the time to check last version and Noise changes.

I found this new VHS record: Do you know if this VHS 1993 looking in Sonic 2 is actually achievable with current preset version? @sonkun @guest.r

As its stated in description, this is recorded from 1993 with Model 1 Genesis, RF cable, Rainbows and intense blurry looking. This is the perfect way to portray games from that decade. Would love to see it in action around here.

Audio is Mono and output rate seem like 16000 hz to me, in retroarch options.

Jump to 11:18 for rainbows and dithering

1 Like

Seems doable by turning up the saturation and blurring the image up:

1 Like

Nice!

And this bug with Super sonic next to the signpost. I remember even this happening in a kids TV show where kids played through the phone buttons number. It really could break all game experience if this ever happened!

12:32

1 Like

Do remember that VHS can also have wow & flutter, tracking, dirty head and dropout artifacts due to physical tape or magnetic degradation.

You might need to add the VHS shader to simulate some of those “effects”.

2 Likes

Edit: I just realized that this update might have accidentally altered the Genesis artifacts, but I’m not sure. I might do another update soon to fix this, but I don’t have time at this exact moment.

This update has limited compatibility with presets made for the previous version. The shader passes are changed, so you will have to re-append all your presets. The only settings you need to update are “Tint”, “Color”, and “R-Y/B-Y lowpass type”.

This is a minor update doing several small fixes and improvments. The main things are slightly more accurate 3-phase, better red push default settings, the 8500K whitepoint, the SMS blue lift from Grade, and better performance. I recommend appending (in order) afterglow-update0 and crt-royale-fast. Consider prepending allowed-settings, to bring commonly used settings to the top of the list. https://www.mediafire.com/file/wgg42omjr7da398/patchy-8500k-2024-10-16.zip/file

I am going to put together a document going over this shader’s very long list of settings. Even though there are so many settings, only a few are really used. I’ve been short on time to work on this project lately, but I think this in particular can get done soon enough.

For those planning to make presets with this, I have a few suggestions. First, the settings to look similar-ish to Grade (but slightly more accurate) are Trinitron P22, 8500K, enable chromatic adaptation, r-y/g-y/b-y preset 0, and brightness 0.1. Second, if you use Grade’s BT.1886, you have to disable Auto Contrast and use the “color ramps” test pattern to set your contrast manually. Third, this update changed the default “R-Y/B-Y Lowpass Type” from 2 to 1 to reduce shadows and smearing, but you might consider changing it back to 2 for a more RF-like look. Fourth, for SMS, I recommend picking either one of the two patchy-genesis options, disabling “Genesis Jailbars on Solid Backgrounds”, and changing “Genesis Plus GX color fix” to SMS (2). A couple generic 2phase presets were added for consoles like PC-Engine and PlaySattion 1.

Detailed changelog and future goals

Full list of changes:

  • Added a generic “2-phase” preset based on Maister NTSC / NTSC Adaptive. It is not based on any particular console, but it’s currently recommended for PlayStation 1. The “hi-res” version is meant for consoles with a horizontal resolution of about 420 or higher.
  • Updated default Saturation (Color) and Hue Rotation (Tint) settings for US jungle chips. They look better now, but many people might think they’re all oversaturated.
  • Sped up the noise generation, but it’s still a laggy piece of shit.
  • Added more white point options, including 8500K for those who are used to Dogway’s Grading Shader.
  • Can do chromatic adaptation with Trinitron P22 with white point 8500K. Make sure you use the specific 8500K option, not a custom CCT. Still, I prefer having chromatic adaptation off, because chromatic adaptation changes the appearance so much.
  • Fixed the leaky integrator R-Y B-Y lowpass leaving behind a jailbar pattern in the signal.
  • The leaky integrator on R-Y/B-Y is no longer the default. If you want the distinct chroma smear to the right, change the R-Y/B-Y lowpass filter type to 2, which is the leaky integrator.
  • Changed default R-Y B-Y lowpass to a windowed sinc, and updated its default settings.
  • Widened the decoder preset lowpasses to filter out the chroma signal more completely. Before, it was only just wide enough to make the chroma signal unnoticeable on many CRT shaders. Now, it’s much harder to notice even when using the signal shader alone.
  • Halved the signal resolution for Genesis presets, giving better performance. The updates to the R-Y/B-Y lowpass were done because of this, because the Genesis would look wrong if you lowpassed in the old way.
  • Added internal 3-phase and 2-phase settings taken from Maister NTSC / NTSC Adaptive. This fixes the SNES being slightly off. (I remember hearing somewhere that N64 has a similar 3-phase signal, but I don’t trust this.)
  • Copied Grade’s Sega Master System blue lift. I haven’t properly put together an SMS preset, but for now, I recommend loading either the genesis-plus-gx or genesis-blastem preset (both work for this), turning off “Genesis Jailbars on Solid Backgrounds”, and changing the “Genesis Plus GX Color Fix” to 2 (SMS).
  • Updated patchy-color a little bit to have the SMS blue lift and the updated saturation and tint settings. Patchy-color is a side thing that I’ve been paying little attention to, and that’s made very obvious by its messy code and missing features.
  • Included bandstop and “anti-highpass” filters that both suck because they attenuate high frequencies so much. “Anti-highpass” especially is bad because it can cause some frequencies to get negated.

Goals for my next update are:

  • Clean up the freaking code. Especially patchy-color. Compatibility with older presets might have to be broken severely.
  • Better handling of varying horizontal resolutions.
  • More accurate Genesis jailbars, by screenshotting a video capture, averaging all the lines, and using as a lookup table.
  • More accurate match of Genesis color carrier settings. Currently, it’s just a little bit off.
  • Make presets for PS1, SMS, and PC-Engine.
  • Add an adaptive comb filter, probably heavily based on cgwg-famicom-geom’s.
  • Add experimental PAL support.
  • Add experimental support for LUTs that include the entire demodulate+eotf+phosphor+oetf process baked together, thanks to Chthon’s program called gamutthingy. Some fixes will have to be made to this later.
  • Add R-Y/B-Y clamping levels, preferrably from same chips.
  • Search up a bunch of demodulator chips on CRT-database and elsewhere, and pool together the results.

Other future goals:

  • If not already done, update gamutthingy to allow RGB resultant values over 255, and automatically darken the entire LUT by a constant factor to make the whole gamut fit from 0 to 255.
  • Bake the entire color grading process into an LUT, resulting in better performance and better colors. Improving my video signal is a higher priority for now.
  • At that point, may as well get a CRT-compatible (!) colorimeter and make an LUT based on a real CRT, and/or try doing it by eye.
  • More accurate EOTF, and other color accuracy improvements.
  • Get more CRTs.
  • Add support for hardcoded filters, like from Maister NTSC.
  • See if it’s possible to create filters based directly on the inductor/capacitor circuits in the original Genesis. Up to this point, everything’s been done by eye.
  • Better adaptive comb filtering.
  • More accurate noise.

I just saw these posts about VHS. From some brief searching online, VHS compresses the video an awful lot. The tape itself contains a different kind of composite video signal which uses a much lower chroma subcarrier frequency, and a VCR has to convert standard composite video both to and from this VHS composite signal. This would mean, to update this shader to support VHS, I would make it modulate and demodulate the signal three times, using at least 4 additional shader passes.

3 Likes

I’ve spent these past 2 months focusing only on my university coursework. Even over the fall break, I was just spending most of the day working on course projects or studying. I just feel so relieved now, now that my most stressful, overwhelming university semester ever is finally over. No more of that servers-within-servers-within-servers nonsense.

Just this past week, I was able to get a cheap used colorimeter on eBay. My latest update here is a hasty attempt to use this colorimeter to approximate my 1989 RCA ColorTrak’s colors in a shader, with all of the imperfections that a consumer CRT has. The NES colors turned out nice, but the Genesis didn’t turn out quite right. This colorimeter likely has drifted over time.

This update has many other random changes too, which I made during what little free time I had.

This is also my last planned update to patchy-ntsc. I’m planning to ditch patchy-ntsc entirely and make another shader from scratch, which I hope will have much more bearable performance, cleaner code, better accuracy, and better familiarity and ease-of-use for other LibRetro shader users. This shader still can do much, much better with accuracy, since it currently is just doing rough guesses at the signal’s filtering/effects using windowed sinc functions, while it could benefit well from hardcoded LUTs or arrays instead, as seen in Maister NTSC and NTSC Adaptive. Plus, there are several improvements that just can’t be added into patchy-ntsc, such as Chthon’s full gamutthingy LUTs. By this update, patchy-ntsc has just gotten too patchy, with such high performance requirements and such messy, unmaintainable, unoptimized code.

In this release, I’ve decided not to include any CRT presets. Anytime I would append a “sanitized” CRT preset, the result would change too much. I recommend appending an interpolation shader, such as bicubic or b-spline.

Download at https://www.mediafire.com/file/idunzdx47lur8xb/colortrak_2024_12_16.zip/file and place all these folders directly inside your “shaders” folder, which contains another folder called “shaders_slang”.

I’ve also sampled an NES palette from this 1989 RCA ColorTrak, albeit with noise throwing off the results slightly. In comparison to the palette that I eyeballed from my 1995 Toshiba CE20D10 (which I no longer have), this is drastically different. Were all late-80s/early-90s CRTs like this? Since I couldn’t sample the D-column of the palette in the 240p test suite, I reused the grays from the 00 column, whereas in the shader preset pack above, I used simple bilinear interpolation to approximate guess the gray axis and de-emphasized colors. https://www.mediafire.com/file/98t1kvwl2x30s2c/colorimeter_palette.pal/file Note: This palette already is based on the final output colors. If you use it with a CRT shader, make sure you set both input gamma and output gamma to 2.2, and make sure any gamut-affecting settings just pass the color through. For instance, in crt-hyllian, set LUT to off.

Edit (2024-12-20): I have now done this same procedure on my 2000 Panasonic CT-36D30B. I will post the palettes and data in a bit. It allows you to set the white point to “warm”, “normal”, or “cool”, but funny enough, “warm” is actually the standard white (D65), whereas “normal” is 9300K, and “cool” is ~14000-15000K. All 3 had the same demodulation settings. Seeing as my 1989 RCA was about 9300K too, I think this is a pattern.

My methodology for reversing this CRT’s NTSC gamut correction

Spoiler (click to show/hide)

To try to replicate the colors for consoles other than NES, I measured three things. I am making several assumptions about how this CRT works which might throw off the result.

First, I sampled my CRT’s phosphors. I used the bottom row of the NES palette with high saturation and low brightness to isolate each individual phosphor. The results averaged to the following:

Red: x: 0.598576833333333, y: 0.35618925 Green: x: 0.303930178571429, y: 0.593650071428571 Blue: x: 0.153156090909091, y: 0.0663752121212122

(Edit: I’ve since used this same colorimeter to measure the phosphors and white points on my other CRT (which let me pick “warm”, “normal”, and “cool”), and the results were close to standard. The colorimeter is probably right. Regardless, I’m going to re-measure this 1989 CRT, just to be safe.)

Notice how this gamut mostly fits nicely into sRGB, with little need for gamut compression. This is great for my shader project, but I’m still doubting this colorimeter’s accuracy.

With this information, I’m able to represent any color from the CRT as a linear combination of these 3 phosphors, in linear space.

Second, I sampled a grayscale. I connected a cheap HDMI-to-composite converter to my laptop, and used HCFR to be able to easily sample the full grayscale from 0 to 255, but with only one sample per gray level, to save time.

Both the HCFR software and the HDMI-to-composite converter may have been altering the colors. I found that the input colors from 0-15 and 236-255 were getting clamped, which meant that something was interpreting my RGB as being in limited space from 16 to 235. With further trial-and-error, I found out that the grayscale approximated a gamma of about 2.1, which is about 2.4*2.2/2.5, meaning that something was correcting from sRGB gamma to NTSC gamma, while my CRT was outputting directly with approximately 2.4 gamma with no further corrections. The grayscale from the CRT did not have a steady white point (as expected from a consumer unit), so in Excel, I converted each xyY point into XYZ, and then into a linear combination of the 3 phosphors.

Once I had the full grayscale, I was able to take any color from the CRT, represent it as the 3 phosphors in linear-light space, and invert the CRT’s EOTF (a.k.a. gamma) to get the internal RGB values.

Graph of the grayscale: https://www.desmos.com/calculator/uoiwfketdn (Edit: This isn’t the right graph. If you want to see the grayscale, represented as linear Y luminance values for each phosphor, you can find it in my shader code, in patchy-ntsc-eotf.slang.)

Third, I sampled a full chroma cycle (500 colors) in YIQ space, keeping Y and sqrt(I^2 + Q^2) constant. I did this before realizing that the 16-235 clamp and the 2.2/2.5 gamma correction were happening, but when I graphed the data without correcting for those things, the result still formed very clean sine waves. The graph showed very clearly that this CRT is doing an ordinary R-Y/B-Y demodulation to correct the colors, as I saw in a number of chips’ documentation. I found that R-Y, G-Y, and B-Y were at these offsets and gains:

R-Y: offset 54.5168223778 degrees, gain 47.170890387 G-Y: offset 214.599290038 degrees, gain 15.5833234335 B-Y: offset 317.451910996 degrees, gain 52.5768429019 (I = 0 degrees, Q = 90 degrees, chroma radius: 0.1 (0 to 1) or 25.5 (0 to 255)) Gains are in RGB space. I had forgotten to take into account the 16-235 clamp and the 2.2/2.5 gamma correction, so the numbers are a bit off. Simply multiplying the gains by (235.0 - 16.0) / 255.0 makes the result more accurate.

Graph of R, G, and B in the full chroma cycle: https://www.desmos.com/calculator/kkazpj4z1a

The result had R-Y about 97 degrees off from B-Y, at about 0.9 relative amplitude, while G-Y was about 237 degrees off from B-Y at about 0.3 relative amplitude. This is similar to Sony’s JP axes in the CXA2025AS and CXA1644AS. This makes sense with the CRT’s white (mostly in the brighter half of the grayscale) being steadily near (x=0.28, y=0.295), which is close to 9300K, the reference white used in the Japanese NTSC standard at the time.

6 Likes

I really like the idea and am interested in a fast version. It does some unique things with the signal.

1 Like

Yay, Pants is back. Thank goodness.

1 Like

This zip file has 3 NES palettes based on my 2000 Panasonic CT-36D30B. The CRT allowed you to change the color temperature to cool, normal, or warm. Normal is about 9800K (0.2801, 0.2922), warm is about 7100K (0.3057, 0.3145), and cool is about 14400K (0.26066, 0.27436). The color temperature only changed the white balance without changing the demodulation settings. Like before with the RCA ColorTrak palette, these palettes are not finished because I did not sample the D-column, which I should’ve done using the 240p Test Suite’s IRE test. Instead, the D-column reuses values from the 0-column. https://www.mediafire.com/file/iaojvggifrutfsy/panasonic-ct-36d30b-colorimeter-palettes.zip/file

Unlike other NES palettes, these palettes already are gamma-fixed because they are sampled directly from my CRT using a colorimeter. If you use this in a CRT shader, make sure your “input gamma” and “output gamma” are both set to 2.4. If you only see one option, called “CRT gamma” (or something like that), set it to 2.2.

I’m pretty happy with the result. I think it’s a good improvement over the popular Sony CXA2025AS consumer palette and FCEUmm default palette, in that the 3-column is more like a bluish-purple instead of pink, the 2-column is more of a dark blue, the 6-column is a more pure red, and you get green 08, brown 18, and orange 28 at the same time. It is a pretty good American consumer palette, and drastically different from my 1989 RCA ColorTrak Remote E13169GM which is similar to the CXA2025AS’s JP axis setting.

For no reason, I’m also including two different attempts I made months ago to eyeball the palette from my 1995 Toshiba CE20D10, which I do not have anymore. For both, I put my laptop near the TV, and adjusted the color on my laptop until it looked similar to the CRT’s color from the 240p test suite. My first attempt was this https://www.mediafire.com/file/2ws9taf2uxp5j5b/manual_eyeballed.pal/file using some random color-picker website with a solid-color screen. The second here https://www.mediafire.com/file/xxa8ykx42o9ba0i/crtshader_manual_eyeballed.pal/file was similar, but it is less accurate, as I was doing it with a CRT shader (probably my “crt-advanced-personal-preset” from my previous downloads, but I don’t remember…) with the SNES 240p test suite to pick an RGB color with only 15-bit color (5 bits per color channel). I recommend the first one in favor of the second, but ugh, eyeballed color palettes are so ugly and bad, and the pinkish white point is so severely exaggerated. (If you average all 12 colors in the 3-row of the palette (31 through 3c) you get much closer to white C, but this eyeballed palette overexaggerates the pinkish white point.) I instead recommend using one of my 3 Panasonic palettes or my RCA ColorTrak palette. However, this Toshiba CE20D10 palette is special in that it has strong browns in the 8-column and cyans in the b-column at the same time. I know for sure this CRT has the TA8867AN, but in my time messing around with NES palette generation, I’ve never made the TA8867AN’s emulated output in my shaders look quite like this, probably because how how badly worn-out and overused the TV was.

Speaking of which, in a previous post here, I stated that my Toshiba CRT didn’t have “very orange yellows”, but I now remember that I had been changing the CRT’s “Tint” (chroma offset) setting to make yellow look normal. I’ve since learned that “Tint” should generally be centered on CRTs. Looking at my RCA and Panasonic TVs on the default Tint setting, the RCA’s default has a slightly orange yellow, a more pink magenta, and a normal cyan, while the Panasonic has slightly redder magenta and slightly oranger yellow; this is reflected in my latest and final patchy-ntsc release which sampled the R-Y/G-Y/B-Y offsets/gains using a colorimeter, as well as the directly-sampled NES palettes I’m posting which have similar results. Especially, the Toshiba CE20D10 palette messes up NES Battletoads badly, with brown ground in the first level, and a half-cyan title screen, both of which I remember happening with Tint set to its default–In other words, this TV was a total wreck that needed to be thrown away. I can assure that my RCA and Panasonic CRTs both are working well.

More in-depth info about this CRT (spoiler)

In terms of YIQ: (I = 0 degrees, Q = 90 degrees) (Not sure how precise) (Edit, later same day: Fix G-Y and B-Y gains being in the wrong units, while R-Y’s gain was in the correct units.)

R-Y: Offset 67.565130965, gain 1.799208485

G-Y: Offset 199.196534978, gain 0.813930348

B-Y: Offset 325.25680155, gain 2.067112454

Phosphors are basically the same as the standard. This makes it even more frustrating that I can’t get close enough to my RCA ColorTrak’s color in non-NES games.

Red: (0.641967333, 0.339582)

Green: (0.294701667, 0.607772333)

Blue: (0.148118, 0.066948)

The measures of the chroma cycle weren’t that precise. This time, to save hours of my time, and avoid burning in a rectangle in the middle of my irreplaceable back-breaking 36-inch comb-filtering beast CRT from 2000, I reduced the amount of chroma cycle samples from 500 to 100, and reduced the amount of gamma ramp samples from 256 to 64. (Edit: I don’t know why the “normal” and “warm” graphs on Desmos are the same, but I have 3 different results listed in my Excel spreadsheet. I averaged the three different results together to create the results above.)

Chroma cycle (Cool color temp) https://www.desmos.com/calculator/q6zg7owar8

Chroma cycle (Normal color temp) https://www.desmos.com/calculator/imifj3qgjx

Chroma cycle (Warm color temp) https://www.desmos.com/calculator/hi3ddiwqav

Normal gray ramps (LONG) (Used in conjunction with samples phosphors to invert gamma and get internal RGB values for the output of the full chroma cycle)

Cool
0.325825 0.325825 0.325825 0.325825 0.325825 0 0.081882 0.229763 0.221645 0.234217 0.227298 0.223461 0.235704 0.229452 0.235903 0.238511 0.240604 0.241047 0.2423 0.245222 0.23961 0.244896 0.246927 0.249793 0.251491 0.246709 0.248954 0.249537 0.254679 0.252887 0.25317 0.252904 0.253545 0.253574 0.255329 0.254776 0.253157 0.253145 0.255279 0.255362 0.255871 0.256331 0.255564 0.255527 0.255898 0.257933 0.256396 0.25762 0.257174 0.258261 0.258305 0.257574 0.258897 0.258473 0.258845 0.260232 0.258698 0.259715 0.259511 0.259897 0.260608 0.260585 0.26042 0.260026 0.261301
0.190482 0.190482 0.190482 0.190482 0.190482 0.969963 0.27783 0.312861 0.280423 0.279696 0.261919 0.235394 0.267399 0.247716 0.255055 0.262209 0.256126 0.263994 0.257417 0.266651 0.258777 0.258827 0.263639 0.2641 0.266198 0.25452 0.265934 0.263018 0.269643 0.264345 0.265418 0.266592 0.259001 0.265015 0.265461 0.266301 0.263559 0.262266 0.265808 0.263441 0.263717 0.263967 0.26249 0.266194 0.259432 0.266475 0.26231 0.264731 0.26564 0.263772 0.265868 0.263305 0.266122 0.263447 0.265424 0.266119 0.262891 0.267013 0.266323 0.265807 0.26651 0.265244 0.266416 0.262859 0.267433
0.00002 0.00002 0.00002 0.00002 0.00002 0.028461 0.061551 0.086605 0.160466 0.248908 0.329157 0.447624 0.57025 0.721451 1.055482 1.146492 1.42591 1.665656 2.031557 2.334238 2.719673 3.298308 3.497337 4.020119 4.520913 5.293955 5.688953 6.302712 7.094445 7.614383 8.415025 9.215246 9.924679 11.02029 11.521341 12.722216 13.326401 14.630997 15.728536 16.935003 17.836644 18.738285 20.244038 20.837134 22.256056 23.743497 25.356354 26.653438 27.351815 29.262272 30.357917 31.568033 33.062839 34.374588 37.273515 37.973855 39.989452 40.774798 42.781275 44.287096 46.589278 49.000389 50.496951 52.119068 53.69895
Normal
0.325825 0.325825 0.325825 0.325825 0.325825 0 0.237449 0.266842 0.249194 0.263395 0.256573 0.256272 0.263552 0.254744 0.26217 0.261294 0.267315 0.26934 0.264652 0.273525 0.267439 0.270474 0.271141 0.272417 0.273493 0.269337 0.272206 0.27195 0.275555 0.274916 0.273316 0.275299 0.273327 0.273451 0.273776 0.276525 0.275844 0.275682 0.277081 0.275158 0.27795 0.276868 0.276141 0.277278 0.277165 0.278859 0.276648 0.27796 0.279171 0.278154 0.279397 0.277981 0.278764 0.278596 0.280035 0.280202 0.279986 0.280218 0.27982 0.281296 0.280806 0.281611 0.281911 0.280442 0.28206
0.190482 0.190482 0.190482 0.190482 0.190482 0.9702 0.300414 0.40432 0.338369 0.335739 0.303616 0.261528 0.308371 0.281398 0.292344 0.291381 0.291388 0.298599 0.283621 0.29526 0.285553 0.287747 0.288512 0.293046 0.293306 0.277763 0.289743 0.283985 0.29155 0.287592 0.29476 0.288924 0.28384 0.288201 0.288578 0.290349 0.289441 0.285599 0.288372 0.28626 0.28779 0.286269 0.283016 0.288923 0.282616 0.288075 0.283489 0.287624 0.286989 0.28546 0.28839 0.284046 0.287778 0.285021 0.286824 0.287676 0.285246 0.287959 0.287142 0.287738 0.288882 0.287163 0.289079 0.285168 0.288698
0.00002 0.00002 0.00002 0.00002 0.00002 0.033097 0.070694 0.099424 0.195365 0.310009 0.401479 0.532335 0.730391 0.922627 1.316765 1.470746 1.85303 2.188852 2.60564 2.941631 3.536439 4.234412 4.59018 5.08705 5.987848 6.793072 7.346676 8.104446 9.09971 9.903031 10.995809 11.902337 13.007866 14.202925 15.102742 16.40172 17.502907 19.309907 20.206075 21.90955 23.10879 24.211801 26.220171 27.907158 29.224517 30.811766 32.023706 34.113503 36.31784 38.122946 39.414559 40.829763 43.017474 45.029562 47.725433 49.022518 51.034606 52.922963 55.727694 57.32792 59.22175 61.333715 63.824428 66.946825 67.728591
Warm
0.325825 0.325825 0.325825 0.325825 0.325825 0 0.386128 0.381331 0.292094 0.306808 0.292077 0.284663 0.294489 0.287449 0.29225 0.289607 0.293336 0.295105 0.294686 0.294473 0.289033 0.29428 0.298379 0.296851 0.297243 0.293497 0.297904 0.295752 0.298328 0.297508 0.299958 0.2973 0.296851 0.297636 0.299682 0.301235 0.298619 0.299325 0.301036 0.29867 0.300101 0.300232 0.300396 0.300994 0.300012 0.301028 0.300221 0.30147 0.302 0.301872 0.302649 0.301741 0.302514 0.301734 0.303075 0.304572 0.303634 0.304198 0.303831 0.304116 0.304635 0.305234 0.305269 0.304625 0.304381
0.190482 0.190482 0.190482 0.190482 0.190482 0.970339 0.604104 0.608785 0.38817 0.375995 0.340689 0.307695 0.345169 0.319376 0.315381 0.322457 0.315255 0.32224 0.309767 0.321806 0.311338 0.311757 0.313908 0.315814 0.312163 0.300145 0.312092 0.309428 0.314339 0.310756 0.309298 0.311172 0.305319 0.309919 0.307832 0.309561 0.307783 0.305015 0.308401 0.306463 0.30637 0.307352 0.303342 0.308633 0.301685 0.30908 0.303509 0.306314 0.305137 0.306141 0.307501 0.304658 0.307557 0.305498 0.306945 0.307115 0.304717 0.307874 0.307331 0.307327 0.308887 0.307287 0.307333 0.304259 0.30842
0.00002 0.00002 0.00002 0.00002 0.00002 0.036602 0.081706 0.116377 0.23158 0.367953 0.485461 0.672007 0.889401 1.132756 1.592094 1.793669 2.225557 2.667808 3.111657 3.651902 4.252405 5.230903 5.591024 6.266031 7.065965 8.197938 9.089879 9.990409 11.185688 11.987802 13.189048 14.784376 15.790659 17.283641 18.386792 19.683946 21.184225 23.48837 24.682068 26.683072 28.18349 29.580383 32.089616 33.774779 35.493125 37.170921 39.286534 40.677954 43.281453 46.575963 48.070839 49.580379 51.768159 53.674967 56.369083 57.670024 61.178813 63.662229 65.663302 67.562813 70.153404 71.663082 73.961685 78.17818 79.249832

Bright gray ramps (Also long) (Not used in any calculations, but included for anyone who might be interested in the future.)

Cool
0.325825 0.325776 0.21854 0.225325 0.233478 0.240617 0.243058 0.245211 0.247157 0.250357 0.250822 0.253362 0.255187 0.254915 0.256504 0.25722 0.257872 0.258601 0.259632 0.25957 0.259712
0.190482 0.661491 0.311974 0.269829 0.282816 0.265523 0.264612 0.275526 0.266276 0.273367 0.270239 0.267364 0.26738 0.268143 0.269596 0.272955 0.272203 0.270751 0.271078 0.27149 0.274506
0.00002 0.065846 0.3876 0.986082 2.256764 4.127276 6.809505 10.305288 13.520255 18.516432 23.628679 29.446807 34.657107 41.665008 48.671223 56.364731 64.780609 73.303661 82.316422 85.817636 85.692081
Normal
0.325825 0 0.253146 0.246778 0.258352 0.263751 0.265273 0.264553 0.269607 0.272774 0.272211 0.273558 0.275752 0.27596 0.277116 0.277724 0.279064 0.280578 0.281811 0.281096 0.280263
0.190482 0.97051 0.408558 0.316488 0.316751 0.291819 0.292892 0.300617 0.288775 0.296165 0.291035 0.288969 0.288237 0.289838 0.290638 0.294322 0.293868 0.293753 0.291894 0.291698 0.293547
0.00002 0.042087 0.293775 0.909132 2.270735 4.587804 7.796426 11.986387 16.000595 22.18849 28.797506 36.105039 43.011724 50.90681 58.805684 67.685663 77.389781 85.693428 94.811886 98.812001 99.693228
Warm
0 0.343174 0.266729 0.274919 0.281311 0.286553 0.292306 0.288531 0.29262 0.295474 0.294865 0.298295 0.299827 0.300056 0.301497 0.302073 0.303782 0.304069 0.305725 0.305676 0.304232
0.969215 0.645059 0.407052 0.342043 0.341739 0.317663 0.313541 0.322155 0.313504 0.317361 0.314504 0.311058 0.310414 0.311958 0.312317 0.315533 0.315273 0.313948 0.312167 0.31248 0.314471
0.019708 0.091201 0.581073 1.501156 3.477856 6.571391 10.585341 16.165316 21.370655 28.854018 37.148405 45.853246 53.95012 62.434932 71.226603 81.296839 90.591197 99.591605 109.40156 114.493948 114.770856
4 Likes

This isn’t a serious post or anything, but I was thinking about how some CRTs make the image bigger whenever the screen gets brighter, and how some CRTs also have these “shadows” to the right of bright objects. I ended up causing individual scanlines to stretch by different amounts.

Horizontal foldover, bright red/blue bleeding, shadows to the right of bright objects, scan velocity increasing the brighter the color is… So freaking ugly. I hate it.

I’ve create a monstrosity. Why do I always stay awake for hours past midnight coding these stupid things?

Anyway, here’s a download link if anyone wants to try it for some reason. Extract the shader files into any folder and load it in RetroArch. I don’t know why I named it “translate”, but whatever. https://www.mediafire.com/file/ak9arkl30y86gru/translate.zip/file

Oh my god

I just remembered, I made a gradual burn in shader last year too, but it stops being funny once the screen becomes too dark to see anything.

3 Likes

I’ve managed to get a CRT that was manufactured 1985. (To be clear, this is in the USA.) It has some problems, but it works well enough to make a shader and an NES palette based on it. This year is important because of SMPTE-C becoming a thing in 1987, and early games on NES, Atari, etc. were played on TVs like this. (Though still, games made in Japan were meant to be seen on Japanese TVs, which follow a very different version of the NTSC standard.)

Unfortunately, the CRT has a couple problems. First, the CRT is broken in such a way where the brightness (black level) can’t be raised high enough. This prevented me from directly capturing an NES palette, so I had to use a program to generate it instead. Second, this CRT uses physical knobs for its settings instead of an on-screen display, so there’s no “reset” button to get the default Tint and Color settings. Even so, the brightness problem didn’t stop me from getting the phosphors, grayscale, and (relative) chroma demodulation settings, using my colorimeter. With this data, it’s possible to approximate the TV’s colors (with my chosen Tint and Color settings) in a shader in RetroArch.

You can download the shader and NES palette here: https://www.mediafire.com/file/9jpcd1n682hbdr4/toshiba_1985.zip/file (UPDATE: More hardware-accurate grayscale and gamma https://www.mediafire.com/file/z8fv3q9xcbko1rr/blackstripe_with_grayscale.zip/file) This time, I used ChthonVII’s program called gamutthingy to generate the NES palette and LUT. Their program uses advanced gamut mapping methods for better color accuracy.

When playing Genesis/MegaDrive games, use BlastEm for best results with this shader.

As I’m still learning how to use gamutthingy, this shader isn’t complete yet. In particular, I haven’t set up my sampled grayscale yet. Consumer CRTs are terrible at keeping the same white balance across their whole grayscale, and this one is no exception. BT.1886 doesn’t perfectly match any of my CRTs either. For now, the LUT shader and NES palette both have a constant white balance, and they use ITU-R BT.1886 for their EOTF. That’s as hardware-accurate as I’ll do tonight, but soon, I’ll set it up to use my CRT’s grayscale. I’ve added a new link above with these features added.

I’m planning to take one last try at sampling my 1989 RCA ColorTrak Remote, because my previous two attempts at it are clearly wrong. I’m not 100% sure, but I think I know how to do it right this time.

Of course, rebuilding my NTSC composite effect from the ground up is still a goal. The main goals are optimization, accessibility, and familiarity for other RetroArch users. I also have one idea that might or might not make the Genesis artifacts more accurate, but don’t count on it.

CRT info (Updated)

Phosphors. Each one is a geometric mean of 10 samples to remove RF noise. Compared to other phosphors seen in gamutthingy, this doesn’t seem quite right, but I’ll take what I can get.

  • Red: 0.638994661420802, 0.34054912704359
  • Green: 0.302680061977106, 0.611123488970143
  • Blue: 0.143735472664549, 0.0703919024997988

Grayscale (used for EOTF) (excluding values that are too dark to be seen, due to the CRT’s brightness being too low)

.

=IF(A16<20,0.00945707342805*(A16^2.36-0)+0.00002,
IF(A16<40,(0.00945707342805*(A16^2.36-0)+0.00002)*(40-A16)/20+(0.0376774871875*(A16^2-400)+10.739517)*(A16-20)/20,
IF(A16<60,(0.0376774871875*(A16^2-400)+10.739517)*(60-A16)/20+(0.155689133485*(A16^1.68-491.429004672)+57.097684)*(A16-40)/20,
IF(A16<80,(0.155689133485*(A16^1.68-491.429004672)+57.097684)*(80-A16)/20+(0.611867814498*(A16^1.4-308.611247805)+131.307476)*(A16-60)/20,
0.611867814498*(A16^1.4-308.611247805)+131.307476)))) 

(Created by hand using this annoying piecewise regression machine that I hate: https://www.desmos.com/calculator/bjltmbkzcr Why did I create such a horrible tool?)

Note: Uncalibrated CRTs do not keep a consistent white point throughout their grayscale. The xy graph is showing how the white point changes as Y’ (from the YIQ/YUV video signal) changes.

Linear regression to get the demodulator settings: https://www.desmos.com/calculator/52qrtlqybr Clearly, this isn’t perfect, as the peaks of the sinusoids are a little noisy. https://www.desmos.com/calculator/5vxku72991 Updated to reduce noise (by using previous two regressions) and remove outliers for better precision

I can share my excel spreadsheets if requested, but the above information should be all that anyone needs.

7 Likes

2025-03-27

This is my latest NTSC CRT color emulation setup, which tries to approximate the following CRTs: Toshiba FST Blackstripe CF2005 (1985), RCA ColorTrak Remote E13169GM (1989), Sony Trinitron KV-20S11/KV-20M10 (plus at least one unknown Japanese variant with slightly different settings) (1994), and Panasonic CT-36D30B (2000) with its “Normal” color temperature setting. The non-Sony ones are based on data that I sampled myself, while the Sony ones are from data found online.

The catch: The resulting images are much darker than they need to be. If you try using it with a CRT shader, it’ll become even darker. For this reason, I’ve been using a basic bilinear filter lately.

Pay special attention to the US Sony one. My previous shaders have attempted to emulate that specific CRT’s colors, but this new implementation is much more accurate.

Note: For Genesis, you must use the BlastEm core with this shader. That emulator outputs the original hardware’s RGB levels. Some of my previous shaders allow you to correct Genesis Plus GX’s output, but I forgot to include that this time.

Download and installation

Download here: https://www.mediafire.com/file/1gmfye6js9t5gtv/crt_color_2025_03_26.zip/file

Unzip into any folder, preferrably the “shaders” folder in your RetroArch directory.

Move the .pal files into your RetroArch system directory. These are NES color palettes. To use one, make three copies of it called “nes.pal”, “custom.pal”, and “MesenPalette.pal”. Then, in the emulators FCEUmm, Nestopia, and Mesen, change the color palette to “Custom”. To use with a standalone NES emulator, look up that emulator’s own instructions.

The following instructions are for consoles OTHER THAN NES ONLY:

In RetroArch, make sure your driver for video is “vulkan” or any driver that is able to run slang shaders. Changing this setting requires a restart. Most recent PC should be capable of this. Most console ports of RetroArch are not able to run slang shaders, so they’re not able to use my shaders at all. (My NES palettes will still work; in fact, they work on emulators outside RetroArch too.)

Load any game as usual. (Note: For Genesis, you must use BlastEm with this shader. That’s my mistake.) In the Quick Menu, choose “Shaders”, and choose “Load Preset”. Navigate to wherever you unzipped crt_color_2025_03_06, and you should now see the files starting with “P68k” which each correspond to a different CRT. Pick whichever one you like–I recommend starting with P68k_SonyJP_1994. After loading it, go to “Shader parameters”, and feel free to change only these four settings to whatever you like best:

You are recommended to change ONLY these four settings

  • Enable NTSC color correction (a.k.a. red push) – Turning this off is equivalent to RGB-modding a CRT or using YPbPr Component (if available), which bypasses the NTSC color corrections.
    • You may only disable this on the 2000 Panasonic CT-36D30B. This is the only CRT where you can bypass the “red push” on the real hardware because it has a YPbPr Component input, which the other CRTs don’t have.
  • (Default=0.0) End-user Tint knob rotation – You are very highly encouraged to change this to whatever you like best.
  • (Default=1.0) End-user Color knob rotation – You are very highly encouraged to change this to whatever you like best.
    • Prior to the late 90s, everyone always had to mess with the Tint and Color settings on their TVs to make the image look acceptable, but it never would look perfect. Everyone was happy that their TV just worked.
    • The defaults in my shader approximate the broadcast standard, but consumer TVs before the late 90s often had totally wrong defaults.
    • In addition, game developers often didn’t have the best defaults either. In fact, many developers used RGB (except for the NES).
  • Approx. Gamma (recommend 2.2) – This is the “Brightness” knob in disguise. You are very highly encouraged to change this to whatever you like best.
    • “2.2” is the actual NTSC standard, but 2.0 gives the best detail in dark areas, while 2.4 later appears in the BT.1886 standard. In general, I recommend 2.2.
    • Note: Do not confuse this with the other setting called “(Dual) CRT’s actual gamma”. This is best left at 2.0.

More details about how this works

The most important part of this by far is the improved KV-20S11/KV-20M10 approximation. Unlike the other CRTs here, I have never owned either of these Trinitrons, so they are being approximated solely using information from a few different sources on the internet. All my previous uploads, from before I owned a colorimeter, assumed these CRTs used illuminant C, the standard whitepoint for NTSC broadcasts. I have since discovered that the correct whitepoint is most likely 9300K+8MPCD, the standard whitepoint for Japanese broadcasts, even though the CRT is manufactured in the USA. In fact, most CRT TVs have much higher color temperatures than the standard. (More details here.)

That means, my releases from before December 2024 (which feature signal artifacts and “sanitized” presets) need their whitepoint changed to a “custom x, y” with x=0.2838, y=0.2981 (shown as 2.84 and 2.98 in the settings). That fixes the issue with them being extremely pink. While you’re at it, you should fix the demodulation settings: change the R-Y/G-Y/B-Y auto-sync to “off” (or -1), and change Color/Saturation to 0.975 and Tint/Hue Rotation to either positive 9 or negative 9, whichever one looks correct. Feel free to adjust these two Color/Tint settings to your liking, but know that these are the defaults for US NTSC.

For the other CRTs, these are ones I currently own in real life, and I have used an X-Rite i1Display 2 colorimeter to measure them. I have completely re-sampled the Toshiba CF2005, RCA ColorTrak Remote, and Panasonic CT-36D30B, and I’ve done it more accurately and carefully this time. (Note: The CF2005’s white balance couldn’t be taken directly because of its poor condition, so I had to make an educated guess: The red and green color channels both are very closely in-sync, but the blue channel is out of sync. That means the correct whitepoint must be close to this specific red/green ratio. Assuming that point is on the daylight locus, it’s about 8300K.)

Another improvement is that the Contrast, Brightness, Color, and Tint knobs are automatically calibrated for you. By default, the shader approximates the 1953 NTSC standard in the CRT’s intended region. You are still allowed (and encouraged) to adjust the Tint and Color knobs by yourself easily. Brightness is adjusted using a different setting called “Approximate gamma”, which is really a brightness setting. (That’s not to be confused with “Actual gamma”, which is the CRT’s real gamma constant–Don’t adjust “Actual gamma” unless you know what you’re doing.)

I have improved the EOTF too. When looking at sampled data, it’s easy to fool yourself into thinking your CRT is around 2.4 gamma, or that something is wrong with your setup. What seems more likely to me, just based on the data from my colorimeter, is that CRTs tend to have a gamma somewhere between 1.9 and 2.1, and that the brightness tends to be lower than the standard black level to approximate the standard 2.2 gamma. Hence, for this CRT emulation, I’ve set a gamma of 2.0 and a brightness of about -0.08 for all CRTs. In the shader’s settings, you can set the CRT’s real gamma and the desired gamma yourself.

I’m using ChthonVII’s program called gamutthingy for simulating the phosphor gamuts with state-of-the-art gamut compression mapping. For more information on that, see https://github.com/ChthonVII/gamutthingy

Something not emulated is how the 1980s CRTs have very reflective screens. Even when powered off, the screen is still a light gray. This will have to be added in an update. This also isn’t emulating these CRTs’ uncalibrated grayscales either; the white balance is constant throughout the grayscale in this shader.

NES palettes for all models except the Sony Trinitrons have been included. The Toshiba 1985 and RCA ColorTrak 1989 ones are improved, but the Panasonic 2000 ones are the same ones that I’ve already posted.

As a final note: I still apologize for not posting any video signal improvements, after months of promising.

10 Likes

2025-04-24

Minor update to my previous shaders, but the default settings look very different from before. I’m releasing this update a bit hastily without extensive testing, so beware of that. https://www.mediafire.com/file/ri1x3pk8xveklrq/crt_color_2025_04_24.zip/file (Modified 22:04 UTC to remove “Auto” chromatic adaptation, which is bad and has no use case.) Few or zero true improvements to accuracy have been made, and the previous version can mostly appear similar to this one just by adjusting settings.

Usage and installation instructions are unchanged from the previous post, except that this new version doesn’t include NES palettes.

  • Changed the default Tint, Color, and Brightness settings to look better. This change looks much better than my previous version’s defaults, at least in my own opinion. (Though, you were encouraged to change those to whatever you like, and I still encourage that now.)
    • In short: The previous version was calibrated for actual NTSC video (with one small issue), and this new version is calibrated for video games.
  • Added “1997ish” presets that use the well-known Sony CXA2025AS in US and JP mode. This really should’ve been included from the start; there was no good reason for omitting it.
  • Added a “split” SMPTE-303M test pattern. This pattern can be used along with the “Goal gamut” setting to help set the CRT’s Tint, Color, and Gamma to your preference. (Really, I made it to try to reverse-engineer the way that these CRTs are intended to decode color, and to try to determine how typical end-users would likely set their settings while playing video games.)
  • Updated the 1985 Toshiba CRT’s whitepoint to a newer estimate that should be better. (It still might not be that reliable.)

For some more details about what’s changed with the default settings:

  • The previous version had the CRT’s real gamma at 2.0, but the brightness knob was darkened to approximate 2.2 gamma. The rule of 2.2 gamma was never enforced, and values ranging from 1.8 to 2.5 were used (and I won’t cite a source for this). This new version uses a straight 1.925 gamma with perfect brightness, which is more like you’re playing in a well-lit room, and this is also a match both for my mostly-intact 13-inch RCA ColorTrak Remote, as well as for the later SMPTE-170M/240M standards.
  • The previous version set Tint and Color to match the color Orange in standard 1953 NTSC, but I took chromatic adaptation into account, which I now think is wrong and isn’t what most people did. This current version sets Tint and Color on a 1.925-gamma CRT to match a flesh tone in a 2.4-gamma Japanese RGB monitor, without performing any chromatic adaptation. 2.4 is for CRTs whose brightness is calibrated in a dark room, and it appears in the standard BT.1886.
  • To make non-Japanese NTSC games look better, change the setting “Goal Gamut” to 2.
More details about skipping chromatic adaptation (Please don't click this)

The previous version accounted for chromatic adaptation for these reasons:

  1. These CRTs are from the mid/late 80s to the 2000s, and chromatic adaptation was absolutely not an unknown concept. By the time that CIELAB was published in 1976, it had been decided that XYZ-scaling sufficiently approximated chromatic adaptation for that purpose. By 1985, the Bradford method was published, and this method still is used to this day in commonly-used software such as ArgyllCMS, Adobe Photoshop, and (correct me if I’m wrong about how this works) Windows 11’s stock color management.
  2. Performing chromatic adaptation in a SMPTE-303M test pattern had shown that orange, blue, and other critical colors were matching great at the expense of green being a little bit too yellow. It looked believably like this is what it was supposed to be.

My reasons for not accounting for chromatic adaptation in this update are the following:

  1. Documents such as “The White Color of Television Receivers” by Donfrio, Hess, and Sember and Toshiba’s patent US5301017A both seem to suggest that whitepoints bluer than C/D65 are just there for technical reasons and for making black-and-white footage look right (due to old black-and-white CRTs having very blue/green whites), but nothing ever suggests that anyone would ever genuinely want color video to visually appear like it’s illuminated by a bluer whitepoint. Perhaps they might decode the saturated colors in a way that still looks like it’s illuminated by D65 or C.
  2. I got a spare half-hour and finally found a PDF for this paper that had been shared with me last year. (Really, it was hiding in plain sight.) It is from 1966 (predating all CRTs in this thread by at least 19 years), and it explains just one method for deriving the corrective R-Y/G-Y/B-Y demodulation. The paper shows how NTSC color can be almost perfectly represented at D65, even with care taken to make specifically chosen critical areas more perfect. However, it also acknowledges that many CRTs have a nominal white near 9300K (in this case specifically referring to 9300K+27MPCD, x=.281, y=.311, not to be confused with 9300K+8MPCD), and as such, it performs the same derivation for this too. This part is the kicker–Do you remember what I said earlier about no one genuinely wanting color videos to look like they’re illuminated by 9300K? This paper just straight up derives a matrix that perfectly represents a flesh tone and a green (and thus everything in between them) as if illuminated by the standard illuminant C, but it moves the base white from C to 9300K at the expense of everything else being screwed up. (Something not mentioned is that they could’ve experimented with adjusting the luminance of this 9300K whitepoint independently of the green/flesh luminances, which could at least make the rest of the gamut look slightly better.)
  3. Now that I’ve tried matching the CRTs in the 303M test pattern without accounting for chromatic adaptation, the Japanese-branded American NTSC CRTs (Toshiba and Sony), when used with a test pattern of American standard NTSC colors, appear to be doing exactly what that paper described, making green through flesh look correct, moving white to something bluer, and messing up other things, although the whitepoints they picked mess things up differently than 9300K+27MPCD. My 13-inch American-branded (RCA) one that I keep on my desk in my university dorm, which is closer to D65 but really more like blackbody 7500K (consistent with Dogway’s claims that D65-region CRTs were typically around ~6900-7100K and sometimes ~7500K in practice) makes almost all of the American NTSC test pattern colors look nearly right, consistent with how this paper demonstrates how CRTs with the standard white have vastly superior colors. Similarly, the Japanese Sony CRT, when used with a test pattern of Japanese standard NTSC colors, leaves everything mostly intact like it had been broadcast, since the whitepoint is already at 9300K and doesn’t have to be moved. (I can’t tell what’s going on with the Panasonic one at all.) Even though these tests are done hastily, I believe for now that these CRTs’ color corrections were made without chromatic adaptation.
  4. In general, performing chromatic adaptation just doesn’t preserve the original image that well in my opinion, based on my own experimentation.
5 Likes

2025-04-26 - White Trash

This is a new NTSC CRT color shader, called white-trash, which I spent some hours making over the past two days. It has a similar purpose to my shader from two days ago.

Unlike the previous release, this one isn’t based on any specific TV. Instead, this one tries to be a generic average of common American TVs. There isn’t as much real data backing this one up, so take it with a grain of salt.

The shader works like this:

  • Your TV is made to decode 1953 NTSC video that’s broadcast over the air with a gamma of 2.2. It also is made to change the white point to ~8700K daylight without changing the red/yellow/green range of colors, but at the expense of other colors becoming bluer. (This is why it’s called white-trash.)
  • The game you’re playing is assumed to developed on a CRT in Japan over an RGB connection with a gamma of 2.4.
  • You turned your TV’s brightness up higher to make dark things easier to see, resulting in a gamma of 1.925. You change your TV’s color and tint to make the game look acceptable, but it’s still not perfect because your TV is made for watching NTSC video broadcasts, not Japanese RGB.

EDIT: There is a bug. This only works if the broadcast white is set to illuminant C.

Download here: https://www.mediafire.com/file/4gg2npxm3atkvjc/white-trash-2025-04-26.zip/file and install by extracting it into RetroArch’s shaders folder.

The shader has the SMPTE-303M testchart built in so that you can see what it’s doing. In each box, the left half is what the color is supposed to look like, and the right half is how the TV displays that color. These ones are set to automatically match the brightness of both halves so that you can just compare the color itself.

Here’s one showing how colors meant for sRGB (really EBU) 2.2 gamma get changed on this CRT. In other words, this is comparing what an emulator typically shows to what an average American TV shows. Notice how gray, cyan, and some greens all become bluer. Other than that, it’s not too different.

Here’s one comparing what many Japanese developers saw (on the left halves) to what the average American consumer (according to this shader) saw (on the right halves). Notice how the grays aren’t changing much because both TVs used similar white points, but there is still some change elsewhere. Like before, it’s not too different.

The previous upload from 2024-04-24 had an SMPTE-303M test pattern built in too, so for comparison, here’s how the Sony US 1997ish preset from two days ago affects sRGB colors:

and here’s how that same Sony US 1997ish preset affects the colors that Japanese developers saw:

Comparing these, I can’t say for sure that “white-trash” is that close to original hardware. That’s even though I coded white-trash specifically based on what I assumed many popular brands must have been doing. Even so, these different TVs’ colors are so slightly different but similar to each other that I’m not sure that it’s worth it to keep experimenting with it either.

Anyways, I am satisfied with the colors for now. The next thing to work on is composite video signal artifacts, the thing I’ve been meaning to update for at least six freaking months. At this point, every possible reason for me to wait on that is gone.

8 Likes

Turns out, there actually are a couple more reasons to wait on working on the composite.

Japan RGB shader pack

Over the past couple posts, I’ve stated that I’m color-matching the old TVs’ settings against what I believe to be the most common intended colors for Japanese-developed games, yet for some reason, I haven’t actually ever posted a shader for the Japanese intended colors.

This pack just does Japanese RGB straight-up. (Keep in mind, not all Japanese CRTs looked quite like this. There is absolutely no definitive correct answer, as all CRTs were a little different from each other.)

Download here: https://www.mediafire.com/file/4er1xoema7v8v6i/crt_color_jp_rgb_sony.zip/file

Details

The above shader is based on Sony Trinitron P22 phosphors, a white point of 9300K+8MPCD (x=0.283, y=0.298), and an EOTF of either 1.934, 2.2, or 2.4 gamma. Many CRTs in Japan had phosphors close to these Trinitron phosphors, and there is also a Japanese phosphor specification described in ARIB TR B9 v1.0 (1998) that looks similar to this. 1.934 gamma approximates the SMPTE-170M/240M and Rec. 709 standards, and is probably closer to what more end-users saw if they turned up their brightness for a well-lit room. 2.2 is from sRGB, the same as the monitor you’re currently using. 2.4 (from BT.1886) or 2.5 (just a commonly shared number) happens if you carefully set your brightness in a dark room. (With a little more time, I could use BT.1886 and do a regression to approximate those gammas, but I’ve chosen to just directly use those gammas to save my time. This post is being done in more of a hurry.)

Dogway’s Grading Shader, which has existed for a long time, is intended to show color as seen on Japanese developers’ professional monitors. The shader’s main flaw is that it has to perform gamut compression in real time, and it isn’t able to do a great job at that. ChthonViI’s program, gamutthingy, solves that problem by precomputing a full LUT in advance with much better gamut compression mapping.

There are some aspects of gamutthingy that I don’t fully agree with at the moment. First, its EOTF uses specific real-life black and white levels in cd/m^2 and sets up the BT.1886 Appendix 1 EOTF function around that. I would much rather keep the EOTF’s white fixed at 1.0 and pick a black level such that the EOTF approximates the 2.4 gamma found within that same standard. Second, gamutthingy’s default behavior is to perform chromatic adaptation from the CRT’s whitepoint to sRGB’s whitepoint, but I would rather keep the original CRT whitepoint intact. In fact, I’m not 100% certain of this, but I might rather have chromatic adaptation never be performed, as if the content being displayed is meant to appear to be illuminated by D65 even though the CRT’s white point is something different. Third, when CRT emulation is in use, you’re limited to using the BT.1886 EOTF, when I might rather use an alternative EOTF ripped from my own CRT, especially with close to a gamma of 1.925-ish. Recently, I found that regressions of the form (ax+b)^(cx+d) do a very great job at matching a sampled EOTF, so I am strongly considering making a custom EOTF from a real CRT.

Simple test pattern shader pack

I’ve been putting built-in test patterns in my shaders for a very long time now. I figure that other shader and preset authors might benefit from having them too.

Download here: https://www.mediafire.com/file/stgl5oo901ncqbb/test_pattern.zip/file

Using this is simple. Load the RetroArch shader that you want to test, prepend the “test-pattern-prepend” preset, and (optionally) append the “test-pattern-append” preset.

The test patterns included are:

  • Three kinds of stepped color ramps:
    • Brightness scales for primaries, secondaries, and white
    • Saturation scales for primaries and secondaries
    • Hue rotation between primaries and secondaries
  • Full HSL spectrum
  • HSL spectrum with primaries and secondaries widened
  • All NES palettes from the Mesen, Nestopia, and FCEUmm LibRetro cores, and from MiSTer.
    • Some of these palettes weren’t originally made with de-emphasized colors. For these palettes, emulators have to make their best guess for what the de-emphasized colors look like. This test pattern includes Mesen and Nestopia’s de-emphasized colors for those palettes, but not FCEUmm’s de-emphasized colors. For those palettes, I am also including generated .pal files with the de-emphasized colors included, for use in other NES emulators or NESRGB mods.
    • Some palettes from Nestopia are not hard-coded but are instead generated inside the emulator. For this reason, Nestopia’s Sony CXA2025AS US and JP palettes both look different from the ones in other NES emulators. I am including these both in the test pattern and as .pal files for use in other NES emulators or NESRGB mods.
    • I wasn’t able to open full_palette.nes in FCEUmm, so I had to extract FCEUmm’s palettes without de-emphasis at all. Anyways, FCEUmm’s default palette is now available as a .pal file in this release.
    • The MiSTer project has this large listing of 262 NES palettes as .pal files. I have included all of these in this test pattern shader.

I have chosen not to include the SMPTE-303M pattern because few other people here have a use for it. The pattern only makes sense in cases where you already know what you want something to look like, and you are trying to match that thing. Hence, you would have to pick several specific colors out of different games and arrange each in that pattern. At that point, it just makes more sense to use images from actual games as your test pattern.

These test patterns make it easier to tell if a shader preset is doing something weird. For instance, if you run this against Megatron (in shaders/shaders_slang/hdr), you can see that some of the SDR presets have blue getting too bright, which causes some detail to be lost. This can be fixed by reducing the contrast.

There is one major problem with using test patterns. Some shaders, such as the afterglow in crt-guest-advanced, take pixels from the original game’s output, bypassing any shaders that are prepended before it. This results in the test pattern getting mixed with the game’s image. As such, with shaders that work like that, you shouldn’t use what I’m linking below. I suggest instead using either the 240p Test Suite (preferrably on consoles like SNES, PS1, or Wii) or the image viewer LibRetro core. (I have also seen a window-caster core posted elsewhere, but I have not tried it before.)

Here’s what that looks like. These two screenshots are with an older preset by sonkun. Notice that the status bar from NES Battletoads is glowing near the top of the screen, even though the image being displayed is a test pattern. Also, notice how magenta shifts hue as it gets brighter, and both cyan and blue reach a limit at their brightest points. To me, it looks like sonkun was purposely keeping the colors as bright and colorful as possible, so much so that compromises needed to be made in these areas. That’s in contrast to other presets on this site–including my own–that achieve better accuracy at the expense of darkening the screen.

And lastly, there are some shaders that aren’t compatible with the appendable test pattern. Here’s what happens if I append the appendable test pattern on MegaTron:

Wow.

Sony CXA2025AS palettes

The CXA2025AS palettes in current NES emulators are all still using D65 for white, but the CXA2025AS is meant to be used with Sony Trinitron phosphors at 9300K+8MPCD (or at least something very close to that). I’ll definitely have to post new CXA2025AS palettes with that taken into account.

Point is, I’ll finally do video signal stuff after I address that Sony CXA2025AS issue.

5 Likes

This is useful, why don’t you submit the test patterns with a PR to the official slang shader repo?

2 Likes