# Sobel edge detection line thickness

My goal is to implement an edge detection algorithmus that is capable to find edges of arbitrary 3d meshes. I want to find the edges by detecting normal discontinuities. Furthermore, I want the edges to be one pixel wide.

I render the color values of my scene and the corresponding normal vectors to two different render buffer targets, i.e. to two different textures (screenTexture and normalTexture). I use the sobel edge detection algorithmus in my fragment shader:

#version 330 core

out vec4 color;

uniform sampler2D screenTexture;
uniform sampler2D normalTexture;
uniform sampler2D depthTexture;

mat3 sx = mat3(
1.0, 2.0, 1.0,
0.0, 0.0, 0.0,
-1.0, -2.0, -1.0
);
mat3 sy = mat3(
1.0, 0.0, -1.0,
2.0, 0.0, -2.0,
1.0, 0.0, -1.0
);

void main()
{
vec4 diffuse = texelFetch(screenTexture, ivec2(gl_FragCoord), 0);
vec3 normal = texelFetch(normalTexture, ivec2(gl_FragCoord), 0 ).xyz;
vec3 I[3];
for (int i=0; i<3; i++) {
float sampleValLeft  = dot(normal, texelFetch(normalTexture, ivec2(gl_FragCoord) + ivec2(i-1,-1), 0 ).rgb);
float sampleValMiddle  = dot(normal, texelFetch(normalTexture, ivec2(gl_FragCoord) + ivec2(i-1,0), 0 ).rgb);
float sampleValRight  = dot(normal, texelFetch(normalTexture, ivec2(gl_FragCoord) + ivec2(i-1,1), 0 ).rgb);
I[i] = vec3(sampleValLeft, sampleValMiddle, sampleValRight);
}

float gx = dot(sx[0], I[0]) + dot(sx[1], I[1]) + dot(sx[2], I[2]);
float gy = dot(sy[0], I[0]) + dot(sy[1], I[1]) + dot(sy[2], I[2]);

float g = sqrt(pow(gx, 2.0)+pow(gy, 2.0));
g = smoothstep(0.4,0.8, g);

if(g > 0.2) {
color = vec4(0., 0., 0.0, 1);
} else {
color = diffuse;
}
}


The shader produces the following result:

As you can see, the line thickness of the solids are not consistent:

1. Edges visible between the turquois background and the solid are 1px wide like intended.
2. Edges within the object are 2px wide which is too bride.

The reason why 1. works is because I initalized normalTexture with vec3(0,0,0) normal vectors which produces a dot-product of 0 as soon as the current pixel is a scene pixel and the adjacent right or left pixel is an edge pixel of the solid.

But edges within the object are detected two times by sobel because of a gx or gy which is one time positive and one time negative. In other words, gx or gy is both times not 0 and therefore g is greater than 0.2 both of the time.

I'm totally stuck what I can do to produce consistent wide lines.