Thomas
Thomas

Reputation: 2259

Geometry shader with additional clipplanes

I wrote a geometry shader for generating thicker lines. But now i've the problem, that the attribute [clipplanes(...)] does not work. There is the warning:

Severity Code Description Project File Line Suppression State Warning X3554 unknown attribute clipplanes, or attribute invalid for this statement, valid attributes are: maxvertexcount, MaxVertexCount, instance CRenderer \Shaders\GeometryShader\GS_GenerateThickLines.hlsl

I know there is the option to write the clipping of a triangle on my own, but it seem to me like a bit too mush effort. Is there a way of using additional clipplanes in geometry shaders? I also have another idea: the geometry shader gets in a line (2 Vertices) and inside the vertex shader the [clipplanes(...)] attribute works... can I somehow get the clipping point instead of the original vertex inside the geometry shader? For more information you can find my geometry shader here: Render thick lines with instanced rendering in directx 11

Upvotes: 2

Views: 1196

Answers (1)

mrvux
mrvux

Reputation: 8953

[clipplanes]

This attribute is only allowed on Vertex Shader, this has been specifically added in order to support low profile devices (here mostly read: phones).

If you need to perform culling on geometry shader, you can use SV_ClipDistance, which will limit you onto D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT.

This limit is actually of 2, so you can provide 2 variables as per :

struct gs2ps
{
    float4 pos: SV_Position;
    float2 uv : TEXCOORD0;
    float cd0 : SV_ClipDistance0;
    float cd1 : SV_ClipDistance1;
}; 

cbuffer cbClipPlanes : register(b1) 
{
   float4 clipPlane0;
   float4 clipPlane1;
};

gs2ps op;
op.cd0 = dot(clipPlane0, position);
op.cd1 = dot(clipPlane1, position);

Besides the 2 elements limitation, please not that it eventually offers a bit more flexibility (as you can provide your own clipping function)

In case the limit of 2 planes is a real issue for your use case, other option is to perform the plane clipping in Pixel Shader:

  • Use a Zero alpha value (if depth/stencil is unimportant)
  • Use clip or discard

For the second case, you will need to pass your screen space value as another semantic to your pixel shader, like:

struct psInput
{
    float4 pos: SV_POSITION;
    float4 screenPos : SCPOS;
}; 

(Pass the same value in pos/screenPos)

float4 PS(psInput input): SV_Target
{
    clip(dot(clipPlane0, input.screenPos));
    clip(dot(clipPlane1, input.screenPos));
    return color;
}

In that case you can have an unlimited amount of clip planes, but please note that clip is not msaa friendly.

Upvotes: 3

Related Questions