From the start of this thread to the present, I’ve been using a different LUT sampler shader from the one in RetroArch. The one I’m using is by ChthonVII, and here’s what the comments in it say:
// retroarch can't correctly sample a 1.0 coordinate
// so we are going to add a just-under-half-step offset to red and green, then increase their divisors by 1
// This should get us a slightly lower coordinate within the same pixel
// This is where reshade's LUT is slightly inaccurate because it's taking a linearly filtered sample from the wrong spot.
In their shader, I also added an extra line of code towards the beginning of the shader to clamp the input RGB values between 0.0 and 1.0. Values out of those bounds cause the result to become a (0, 0, 0) black.
For convenience, here’s a link to the most recent batch of 128x128x128 LUTs I posted that were generated by gamutthingy, which comes with a slightly modified version of Chthon’s trilinearLUT.slang. https://drive.google.com/file/d/1aXmnEsUdW4xDNqliGdhQC2xAsQ6wH8T5/view
…unless you include the two hours it took for my lazy implementation to complete the 8 LUTs in my last post. ChthonVII’s can complete a LUT in a few seconds. The culprit is a 100000-iteration for-loop to brute-force search the closest valid in-gamut color for out-of-gamut colors.
Because 32x32x32 is such a low resolution, it’s better for you to only apply the LUT in a way that converts from some linearized colors to some other linearized colors, or I guess, from one gamma to the same gamma might also give decent results. Since ChthonVII couldn’t figure out how to put a 256x256x256 LUT into RetroArch, they had to create a solution for this problem already, by adding the option --lutmode postgammaunlimited. It’s then the shader’s responsibility to perform the NTSC/PAL color corrective matrix, the CRT EOTF, and the sRGB OETF. The LUT is applied between the CRT EOTF and sRGB OETF steps.
For your convenience, though, I’ve just generated these LUTs to include the NTSC/PAL corrective matrix, the CRT EOTF, and the sRGB OETF for you, so that all you need to do is apply the LUT just like you’re used to doing. Ones that say “gamutthingy” are by ChthonVII’s program which I’ve linked in this thread half a million times. The other ones are by my LUT generator, which took about 24 minutes total to complete all eight LUTs. https://drive.google.com/file/d/11hCmww0f9YH_s-_xmhdxpHK-J3-eWZ3-/view
As I’ve stated in my previous post, my new non-gamutthingy LUTs should only be used in games that have sparse color palettes, since mine will cause some colors to become equal to each other when real hardware doesn’t make them equal to each other. If you need to preserve gradients or preserve the differences between colors that are closer to each other, you should use the LUTs from gamutthingy.
I’ll come back here later and post some that don’t include the NTSC/PAL color correction, since that’s skipped on YPbPr and RGB connections.
Click here for the commands I input into gamutthingy to generate the LUTs.
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod panasonic_CT36D30B --crt-saturation-knob 0.95 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_panasonic_CT36D30B --source-whitepoint D65 --no-source-adapt true --outfile panasonic_CT36D30B_gamutthingy_res64_2026-10-31.png
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod TA7644BP --crt-saturation-knob 1.1 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_toshiba_blackstripe_patchy68k --source-whitepoint 9300K27mpcd --no-source-adapt true --outfile toshiba_CF2005_gamutthingy_res64_2026-10-31.png
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod rca_colortrak --crt-saturation-knob 1.2 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_rca_colortrak_patchy68k --source-whitepoint customcoord --source-whitepoint-custom-coords 0.294,0.309 --no-source-adapt true --outfile rca_e13169gm-f02_gamutthingy_res64_2026-10-31.png
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod CXA1870S_JP --crt-saturation-knob 1.2 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_trinitron_bohnsack --source-whitepoint 9300K27mpcd --no-source-adapt true --outfile sony_CXA1870S_JP_gamutthingy_res64_2026-10-31.png
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod CXA1870S_US --crt-saturation-knob 1.2 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_trinitron_bohnsack --source-whitepoint 9300K27mpcd --no-source-adapt true --outfile sony_CXA1870S_US_gamutthingy_res64_2026-10-31.png
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod CXA2060BS_US --crt-saturation-knob 1.0 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_trinitron_bohnsack --source-whitepoint D65 --no-source-adapt true --outfile sony_CXA2060BS_US_gamutthingy_res64_2026-10-31.png
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod CXA2060BS_JP --crt-saturation-knob 1.0 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_trinitron_bohnsack --source-whitepoint 9300K8mpcd --no-source-adapt true --outfile sony_CXA2060BS_JP_gamutthingy_res64_2026-10-31.png
build/gamutthingy --lutgen true --lutsize 64 --crtemu front --crtdemod CXA2060BS_PAL --crt-saturation-knob 1.0 --crtclamphighenable false --crtblack 0.0023384888513 --crtwhite 1.34273107128 --source-primaries P22_trinitron_bohnsack --source-whitepoint D65 --no-source-adapt true --outfile sony_CXA2060BS_PAL_gamutthingy_res64_2026-10-31.png