CRT Color Correction 3DLUTs (Sony, Mitsubishi, CTX, NEC, Hyundai)

Here are several 3DLUTs in 16px and 32px PNGs to use with the current LUT shader. They’re created from official color profiles distributed with CRT monitor drivers, and one I modified personally to better match physical art to games.!Qxdj3YDT!N8P6cZ-ll91249JeYm6_jfGaWkkfwYJWmbStBxoo7yY

The CRT monitors are:

  • Hyundai ImageQuest V700+
  • NEC MultiSync FE990
  • Mitsubishi Diamond Pro 750SB
  • Mitsubishi Diamond Pro 920
  • Mitsubishi Diamond Plus 230SB
  • CTX T-Group
  • CTX PFS-Group
  • CTX D-Group
  • Sony Trinitron Std
  • Sony Trinitron Edit 1

Sony Trinitron Edit 1 had its gamma adjustment removed, it was white balanced, and the colors were pushed more toward matching physical art to games. Due to the gamma adjustment removal you’ll need to adjust the gamma yourself, it would have been set to appear as 2.5.

Here’s an Imgur album of a collage of screenshots run through each 3DLUT, some with an additional image with gamma adjustment. I believe they’re all named correctly.


Could you explain how to use and swap out these LUTs I’ve yet to use LUTs?

I’m not understanding exactly what is being shown here. What is a LUT? or where can I learn more?

1 Like

My understanding is that it’s color correction via an image (LUTs)? This may be completely wrong though.

Yes, LUT stands for “look-up texture” (or “look-up table” in other contexts), and we can use it to store a bunch of color data in an image instead of a bunch of numbers. A specially crafted shader can then decode the information and apply the appropriate transformations to the image.

I wrote a tutorial on how to make the LUTs here:

In this case, though, you’re not trying to create a LUT, but just apply it to an image, which is a little different. If you open up the LUT shader preset, you’ll see a line that points to an image:

SamplerLUT = shaders/LUT/16.png

That’s the line that tells the shader which LUT to apply. If you change that path to point to one of torridgristle’s LUTs, it’ll apply it instead. The only other thing to know is that the LUTs are designed for a specific color depth. The shader’s default is 16-bit color, but some (most? all?) of torridgristle’s are 32-bit, so you also need to increase the depth parameter (called “LUT Size” in the shader) to 32 to match (this can also be set in the preset for convenience).

You’ll know you need to change the parameter if your colors are straight-up crazy, like blues are orange, etc.


3DLUTs work by taking an input RGB value, like #6412A4, and using the 3 RGB values as coordinates in a cube of data. The number at (64,12,A4) is the resulting value. This allows you to store complex color manipulations without needing to do the math each time, instead just recording what almost every color would turn into when manipulated.

Imagine a graph of a curve. You can look up an input number X and read what the output number Y is without knowing the math that went into making the curve. It’s like this with more dimensions.


Sorry to take up more of your time but if I wanted to use a lut in a crt shader chain where would it go in the chain before or after a crt shader?

You typically want to put it before the CRT pass(es). This is usually the case for color-changing shaders and/or signal emulation (like NTSC or PAL).

1 Like

@hunterk Is it possible that you add those LUTs in libretro shaders repo ? ( reshade\shaders\LUT ), it would be a shame to miss out. Thanks :slight_smile:


Shouldn’t the RGB phosphors also be mapped? I’m using lut.glsl to remap to my calibrated display profile but doesn’t work, only when stacked at the very beginning.

shader14 = "..\..\shaders_slang\crt\shaders\crt-royale\src\crt-royale-geometry-aa-last-pass.slang"
filter_linear14 = "true"
wrap_mode14 = "clamp_to_border"
mipmap_input14 = "true"
alias14 = ""
float_framebuffer14 = "false"
srgb_framebuffer14 = "false"
scale_type_x14 = "viewport"
scale_x14 = "1.000000"
scale_type_y14 = "viewport"
scale_y14 = "1.000000"
shader15 = "..\..\shaders_glsl\reshade\shaders\LUT\LUT.slang"
filter_linear15 = "false"
wrap_mode15 = "clamp_to_border"
mipmap_input15 = "false"
alias15 = ""
float_framebuffer15 = "false"
srgb_framebuffer15 = "false"
scale_type_x15 = "source"
scale_x15 = "1.000000"
scale_type_y15 = "source"
scale_y15 = "1.000000"

If you want the phosphors corrected, too, I would suggest applying the LUT in Photoshop or whatever and then save over the existing phosphor images.

1 Like