Question

I'm doing a color lookup using a texture to apply an effect to a picture. My lookup is a gradient map using the luminance of the fragment of the first texture, then looking that up on a second texture. The 2nd texture is 256x256 with gradients going horizontally and several different gradients top to bottom. So 32 horizontal stripes each 8 pixels tall. My lookup on the x is the luminance, on the y it's a gradient and I target the center of the stripe to avoid crossover.

My fragment shader looks like this:

 lowp vec4 source = texture2D(u_textureSampler, v_fragmentTexCoord0);
 float luminance = 1.0 - dot(source.rgb, W);
 lowp vec2 texPos;
 texPos.x = clamp(luminance, 0.0, 1.0);
 // the y value selects which gradient to use by supplying a T value
 // this would be more efficient in the vertex shader
 texPos.y = clamp(u_value4, 0.0, 1.0);

 lowp vec4 newColor1 = texture2D(u_textureSampler2, texPos);

It works good but I was getting distortion in the whitest parts of the whites and the blackest part of the blacks. Basically it looked like it grabbed that newColor from a completely different place on texture2, or possibly was just getting nothing for those fragments. I added the clamps in the shader to try to keep it from getting outside the edge of the lookup texture but that didn't help. Am I not using clamp correctly?

Finally I considered that it might have something to do with my source texture or the way it's loaded. I ended up fixing it by adding:

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

So.. WHY?

It's a little annoying to have to clamp the textures because it means I have to write an exception in my code when I'm loading lookup tables..

If my textPos.x and .y are clamped to 0-1.. how is it pulling a sample beyond the edge?

Also.. do I have to use the above clamp call when creating the texture or can I call it when I'm about to use the texture?

Was it helpful?

Solution

This is correct behavior of texture sampler.

Let me explain this. When you use textures with GL_LINEAR sampling GPU will take an average color of pixel blended with nearby pixels (that's why you don't see pixelation as with GL_NEAREST mode - pixels are blurred instead). And with GL_REPEAT mode texture coordinates will wrap from 0 to 1 and vice versa, blending with nearby pixels (i.e. in extreme coordinates it will blend with opposite side of texture). GL_CLAMP_TO_EDGE prevents this wrapping behavior, and pixels won't blend with pixels from opposite side of texture.

Hope my explanation is clear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top