# Is it reasonable to use a 2D texture as a lookup table in GLSL

I need a lookup table in a shader. The input values would be color values and the output other color values. Something like:

uniform float lut[256];

color = vec3(lut[int(color.r*255.)], lut[int(color.g*255.)], lut[int(color.b*255)]);


does what I need but certain implementations of OpenGL ES do not allow arrays with variable indexing so finally I've arrived to the conclusion that the most portable way is to have a 2D texture as the LUT. A texture of 256x256 could store many different lookup tables, each one (256 entries) in a single row.

In order to load a row in the texture (c++) I would use:

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);


to store a table in the first row (I assume that internally in the texture I'd have the value repeated in R, G and B)

To fetch the LUT in the fragment shader I'd use texture2D(lut,vec2(index, constRow)) (index in the range 0-1 and constRow = 0 being the row in the texture where it is stored the lut).

Is that a reasonable way to implement that?

Update: In order to fetch values in the texture-LUT you need normalized indexes (0.0-1.0), so to access row 7 I have to index it as texture2D(lut, vec2(index, 7./255.)); From what I see the result is (or may be) an interpolation with the two other consecutive rows.

• Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. – Kromster Sep 1 '14 at 17:04
• Sorry for the fuzzy question. I've edited it, hopefully it's clear now. – Joan Sep 1 '14 at 18:14
• If everything works, then what is the problem that you are facing? GDSE is not a "review my solution" kind of place. It's more like a QA ;) – Kromster Sep 2 '14 at 5:39
• I was asking for the case someone addressed the same problem with a different aproach (I though the problem posed was quite frequent). So far my solution is not as simple to implement as one would say at first sight, at least for me. – Joan Sep 2 '14 at 10:10
• Have you tried setting the texture sampling to GL_NEAREST for the texture? You just want to explicitly disable the bilinear filtering – Steven Lu Sep 2 '14 at 15:00

Therefore, the integer pixel coordinate (i,j) is located at the normalized coordinate ((i+0.5)/W, (j+0.5)/W).