2

I am currently trying to write a simple outline shader in glsl (using SFML). I am new to shader programing so forgive me if the question is obvious. Anyway, the shader works fine for detecting edges within the texture but fails to detect the borders at the edge of a texture.

Picture of the working outlineShader
Picture of the working outlineShader

Picture of the outline shader not working correctly
Picture of the outline shader not working correctly

Here is the code of my fragment shader (I only have a 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;
}

So essentially what I am looking for is a way to determin whether the neighbouring pixel still belongs to the texture or not.

BTW: Since gl_TexCoord[0].xy appears to be depricated after shadermodel #version 120, an alternative would be much appreciated.

Thanks for Your help,

Adrian

alseether
  • 1,889
  • 2
  • 24
  • 39

1 Answers1

0

Have you tried to sample 8 texels? It looks like your kernel is imperfect for the some cases.

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)

// ...
  • Yeah, that was my first try. I found a workaround by drawing on a larger (transparrent) render texture first and then applying that shader to the renderTexture. It works since the edges are no longer at the edge of the texture but tanks performance by quite a bit. Thanks for replying tho ^^ – Adrian Albert Koch Oct 27 '17 at 16:57