2017-10-19 11 views
1

J'essaie actuellement d'écrire un simple shader de contour dans glsl (en utilisant SFML). Je suis nouveau à la programmation shader alors pardonnez-moi si la question est évidente. Quoi qu'il en soit, le shader fonctionne correctement pour détecter les arêtes dans la texture, mais ne parvient pas à détecter les bordures au bord d'une texture.Comment puis-je vérifier si un fragment se trouve sur le bord d'une texture?

Image du travail outlineShader
Picture of the working outlineShader

Image du shader contour ne fonctionne pas correctement
Picture of the outline shader not working correctly

Voici le code de mon shader fragment (j'ai seulement un fragment shader)

uniform sampler2D texture; 
uniform float outlineThickness; 
uniform vec2 textureSize; 
uniform vec3 outlineColor; 

void main() 
{ 
    vec2 offx = vec2(outlineThickness/textureSize.x, 0.0); 
    vec2 offy = vec2(0.0, outlineThickness/textureSize.y); 

    float surroundingAlphaSum = texture2D(texture, gl_TexCoord[0].xy + offx).a + 
     texture2D(texture, gl_TexCoord[0].xy - offx).a + 
     texture2D(texture, gl_TexCoord[0].xy + offy).a + 
     texture2D(texture, gl_TexCoord[0].xy - offy).a; 

    // This pixel 
    vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); 

    // If one of the surrounding pixels is transparrent --> an edge is detected 
    if (4.0 * pixel.a - surroundingAlphaSum > 0.0) 
    pixel = vec4(outlineColor, 1.0); 
    else 
    pixel = vec4(0.0); // transparrent 

    gl_FragColor = pixel * gl_Color; 
} 

Donc, essentiellement, ce que je cherche est un moyen de déterminer si le pixel voisin appartient toujours à la texture ou non.

BTW: Depuis gl_TexCoord[0].xy semble être déprimé après shadermodel #version 120, une alternative serait très appréciée.

Merci pour votre aide,

Adrian

Répondre

0

Il y a plusieurs façons de detect edges. Malheureusement, je viens de travailler avec eux dans Matlab, mais peut-être que le lien vous aide à mettre en œuvre certaines fonctions.

par mon expérience passée, vous devez travailler avec des matrices qui contient l'image, puis, créer une matrice supplémentaire où vous calculer pour chaque pixel si elle est un bord ou non, avec 0 ou 1.

0

Avez-vous essayé échantillonner 8 texels? Il semble que votre noyau soit imparfait pour certains cas.

float surroundingAlphaSum = texture2D(texture, gl_TexCoord[0].xy + offx).a + 
    texture2D(texture, gl_TexCoord[0].xy - offx).a + 
    texture2D(texture, gl_TexCoord[0].xy + offy).a + 
    texture2D(texture, gl_TexCoord[0].xy - offy).a + 
    texture2D(texture, gl_TexCoord[0].xy + offx + offy).a + 
    texture2D(texture, gl_TexCoord[0].xy + offx - offy).a + 
    texture2D(texture, gl_TexCoord[0].xy - offx + offy).a + 
    texture2D(texture, gl_TexCoord[0].xy - offx - offy).a; 

// ... 

if (8.0 * pixel.a - surroundingAlphaSum > 0.0) 

// ... 
+0

Oui, c'était mon premier essai. J'ai trouvé une solution de contournement en tirant d'abord sur une texture de rendu plus grande (transparente), puis en appliquant ce shader à renderTexture. Cela fonctionne car les arêtes ne sont plus au bord de la texture mais les performances des cuves sont assez importantes. Merci d'avoir répondu –