I\'m using (Py)OpenGL to display 256 colors indexed images. I use a shader together with a 1D texture containing the palette. Here\'s the Fragment shader code :
GL_CLAMP_TO_EDGE
for your texture's GL_TEXTURE_WRAP_S
.This problem is occurring partly because the texture coordinate 1.0 references a location that is beyond the last texel's center. Clamp to edge will make it so that your coordinates are clamped to the centers of the edge texels in the S
direction.
When textures are sampled, if a coordinate does not refer to an exact texel center then the filter mode and wrap behavior will dictate where the texel(s) are fetched from. By default OpenGL uses a repeat mode, so the nearest neighbor (closest texel center) to a texture coordinate close to 1.0 may come from the other side of your texture (repeat). With ordinary images you might not even notice this behavior, but when you wrap around to the other side of a lookup table the discontinuity can be very obvious.
http://i.msdn.microsoft.com/dynimg/IC83860.gif
Notice how texture coordinate 1.0 actually refers to the boundary between palette entry 3 and 0?
The short version is if your range is from 0.0 to 1.0 then none of your texture coordinates are referencing texel centers and you can easily wind up sampling the wrong texel. You need to adjust your coordinates so that you are not using the texel boundary for each palette entry.
texelFetch (...)
and skip all of this normalized texture coordinate nonsense altogether. If you want to get the palette entry for your texture using its a
component, then try something like this:
gl_FragColor = texelFetch (palette, (int)(texture2D (texture, uv).a * 255.0), 0);
This will explicitly fetch the texel given by the integer index. You do not have to worry about nearest neighbor(s), wrap modes, filtering, etc.