I am relatively new to GLSL shader programming, and the documentation I found is unfortunately often inscrutable. I am having trouble understanding a few things with how geometry shaders fit into the pipeline.
I am trying to implement silhouette detection by detecting boundary triangles in a geometry shader. A triangle is a boundary triangle if it is front-facing and an adjacent triangle is back facing. The idea then is to emit additional camera-facing triangles to outline them.
For this purpose, I am looking at GL_TRIANGLE_ADJACENCY
shaders, since they seem to fit the bill. Let's assume for the moment that I have already got the data loaded properly into the buffer.
For clarity: I plan on doing skinning and the Model View transform in the vertex shader, but to hold off on the perspective projection until I decide what to do in the geometry shader (this seems reasonable, but maybe I am wrong).
Here is where the uncertainties start to come in. First of all, am I expected to manually perform backface culling at some shader stage?
Second, if a triangle has incomplete adjacency information(only 2 out of three triangles for example), how is this conveyed to the shader? Does it just have a length less than 6 vertices?
Third, what does the pass through shader (the one that does nothing special) have to perform? Do I emit every vertex in the input list, or just 3 from the first triangle? And again, am I supposed to/allowed to cull backfaces?
And last, if I decide to emit additional geometry, is there anyway to distinguish that from the (passed-through) input geometry from the point of view of the fragment shader? I'd like to be able to texture map them separately if it is possible.
If I am on the wrong path on any of this, of course feel free to let me know. In case it is important, I am using OpenGL 3.3.
Based on my understanding and Nathan's answer, I could start with a passthrough shader that looks something like this:
layout(triangle_adjacency) in;
layout(triangle_strip, max_vertices = 14) out;
flat out float is_border;
void main() {
gl_Position = gl_in[0].gl_Position;
is_border=0.0;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
is_border=0.0;
EmitVertex();
gl_Position = gl_in[4].gl_Position;
is_border=0.0;
EmitVertex();
EndPrimitive();
}
And then when/if I add triangle strips for outlines, I will set is_border=1.0
for each of those vertices.