带有附加裁剪平面的几何着色器
Geometry shader with additional clipplanes
我写了一个几何着色器来生成更粗的线条。但现在我遇到了问题,属性 [clipplanes(...)]
不起作用。有警告:
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
我知道可以选择自己编写三角形的剪裁,但在我看来这有点太费力了。有没有办法在几何着色器中使用额外的裁剪平面?
我还有另一个想法:几何着色器排成一行(2 个顶点)并且在顶点着色器内部 [clipplanes(...)]
属性有效......我能以某种方式获取剪切点而不是几何着色器内的原始顶点吗?
有关详细信息,您可以在此处找到我的几何着色器:
[切平面]
此属性只允许在顶点着色器上使用,
这是专门添加的,以支持低配置设备(此处主要阅读:手机)。
如果你需要在几何着色器上执行剔除,你可以使用SV_ClipDistance,这将限制你到D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT.
这个限制实际上是2,所以你可以提供2个变量:
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);
除了 2 个元素的限制,请注意它最终会提供更多的灵活性(因为您可以提供自己的裁剪功能)
如果 2 个平面的限制对于您的用例来说是一个真正的问题,其他选项是在像素着色器中执行平面裁剪:
- 使用零 alpha 值(如果 depth/stencil 不重要)
- 使用剪辑或丢弃
对于第二种情况,您需要将屏幕 space 值作为另一种语义传递给像素着色器,例如:
struct psInput
{
float4 pos: SV_POSITION;
float4 screenPos : SCPOS;
};
(在pos/screenPos中传递相同的值)
float4 PS(psInput input): SV_Target
{
clip(dot(clipPlane0, input.screenPos));
clip(dot(clipPlane1, input.screenPos));
return color;
}
在这种情况下,您可以拥有无限数量的剪辑平面,但请注意,剪辑对 msaa 不友好。
我写了一个几何着色器来生成更粗的线条。但现在我遇到了问题,属性 [clipplanes(...)]
不起作用。有警告:
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
我知道可以选择自己编写三角形的剪裁,但在我看来这有点太费力了。有没有办法在几何着色器中使用额外的裁剪平面?
我还有另一个想法:几何着色器排成一行(2 个顶点)并且在顶点着色器内部 [clipplanes(...)]
属性有效......我能以某种方式获取剪切点而不是几何着色器内的原始顶点吗?
有关详细信息,您可以在此处找到我的几何着色器:
[切平面]
此属性只允许在顶点着色器上使用, 这是专门添加的,以支持低配置设备(此处主要阅读:手机)。
如果你需要在几何着色器上执行剔除,你可以使用SV_ClipDistance,这将限制你到D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT.
这个限制实际上是2,所以你可以提供2个变量:
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);
除了 2 个元素的限制,请注意它最终会提供更多的灵活性(因为您可以提供自己的裁剪功能)
如果 2 个平面的限制对于您的用例来说是一个真正的问题,其他选项是在像素着色器中执行平面裁剪:
- 使用零 alpha 值(如果 depth/stencil 不重要)
- 使用剪辑或丢弃
对于第二种情况,您需要将屏幕 space 值作为另一种语义传递给像素着色器,例如:
struct psInput
{
float4 pos: SV_POSITION;
float4 screenPos : SCPOS;
};
(在pos/screenPos中传递相同的值)
float4 PS(psInput input): SV_Target
{
clip(dot(clipPlane0, input.screenPos));
clip(dot(clipPlane1, input.screenPos));
return color;
}
在这种情况下,您可以拥有无限数量的剪辑平面,但请注意,剪辑对 msaa 不友好。