Geom shader clipping issue - need help

Hey guys.

So I got wide lines /almost/ working in my core profile program. I followed the example here opengl - Wide lines in geometry shader behaves oddly - Stack Overflow
and ran into the exact same guy the issue has there. Oddly enough, this post is the best example of how to do this that I could find anywhere.

Can someone please answer both me and him, why is this clipping problem happening? And what can i do efficiently in my GS to fix it?

Below in my code, the problem occurs when the ‘bad’ boolean evaluates to true. Using my fixVertex function doesn’t help.



#ifdef GL_ES
//precision mediump float;
#else
#define highp
#define lowp
#define mediump
#endif


uniform vec2 renderTargetSize;
uniform vec4 solidColor;
uniform mat4 modelViewProjectionMatrix;
uniform float lineThickness;


in vec4 vtxColor[2];


flat out vec4 varColor;


layout (lines) in;
layout (triangle_strip, max_vertices = 4) out;


vec3 fixVertex(vec3 vert)
{
  //seems like I need to manually clip the lines, otherwise I end up with incorrect lines running across the entire screen
  vert.z = clamp(vert.z, 0.0, 1.0);
  return vert;
}


void main()
{
  vec3 ndc0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w;
  vec3 ndc1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w;
  bool bad = (ndc0.z > 1.0 || ndc1.z > 1.0);
  
  //ndc0 = fixVertex(ndc0);
  //ndc1 = fixVertex(ndc1);
  
  vec2 lineScreenForward = normalize(ndc1.xy - ndc0.xy);
  vec2 lineScreenRight = vec2(-lineScreenForward.y, lineScreenForward.x);
  vec2 lineScreenOffset = (vec2(lineThickness) / renderTargetSize) * lineScreenRight;
  
  gl_Position = vec4(ndc0.xy + lineScreenOffset, ndc0.z, 1.0);
  varColor = vtxColor[0];
  if(bad)
    varColor = vec4(1.0, 0.0, 0.0, 1.0);
  EmitVertex();
  
  gl_Position = vec4(ndc0.xy - lineScreenOffset, ndc0.z, 1.0);
  varColor = vtxColor[0];
  if(bad)
    varColor = vec4(1.0, 0.0, 0.0, 1.0);
  EmitVertex();
  
  gl_Position = vec4(ndc1.xy + lineScreenOffset, ndc1.z, 1.0);
  varColor = vtxColor[1];
  if(bad)
    varColor = vec4(1.0, 0.0, 0.0, 1.0);
  EmitVertex();
  
  gl_Position = vec4(ndc1.xy - lineScreenOffset, ndc1.z, 1.0);
  varColor = vtxColor[1];
  if(bad)
    varColor = vec4(1.0, 0.0, 0.0, 1.0);
  EmitVertex();
  
  EndPrimitive();
}



been looking at this for a few hours with absolutely no luck
anyone??

Try disabling backface-culling, and enabling depth-clamp.

I should’ve noticed this earlier; also, change code to :


vec4 cpos = gl_in[0].gl_Position;
gl_Position = vec4(cpos.xy - lineScreenOffset*cpos.w, cpos.z, cpos.w);

As in, don’t reset W to 1.0 !! Thanks to that, you and the guy at stackoverflow make the HW clipper lose important data it needs, and you get these glitches.

That must be whats happening. I think I tried that but coudln’t get the thickness to work anymore cause it wasn’t properly being done in screen space. Your solution looks a tad different though, so I’ll try that.

I just tried (and miserably failed) to do clipping on my own in the gs and it just will not freaking work
I’m gonna stash all my changes and just put this down for awhile.

I’m completely fried.

that did it. Man, it was so simple. No idea why I didn’t try that earlier! :doh:

Resurrecting this. There solution indeed isn’t correct. Now the line thickness isn’t done in screen space correctly and varies depending on the viewing angle.

To help others that may land here via google. The code below indeed provides the best looking thick lines I could come up with. They still flake out a tiny bit when the thickness gets super high (likely still due to w scaling) but they don’t dissapear into thin air at certain viewing angles like the above.


uniform vec2 renderTargetSize;
uniform vec4 solidColor;
uniform mat4 modelViewProjectionMatrix;
uniform float lineThickness;


flat out vec4 varColor;


layout (lines) in;
layout (triangle_strip, max_vertices = 4) out;


void main()
{
  vec4 ndc0 = gl_in[0].gl_Position;
  vec4 ndc1 = gl_in[1].gl_Position;
  
  vec3 ndc0s = ndc0.xyz/ndc0.w;
  vec3 ndc1s = ndc1.xyz/ndc1.w;
  
  vec2 lineScreenForward = normalize(ndc1s.xy - ndc0s.xy);
  vec2 lineScreenRight = vec2(-lineScreenForward.y, lineScreenForward.x);
  vec2 lineScreenOffset = (vec2(lineThickness) / renderTargetSize) * lineScreenRight;
  
  //lineScreenOffset = vec2(0.0);
  
  gl_Position = vec4((ndc0s.xy + lineScreenOffset)*ndc0.w, ndc0.zw);
  varColor = solidColor;
  EmitVertex();
  
  gl_Position = vec4((ndc0s.xy - lineScreenOffset)*ndc0.w, ndc0.zw);
  varColor = solidColor;
  EmitVertex();
  
  gl_Position = vec4((ndc1s.xy + lineScreenOffset)*ndc1.w, ndc1.zw);
  varColor = solidColor;
  EmitVertex();
  
  gl_Position = vec4((ndc1s.xy - lineScreenOffset)*ndc1.w, ndc1.zw);
  varColor = solidColor;
  EmitVertex();
  
  EndPrimitive();
}



FYI: http://neure.dy.fi/wideline.html