This is an incomplete, ongoing hobby project of mine to get these consoles’ video signals and colors to look more accurate on RetroArch. The main things unique to this are its customizeable video signal and its emulation of the color corrections found in real jungle chips’ data sheets. The US presets aim to emulate the colors of the Sony KV-20M10 and KV-20S11, without their Dynamic Color feature.
Latest version (2024-10-16).
My latest releases have been using my own new NTSC shader called Patchy NTSC, which combines the first three of these four features. (Fyi, my username is going to be changed to “Patchy” in the near future, so please try not to get into the habit of calling my shader Patchy.)
- NTSC video signal artifacts and RF noise. Genesis/MegaDrive, SNES/SFC, and NES/FC are supported, for RF, Composite, S-Video, and Component video signals. The shader carefully encodes the signal, optionally adds RF noise, and carefully decodes the signal to get close to the same artifacts as original hardware, albeit at a serious performance cost, especially if using RF. Advanced users are encouraged to use the shader’s settings to try to replicate more consoles’ signals. Settings to adjust sharpness, noise severity, and the noise RNG seed are included as well. NES signal emulation requires you to set Mesen’s color palette to “Raw”, which looks like just red and green. SNES and Genesis presets automatically detect when the game changes resolution. To get the intended artifacts, make sure you set your emulator to crop equal amounts of overscan on both sides. PS1 support might be coming soon.
- Color alteration caused by the jungle chip. If you’ve seen the CXA2025AS NES palette, that’s one of the jungle chips you can choose (number 7 in the settings), except you can use it on Genesis now, and you can adjust the settings for contrast, brightness, color, and tint.
- Gamma and phosphor gamut. Gamma is handled using the BT.1886 EOTF function. The phosphor gamut is done using Chthon’s precomputed lookup tables with “fancy-pants” gamut compression, resulting in good phosphor gamut emulation without much performance cost. Afterglow is simulated using code from crt-guest-advanced, even if you choose a different CRT shader like Royale or Hyllian.
- The CRT display itself. A few different “sanitized” CRT shader presets are included, which have settings that disable color and signal alteration. The purpose of that is to give my shaders full control of the NTSC signal and color emulation, without the CRT display emulation interfering with that. That said, those CRT shaders are still being worked on separately by their own authors, and if you update them, you might have to update my sanitized settings for them. To use this, you can pick the “SignalOnly” preset that corresponds to your emulator and append a sanitized version of your favorite CRT shader to it. If you customize one of these sanitized presets, be careful not to change anything that could alter the output colors or signal, such as Gamma, LUTs, or some of Hyllian’s features.
Here are the major credits for this project (though, not everything listed here is in my latest version):
- aliaspider - GTU-famicom, an NES video signal emulator, which helped me understand how the NES’s video signal works. I had copied the Y signal resolution setting into Patchy NTSC as a low pass filter option.
- dannyld - Source of the settings in ntsc-md-rainbows, a preset for mame-hlsl’s NTSC passes that approximates the Genesis’s NTSC artifacts. This gave me the idea for customizable color carrier settings.
- Dogway - Grade, a large shader that performs many steps to process CRT colors. Only the EOTF (a.k.a. gamma) function and SMS blue lift are used from it.
- Chthon - gamutthingy, a program for generating lookup tables, and trilinearLUT.slang, which correctly samples the lookup tables. This is used for one of Patchy NTSC’s steps. I’ve altered this a little bit to let the user switch between three tables and toggle chromatic adaptation on or off.
- Guest - crt-guest-advanced, in my opinion the best CRT shader in RetroArch. Also, a gaussian blur shader, which I’ve used in Patchy NTSC as one of the low pass filter options. I have included two different personal presets using this shader, and they still work alright as of now on the latest version of Guest’s CRT shader.
- lidnariq - Posted measured voltages of their NES onto nesdev, including attenuated voltages.
- I forget who, but someone posted estimated NES hue error amounts on nesdev. The 2C02G amount of 5 degrees is a close match to a video capture of my real NES.
- EMMIR (LMP88959) - Created NTSC-CRT, written in C. In my source code, you can see my failed attempt at directly porting the 3-band equalizer from NTSC-CRT.
Important notice regarding my original post and this thread
I am finally able to edit this first post. At the time that I made this initial post, I was pulling an all-nighter, thinking I’d been working on my project for too long without being active on the forums or having a dedicated thread for my work. “Real Consumer Color CRT Shader Presets” was a bit of a misnomer; this is really more like an NTSC emulation setup that I’ve put together specifically for the NES and Genesis, which is then appended onto an essentially blank CRT shader. I kept saying “real” to really emphasize that it was aiming for accuracy to the real hardware, including the original console’s video signal and a CRT’s color corrections, in contrast to other projects which don’t take it quite as seriously, but at the time, I didn’t realize quite how much was needed to do that.
Original post below, with my newbie self’s overconfidence, and a lot of information overload that has little to do with my latest work
Though, my original preset pack does have one goofy feature that my latest pack just hides in its “resources” folder: Using NES palettes on Genesis and other consoles. (Seriously!)
(Spoiler) LOOOONG Outdated original post
WARNING: It is 3AM, and I don’t know why I’m doing this. This is a big mega-essay post for no reason whatsoever. Oh my god.
I need to go to bed. Just download the presets here. I’m not sure what kind of response to expect, other than the obvious “It’s not working”, where it turns out that I in fact uploaded the completely wrong files. https://drive.google.com/file/d/120tmSq6Z09IcJ0Y7JoHEU3sLqHcqmEYh/view?usp=sharing
Credits/sources:
• aliaspider – GTU-famicom, an NES/FC video signal shader. I removed the low-pass and scale-Y shaders.
• Drag – NES palette generator, which I used for colorimetry (phosphor) conversion, different PPU revisions’ hue error amounts, and color clipping.
• Dogway – Grade shader, which had P22-80s/90s/J phosphors and accurate 9300K whitepoint, and a number of functions that I copied
• Guest – Advanced CRT shader with many customization options. I have included a preset with my personal settings for this shader.
• PlainOldPants (myself) – Alternative simplified grade shader with color-correcting YIQ matrix support and built-in test patterns.
- Chthon - Posted a faster algorithm for implementing the YIQ color correction, and discovered two NTSC video decoder chips that were likely to correspond to certain specific phosphors, namely in Sony’s Trinitron TVs that were launched in 1994.
• …and various other people who have written code and/or posted crucial documentation online. Thank you all.
• Sony, Toshiba, et al – The culprits of decades of NES palette disputes and inaccurate NTSC TV colors, thanks to their inaccurate, inconsistent YIQ decoding matrices.
I’ve procrastinated for too long on making a dedicated topic for this. In this post, I am sharing my CRT shader presets. Though I did write a lot of code myself, the majority of this is directly from piecing together parts of other shaders, so I have included a file called credits.txt to give credits. The consoles supported are the NES/FC and Genesis/MegaDrive, but I’ve also included “universal” presets that should look good enough for most mid-90’s and early 2000’s consoles. Using this, you can get quite close to the colors of many specific real TVs.
The main feature of this is the color output. The colors aren’t just realistic, but they’re real. The CRT hardware that affects color is being emulated, including the composite video color correction circuit, the consumer’s contrast/brightness/color/tint dials, the phosphors, and the white point. The current version of Dogway’s Grade shader implements all of these things except for a color correction circuit.
The presets I’ve included are all, by default, specifically trying to emulate the colors of a 1994 Trinitron, using data recently posted by Chthon in the Grade shader thread. The PAL presets are not technically real, but they are the same Trinitron setup with PAL color… Although this is intended to emulate a Trinitron, only the color is being emulated; no attempt was made at emulating the physical look of the screen, outside of using a soft, generic crt-guest-advanced setup. Using the shaders in the “resources” folder, you should be able figure out how to piece together a shader with the CRT shader of your choosing.
How to install:
- Download the shaders. They’ll be either in a .zip or a .tar.gz, which are different kinds of archive files. If you’re on Windows, you might need to install some software to open a .tar.gz file, such as 7-zip.
- Inside the .tar.gz or .zip file, there is a single folder named PlainOldPants. Move the PlainOldPants folder into your shaders folder. So, just to double check, when you’re in your shaders folder, you’ll see at least these three folders: shaders_slang, shaders_glsl, and PlainOldPants.
How to use:
- Make sure your video driver is set to one that is compatible with slang shaders, such as vulkan.
- If you’re playing an NES game, use Mesen. If you’re playing a Genesis game, use Genesis Plus GX, and make sure your emulator is showing all borders, a.k.a. not cropping any overscan. Do not play a Master System or Atari game; those consoles are not supported yet. For other consoles, it doesn’t matter what emulator you pick.
- If you are using Mesen, set your color palette to “Raw”. In-game, it will be just red and green right now, but that’s a special format that’s going to be read by the shader.
- Near the bottom of the quick menu, there’s a shaders menu you can open. In the shaders menu, choose “Load”. One of the folders is titled “PlainOldPants”, and inside that folder, there’s another folder that’s a date. Inside the folder that’s a date, that’s where all the default presets are. If you picked Genesis/MegaDrive or NES/FC, you should pick one for that console; otherwise, pick universal, which just uses a horizontal gaussian blur to mimic the video signal’s blur. Shaders labelled “clean” will also use a horizontal gaussian blur instead of a real video signal. On NES, “fancy” is the best because it allows you to adjust the amount of artifacts to a more accurate amount, unlike “fast” which is stuck at maximum artifacts. The PAL Genesis never had rainbow banding in its video signal, so its only version is clean.
What’s the difference between the us, jp, and pal presets?
- The “US” presets are meant to replicate an American 1994 Trinitron’s colors. It uses demodulator preset 9, which is the Sony CXA1465AS, found in the KV-20M10 and KV-20S11. The phosphors are from the GDM-17SE1 Trinitron computer monitor from the same year. You’ll notice that areas of the screen that used to be light blue become cyan, and areas that were a dark green sometimes become very brown. The brown column of the NES palette becomes much more red. Overall, red is more saturated than an emulator normally shows and is interfering into the slightly brownish green and yellow colors.
- The “JP” presets are meant to replicate a Japanese 1994 Trinitron’s colors. It uses demodulator preset 8, the Sony CXA1464AS, which is like the CXA1465 with Japanese axes for decoding instead. Light blue areas become slightly more purple, and dark green areas are still affected a tiny bit, but not noticeably so. The red is still more saturated than the emulator normally shows, but it doesn’t bleed as much into yellow and brownish green colors.
- The “PAL” preset still uses the Trinitron’s phosphors, but it does not use a Sony demodulator. There is not much variation between PAL demodulators, so I felt safe using the Toshiba TA8867AN’s PAL axes for this. There is basically no unusual color at all, except for green being slightly more saturated.
I don’t want to figure out all these settings! What do you want me to do?
- First of all, if you chose one of the genesis “model1” presets, there is a long list of CRT-related settings that seem to do absolutely nothing. Those are used by ntsc-md-rainbows, and there are a couple settings in there where if you change them, it’ll mess up the video signal, and you’ll have to fix it by reopening your shader. Holding the ‘R’ or ‘R1’ button on your controller (‘W’ on my keyboard) scrolls down fastest in this menu. You’ll eventually reach my settings. The settings will then look like I’ve picked “GenPlusGX” first, and “BlastEm” second. This is not a mistake. Do not fix it, or your colors will look terrible.
- If you’re playing Battletoads or Battletoads & Double Dragon on the NES with a preset that isn’t “clean”, make sure you enable the setting specific to that game at the top. You will notice that the artifacts flicker in a different way from before.
- The “Demodulator preset” is one of the most important settings. You should try a few of the different presets to get a feel of how they affect the image. Presets 3 and 9 have the strongest American consumer effect on the image. 2 is the Toshiba TA8867AN, which looks similar to the CXA2025AS in US mode, but a little more refined to give better blue and brown. 5 and 6 are still distinctly American, but they are a big step closer to modern colors. 7 is a true PAL matrix, and 1 is actually the SMPTE matrix for NTSC broadcast, not truly PAL. The JP ones, 4 and 8, are somewhere right in between the American consumer NTSC and true SMPTE color.
- You know what Contrast, Brightness, Color, and Tint do already. What you don’t recognize is the warning on Contrast: “1.0 recommended. Beware of clamping and gamma.” What this is saying is that the more you raise your contrast, the less the colors are going to fit. Also, the “1.0 recommended” is kind of a lie, because right now, increasing your contrast to 1.0 is going to cause a bunch of colors to get clamped. What you should do instead is set “Contrast 1.0 is: Fit Max RGB” not “Fit Max White”, and have 1.0 contrast with that enabled. That is why 1.0 is recommended!!! Now, you can set Brightness, Saturation, and Tint however you like, and the contrast will automatically darken the exact correct amount to keep everything from getting clamped. You’re still allowed to change the contrast of course, though going over 1.0 will cause clamping. All of the default demodulator presets have the color red so over-saturated that the brightest red is brighter than the brightest white, even by default, so if you try to fit max white, you’ll clamp a bunch of red.
- If you think everything is too red and orange all the time, and you’re tired of having to change your saturation every time you switch demodulators, try enabling “Normalize Saturation to Red instead of Blue”. You’ll notice your saturation suddenly drop. Now, start switching between the demodulator presets again, and you’ll see that they all have the same red and orange saturations now. Problem solved.
- To a beginner, the phosphor settings look quite scary, but they’re actually a simple concept. Some of these settings that have only a subtle impact on the image on a real CRT cause the image to go out of the bounds of the sRGB color space, which causes them to become less accurate. Whether it’s worth it is up to your preferences. Personally, I recommend that you stick with the default settings I’ve picked for you, and only change the “White” setting, which is actually your white point, but that whole string had to be less than 64 characters long to fit. If you want to try changing anything else, switch from Hybrid to 7point. You can set a custom white however you want too, but that’s intended for users who’ve sampled the white point of a wearing-out CRT that they’re trying to color-match… like myself.
- There are 5 different built-in test patterns. One of them is for the NES, and the other 4 are for everything except the NES.
- Those four toggles at the bottom that say “Reveal…” will cause any clamped colors to glow in your face. Make sure all four of those are turned off during your normal gameplay.
- The settings after that pertain to Guest’s advanced CRT shader. Feel free to customize, but beware that only my alternative grading shader is meant to be affecting the colors; the CRT shader is meant to just pass those through. Also, do not enable afterglow, because that causes the emulator’s inaccurate output colors to mix with my shader’s colors, though there’s probably a fix for that that I don’t know about.
Full list of features (LONG):
- Emulates a type of color correction circuit that appeared in most consumer CRTs. Using the same method with different numbers for all of them, several real chips are implemented. View source code to see which one is which. I believe that this is the first RetroArch shader to implement this for consoles other than the NES. Credit to Chthon for fully working out the formulas for a fast implementation.
- Knobs for Contrast (Picture), Brightness (Black Level), Color (Saturation), and Tint (Hue Rotation/Offset), which every consumer TV had, either physically or in an on-screen display. There is a feature, disabled by default, which can automatically decrease your contrast the perfect amount to prevent any colors from going over 255, but I disabled this because some games looked incorrect without some amount of clamping, and some games were just darkened too much.
- Emulates the color of a real CRT’s phosphors, using code and constants originating from both Dogway’s Grade shader and Drag’s NES palette generator. I have implemented my own alternative gamut mapping (gamut compression) algorithms called “7point” and “Hybrid” instead of using the one in Grade. However, when you are just starting, I recommend either sticking by my Trinitron color presets, or using 7point instead of Hybrid if you want to try anything else. Unfortunately, the chromatic adaptation uses the obsolete Bradford method, which I will soon replace with the wp_adjust function from Grade.
- Approximately emulates the NES and Genesis’ composite video artifacts using modified versions of GTU-famicom (by aliaspider) and ntsc-md-rainbows (Sorry, I’ll look up this user soon). ntsc-md-rainbows must be used with Genesis Plus GX (not BlastEm) with the entire overscan shown, not cropped at all. GTU-famicom should be used with the “Raw” NES palette in Mesen. The modded GTU-famicom has updated voltage values and, if you pick the “fancy” mode, allows you to set custom “artifacting” and “fringing” amounts to make the signal as harsh as you want. If you insist on using a specific NES color palette with GTU-famicom instead of decoding the “Raw” one, I’ve modded GTU-famicom to support that too, but it takes extra steps to install your palettes into it.
- Decodes the “raw” NES palette (even if you choose not to use GTU-famicom), and corrects Genesis Plus GX’s colors. BlastEm doesn’t need this correction, so there is an option to disable it. If you want to use a pre-made NES palette without having GTU-famicom’s artifacts, this shader is not what you want, so I instead recommend using one of the shaders by Retro Crisis or Cyber. The Genesis color correction is from Grade, based on the values found in BlastEm. The NES decoding is adapted from GTU-famicom with updated constants from nesdev.
- This one defeats the whole purpose of the shader pack, but if anyone insists on hardcoding their NES palette: By following these instructions, NES palettes can now be used with GTU-famicom. To do this, you still set Mesen’s palette to “Raw”, and install your palette into scaleX-nes-palette-selectable.slang. The FCEUX, YUV, PlayChoice-10, and AspiringSquire’s Reality A (not the same as in FCEUmm or Mesen) palettes are already installed for you. To use another palette, you will have to replace one of those palettes that are already in there, by converting the first 192 bytes of the palette’s .pal file into an array of 192 floats from 0.0 to 1.0. I will make a simple script for you to do this soon, but for now, you’ll have to write such a script yourself, or have ChatGPT or something write the script for you. Once that’s all set, you should pick one of the two “trolling-raw-palette-mesen” shaders.
- Built-in test patterns: Standard color bars; color ramps; full HSV image; full HSV image with key areas widened; full NES raw palette.
- As a joke, you can use NES palettes on the Genesis and other consoles, but this is not meant to be used seriously. You can use it to insult the games that you don’t like. Use the shaders “trolling-genesis” and “trolling-universal” for this. You can use the same instructions as above to change the palettes.
Screenshots (Sorry about the JPEG compression)
(Note: Some of these screenshots might have different settings than the presets I’ve included here.)
Rocket Knight Adventures (JP first, US second. The difference is easier to see if you open each image in a new tab and keep switching between the tabs. Both are at a white point of D65, which I’ve since changed to 9300K and D75 respectively. I plan to change the 9300K to something around 8500K eventually.) Note: If your rainbows are more spread apart than this, that means you are cropping horizontal overscan. The Genesis Plus GX emulator’s settings can be changed to not crop overscan.
Battletoads (This is not a joke!!! JP first, US second. Clearly, this was made with PAL colors in mind, because if you adjust your hue to fix this ground to become green, the bottom half of the title becomes cyan. Both are in D65, like before.)
Sparkster on Genesis. Because I can’t stand playing this game, I decided to upload fake screenshots of it on purpose. I had the shader convert the RGB into YIQ and use the FCEUX and PC-10 palettes to decode it. It’s bizzare how decoding things using an NES palette as a reference still results in something close to the original image. FCEUX keeps turning all the blue skies purple and all the magenta or orange things more red, while PC-10 makes all the bright orange things straight up yellow.
This is a fake image. I converted each pixel into YIQ, and I reversed the YIQ pack into the NES palette, using the NES palette like a lookup table. Only the shaders that have “trolling” in the title are using an NES palette to decode color, so as long as you don’t pick those, you’ll have real colors.