Geometry Shader/Defined Outputs

From OpenGL Wiki
< Geometry Shader
Revision as of 03:32, 5 August 2015 by Alfonse (talk | contribs) (Still a bit unclear on gl_PrimitiveID)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Geometry Shaders have the following built-in outputs.

out gl_PerVertex
{
  vec4 gl_Position;
  float gl_PointSize;
  float gl_ClipDistance[];
};

gl_PerVertex defines an interface block for outputs. The block is defined without an instance name, so that prefixing the names is not required.

The GS is the final Vertex Processing stage. Therefore, unless rasterization is being turned off, you must write to some of these values. These outputs are always associated with stream 0. So if you're emitting vertices to a different stream, you don't have to write to them.

gl_Position
the clip-space output position of the current vertex. This value must be written if you are emitting a vertex to stream 0, unless rasterization is off.
gl_PointSize
the pixel width/height of the point being rasterized. It is only necessary to write to this when outputting point primitives.
gl_ClipDistance
allows the shader to set the distance from the vertex to each User-Defined Clip Plane. A positive distance means that the vertex is inside/behind the clip plane, and a negative distance means it is outside/in front of the clip plane. In order to use this variable, the user must manually redeclare it (and therefore the interface block) with an explicit size.

Certain predefined outputs have special meaning and semantics.

out int gl_PrimitiveID;

The primitive ID will be passed to the fragment shader. The primitive ID for a particular line/triangle will be taken from the provoking vertex of that line/triangle, so make sure that you are writing the correct value for the right provoking vertex.

The meaning for this value is whatever you want it to be. However, if you want to match the standard OpenGL meaning (ie: what the Fragment Shader would get if no GS were used), you must do this for each vertex before emitting it:

gl_PrimitiveID = gl_PrimitiveIDIn;

This naturally assumes that the number of primitives output by the GS equals the number of primitives received by the GS.