2013-09-23 76 views
0

我正在使用纹理进行颜色查找以将效果应用于图片。我的查找是使用第一个纹理片段的亮度的梯度图,然后在第二个纹理上查看。第二个纹理是256x256,水平渐变和几个不同的渐变从上到下。所以32个水平条纹每8个像素高。我在x上的查找是亮度,在y上它是一个渐变,我瞄准条纹的中心以避免交叉。为什么1.0的纹理坐标超出纹理边缘?

我的片段着色器看起来是这样的:

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); 

它的工作不错,但我是在白人和黑人的最黑暗部分的白的部分越来越失真。基本上,它看起来像从texture2上完全不同的地方抓取了newColor,或者可能只是没有为这些片段获得任何东西。我在着色器中添加了夹具以尽量避免出现在查找纹理的边缘之外,但这没有帮助。我没有正确使用夹子吗?

最后我认为它可能与我的源纹理或它的加载方式有关。我结束了通过增加修复它:

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

所以..为什么?

这是一个有点恼人必须夹紧纹理,因为这意味着我必须写一个例外,在我的代码,当我加载查找表..

如果我textPos.x和.Y被锁定到0-1 ..它如何将样本拉出边缘?

另外..当我要使用纹理时,是否必须在创建纹理时使用上述的钳位调用,还是可以调用它?

回答

3

这是纹理采样器的正确行为。

让我来解释一下。当您使用GL_LINEAR采样纹理时,GPU将采用与附近像素混合的像素的平均颜色(这就是为什么像GL_NEAREST模式那样看不到像素化 - 反而像素模糊)。 和GL_REPEAT模式纹理坐标将从0到1,反之亦然,与相邻像素混合(即在极端坐标中,它将与纹理的相反侧混合)。 GL_CLAMP_TO_EDGE可以防止这种包装行为,并且像素不会与纹理反面的像素混合。

希望我的解释清楚。

+0

因此,如果您在GL_LINEAR中,那么无法在着色器中进行调整?它必须用opengl调用进行钳制? 那个glTexParameteri调用呢?可以在绑定纹理时使用它,还是在加载纹理时必须完成? – badweasel

+0

@badweasel您可以***在着色器中实现钳位,实际上'GL_CLAMP_TO_EDGE' * *所做的操作是将坐标范围限制为[0 + 0.5/texSize,1-0.5/texSize]。这导致在***确切*** texel中心采样,以便从不出现使用相邻纹素的插值。 –

+0

@badweasel这个特殊保证当然只适用于采样边缘纹理元素,因此名称。 –