Not sure if there is already a snippet for this, however I didn’t find one, so I’ll just post my code
vec3 applyColorLUT(sampler2D lut, vec3 color) {
float lutSize = float(textureSize(lut, 0).y);
color = clamp(color, vec3(0.5 / lutSize), vec3(1.0 - 0.5 / lutSize));
vec2 texcXY = vec2(color.r / lutSize, 1.0 - color.g);
int frameZ = int(color.b * lutSize);
float offsZ = fract(color.b * lutSize);
vec3 sample1 = textureLod(lut, texcXY + vec2(frameZ / lutSize, 0), 0).rgb;
vec3 sample2 = textureLod(lut, texcXY + vec2( (frameZ + 1) / lutSize, 0), 0).rgb;
return mix(sample1, sample2, offsZ);
}
Usage:
correctedColor = applyColorLUT(myLUTSampler, color);
You can generate the default Color-LUT with this script:
from __future__ import division, print_function
import math
from panda3d.core import PNMImage
lut_size = 64
lut_cols = lut_size
lut_rows = (lut_size + lut_cols - 1) // lut_cols
img = PNMImage(lut_size * lut_cols, lut_size * lut_rows, 3, 2**16 - 1)
def to_linear(v):
return float(v) / float(lut_size-1)
for r in range(lut_size):
for g in range(lut_size):
for b in range(lut_size):
slice_offset_x = (b % lut_cols) * lut_size
slice_offset_y = (b // lut_cols) * lut_size
img.set_xel(r + slice_offset_x, g + slice_offset_y,
to_linear(r), to_linear(g), to_linear(b))
img.write("DefaultLUT.png")
The bigger the lut size is, the more precise the result will be. You should set WMClamp on the LUT-Texture, and also set the format to F_rgb16.