2013-09-23 1 views
0

Je fais une recherche de couleur en utilisant une texture pour appliquer un effet à une image. Ma recherche est une carte de dégradés utilisant la luminance du fragment de la première texture, puis la recherche d'une seconde texture. La deuxième texture est 256x256 avec des gradients allant horizontalement et plusieurs gradients différents de haut en bas. Donc 32 bandes horizontales de 8 pixels chacune. Ma recherche sur le x est la luminance, sur le y c'est un dégradé et je cible le centre de la bande pour éviter le crossover.Pourquoi une coordonnée de texture de 1.0 dépasse-t-elle le bord de la texture?

Mon fragment shader ressemble à ceci:

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

Il fonctionne bien, mais je recevais une distorsion dans les parties des blancs plus blancs et la partie des blackest noirs. Fondamentalement, il a semblé qu'il a attrapé newColor à partir d'un endroit complètement différent sur texture2, ou peut-être ne recevait rien pour ces fragments. J'ai ajouté les pinces dans le shader pour essayer de l'empêcher de sortir du bord de la texture de recherche, mais cela n'a pas aidé. Est-ce que je n'utilise pas la pince correctement?

Finalement, j'ai considéré que cela pouvait avoir quelque chose à voir avec la texture de ma source ou la manière dont elle est chargée. J'ai fini par le fixer en ajoutant:

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

Alors .. POURQUOI?

Il est un peu ennuyeux d'avoir à serrer les textures, car cela signifie que je dois écrire une exception dans mon code quand je suis chargement de tables de consultation ..

Si mon textPos.x et .y sont serrés à 0-1 .. comment tire-t-il un échantillon au-delà du bord?

Aussi ... dois-je utiliser l'appel de pince ci-dessus lors de la création de la texture ou puis-je l'appeler lorsque je suis sur le point d'utiliser la texture?

Répondre

3

Ceci est le comportement correct de l'échantillonneur de texture.

Laissez-moi vous expliquer cela. Lorsque vous utilisez des textures avec GL_LINEAR, le GPU d'échantillonnage prendra une couleur moyenne de pixels mélangés avec des pixels proches (c'est pourquoi vous ne voyez pas la pixellisation comme avec le mode GL_NEAREST - les pixels sont flous à la place). Et avec GL_REPEAT, les coordonnées de texture de mode s'enrouleront de 0 à 1 et vice versa, en se fondant avec des pixels proches (c'est-à-dire en coordonnées extrêmes, elles se fondront avec le côté opposé de la texture). GL_CLAMP_TO_EDGE empêche ce comportement d'habillage, et les pixels ne se fondent pas avec les pixels du côté opposé de la texture.

J'espère que mon explication est claire.

+0

Il est donc impossible de bloquer dans le shader alors si vous êtes dans GL_LINEAR? Il doit être serré avec l'appel opengl? Qu'en est-il de cet appel glTexParameteri? Peut-il être fait lorsque vous liez la texture pour l'utiliser ou doit-il être fait lorsque vous chargez la texture? – badweasel

+0

@badweasel Vous pouvez *** mettre en œuvre le serrage dans le shader, ce que 'GL_CLAMP_TO_EDGE' * fait * fait est de restreindre la plage de coordonnées à [0 + 0.5/texSize, 1-0.5/texSize]. Ceci provoque un échantillonnage au centre du texel *** exact ***, de sorte qu'une interpolation utilisant des texels voisins ne se produit jamais. –

+0

@badweasel Cette garantie spéciale ne s'applique bien sûr qu'à l'échantillonnage des texels de bord, d'où le nom. –