Geometry Shader

The Geometry Shader is an optional stage in the DirectX graphics pipeline that can be used to create or destroy primitives (like points, lines, and triangles) after the vertex shader has processed the geometry. Unlike the vertex shader, which operates on individual vertices, the geometry shader operates on entire primitives and can emit new primitives.

Purpose and Capabilities

How it Works

The geometry shader receives a single primitive (a point, line, or triangle, or potentially a patch for tessellation) as input. It can then iterate over the vertices of this primitive and emit zero or more new primitives. The output can be of a different type than the input. For example, a geometry shader could take a single point and emit a triangle.

Shader Model Versions

Geometry shaders are supported starting with Shader Model 4.0.

Input and Output

Geometry shaders use specific input and output structures to define the data passed between stages. The output primitive type can be specified as part of the shader declaration.

Example Shader Declaration (HLSL)


struct GS_INPUT
{
    float4 pos : SV_POSITION;
    float2 tex : TEXCOORD;
};

struct GS_OUTPUT
{
    float4 pos : SV_POSITION;
    float2 tex : TEXCOORD;
};

[maxvertexcount(10)] // Example: Maximum 10 vertices can be emitted
void GS_Main( primitive GS_INPUT input[3],
                 inout stream GS_OUTPUT output [10] )
{
    // Shader logic to process input primitive and emit output primitives
    // For example, to emit a triangle for each input vertex:
    for (uint i = 0; i < input.length(); ++i)
    {
        output[i].pos = input[i].pos;
        output[i].tex = input[i].tex;
    }
    output.Append(); // Emit the generated primitive
}
            

Use Cases

Performance Considerations

While powerful, geometry shaders can introduce performance overhead. The number of primitives emitted can significantly impact performance. It's crucial to profile and optimize geometry shader code, limiting the number of emitted vertices and avoiding excessive complexity. In many modern rendering scenarios, tessellation (Hull and Domain Shaders) or compute shaders are preferred for certain tasks that geometry shaders were historically used for.

Note: The use of geometry shaders can be a performance bottleneck. Consider if tessellation or compute shaders might be a more efficient alternative for your specific use case.
Tip: Always specify the maxvertexcount attribute to inform the driver of the maximum number of vertices your shader can emit, allowing for better resource management.

Related Topics