web-dev-qa-db-fra.com

Comment obtenir des informations sur les pixels dans un fragment shader?

Dans mon fragment shader, je peux charger une texture, puis procédez comme suit:

uniform sampler2D tex;

void main(void) {
   vec4 color = texture2D(tex, gl_TexCoord[0].st);
   gl_FragColor = color;
}

Cela définit le pixel actuel sur la valeur de couleur de la texture. Je peux les modifier, etc. et cela fonctionne bien.

Mais quelques questions. Comment dire "quel" pixel je suis? Par exemple, supposons que je souhaite définir le pixel 100 100 (x, y) sur le rouge. Tout le reste au noir. Comment puis-je faire un:

"if currentSelf.Position () == (100,100); then color = red; sinon color = black?"

?

Je sais comment définir les couleurs, mais comment puis-je obtenir "mon" emplacement?

Deuxièmement, comment puis-je obtenir les valeurs d'un pixel voisin?

J'ai essayé ceci:

vec4 nextColor = texture2D(tex, gl_TexCoord[1].st);

Mais pas clair ce qu'il revient? si je suis pixel 100,100; Comment puis-je obtenir les valeurs de 101,100 ou 100,101?

24
user697111

Comment dire "quel" pixel je suis?

Tu n'es pas un pixel. Vous êtes un fragment . Il y a une raison pour laquelle OpenGL les appelle "shaders de fragments"; c'est parce qu'ils ne sont pas des pixels encore . En effet, non seulement ils ne peuvent jamais devenir des pixels (via discard, des tests de profondeur ou autre), mais, grâce au multi-échantillonnage, plusieurs fragments peuvent être combinés pour former un single pixel.

Si vous voulez savoir où se trouve votre fragment shader dans l'espace-fenêtre, utilisez gl_FragCoord . Les positions de fragment sont des valeurs à virgule flottante et non des nombres entiers. Vous devez donc tester avec une plage au lieu d'une valeur unique "100, 100".

Deuxièmement, comment puis-je obtenir les valeurs d'un pixel voisin?

Si vous parlez du pixel de framebuffer voisin, vous notez . Les shaders de fragments ne peuvent pas lire de manière arbitraire dans le framebuffer, ni dans leur propre position, ni dans une position voisine.

Si vous parlez d'accéder à un Texel voisin depuis celui auquel vous avez accédé, il ne vous reste plus qu'à biaiser la coordonnée de texture que vous passez à texture2D. Vous devez obtenir la taille de la texture (puisque vous n'utilisez pas GLSL 1.30 ou supérieur, vous devez l'insérer manuellement), inversez la taille et ajoutez ou soustrayez ces tailles des composants S et T de la coordonnée de texture. .

29
Nicol Bolas

Peasy facile.

Il suffit de calculer la taille d'un pixel en fonction de la résolution. Ensuite, cherchez +1 et -1.

vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;
gl_FragColor = (
   texture2D(u_image, v_texCoord) +
   texture2D(u_image, v_texCoord + vec2(onePixel.x, 0.0)) +
   texture2D(u_image, v_texCoord + vec2(-onePixel.x, 0.0))) / 3.0;

Il y a un bon exemple ici

1
newshorts