Well, gamma can be a bit tricky sometimes.
On CRTs, it works very well. You set 2.4 as the input and 2.2 as the output, and voilà , the colors pop beautifully!
However, when you try the same approach on non-CRT shaders, it messes everything up, creating an overblown, overly saturated, and bland image.
This has always intrigued me, so I decided to dig deeper and understand what’s going on under the hood.
One thing about CRTs is that the scanlines hide the gamma effect in the vertical dimension. It’s almost like the image is one-dimensional—horizontal only. Gamma correction is known for increasing brightness in lighter areas more than in darker ones. On CRTs, this effect is mostly noticeable in the horizontal dimension.
Take a look at the image below of crt-geom . See the dithering pattern on the US flag? The white squares become rectangles after gamma correction:
Now, if we apply cubic gamma correction to the same source, we get this:
See how everything is overblown! The white spots invade the darker ones in all directions, making the final image a mess.
If we disable gamma correction and revert to gamma 1.0 (uncorrected), we get this:
Everything is back to “normal”—at least what we’ve considered normal until now. We’ve avoided linear gamma on non-CRT shaders because it looks awful. So, we’ve stuck with uncorrected gamma. But look again at the last image and notice how the dithering pattern is isometric again—every dot is square. The overall image looks more regular, though bland compared to the CRT (with gamma correction).
I think you’ve already figured out the solution, right? Yes! In non-CRT shaders, we should only apply gamma correction when filtering horizontally ! We should skip linear gamma when filtering vertically. (We’ve been wrong for so long…)
So, I present to you the first Catmull-Rom filter with correct linear gamma (applied only horizontally):
It’s using the same input of 2.4 and output of 2.2 as CRT-geom. Now compare the flags and all the image details with the CRT version and see how it’s finally accurate! And the colors are just as beautiful as the CRT’s!
Here are some shaders I’ve converted to this approach, in case you’d like to test them on RetroArch:
Some shaders gamma-corrected (now truly correct!)
An important caveat: this approach is specific to content made to run at 240p on CRTs. It’s not a general thing that can be applied to any image. It’s a particular characteristic of games made for CRTs!
I don’t know how well this could work with images made for modern devices or even 480i/p content made for CRTs.
Let me know your opinion!
Other screenshots: