如何在 HLSL 中设置几何着色器?
How to setup geometry shaders in HLSL?
我正在尝试将几何着色器阶段添加到我的管道中,但是当我添加几何着色器函数时,即使是顶点着色器编译也会出于某种原因给出错误(顶点、像素和几何着色器在同一个文件中) ).
几何着色器中的代码似乎是导致问题的原因,因为我一删除它,顶点着色器就编译成功了。
我从来没有在任何 API 中处理过几何着色器,但在我看来,设置几何着色器应该和其他的一样简单,有一些 DX11 的几何着色器示例网上有,但不多。至少我能找到的所有这些都只显示了 hlsl 方面。
cbuffer TickConstantBuffer : register(b0)
{
matrix World;
matrix View;
}
cbuffer OnEvent : register(b1)
{
matrix Projection;
}
float4 VS( float4 Pos : POSITION ) : SV_POSITION
{
float4 OutPos;
OutPos = mul(Pos, View);
OutPos = mul(OutPos, Projection);
return Pos;
}
[maxvertexcount(4)]
void GS( point float4 input[1], inout TriangleStream<float4> OutputStream )
{
float4 v;
OutputStream.Append(float4(input[0].x + 0.5, input[0].y + 0.5, input[0].z, input[0].w));
OutputStream.Append(float4(input[0].x - 0.5, input[0].y + 0.5, input[0].z, input[0].w));
OutputStream.Append(float4(input[0].x - 0.5, input[0].y - 0.5, input[0].z, input[0].w));
OutputStream.Append(float4(input[0].x + 0.5, input[0].y - 0.5, input[0].z, input[0].w));
}
float4 PS( float4 Pos : SV_POSITION ) : SV_Target
{
return float4( 1.0f, 1.0f, 0.0f, 1.0f );
}
您的几何着色器没有与之关联的语义。因此,Direct3D 不知道如何将顶点着色器的输出传递给几何着色器,也不知道如何将几何着色器的输出传递给像素着色器。
要解决此问题,您的所有参数都需要具有与之关联的语义。对于输入,这很简单:更改
point float4 input[1]
到
point float4 input[1] : SV_POSITION
这将 link 顶点着色器的输出与几何着色器的输入。
到 link 从几何着色器到像素着色器需要更多的工作。由于您已将像素着色器定义为采用 SV_POSITION
的值,因此您需要输出一个附加了该语义的值。但是,您必须将该语义附加到 TriangleStream
的每个元素,并且不能将语义附加到类型,只能附加到变量,因此像 TriangleStream<float4 : SV_POSITION>
这样的东西将无法编译。
为了解决这个问题,我们将创建一个结构,其中包含一个具有 SV_POSITION
语义的成员变量:
struct GSOutput
{
float4 pos : SV_POSITION;
};
并将我们的 TriangleStream
从
更改为
inout TriangleStream<float4> OutputStream
至
inout TriangleStream<GSOutput> OutputStream
最后,我们需要修改生成点的方法,因为我们不再简单地将它们添加到列表中:
GSOutput gsout;
gsout.pos = float4(input[0].x + 0.5, input[0].y + 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
gsout.pos = float4(input[0].x - 0.5, input[0].y + 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
gsout.pos = float4(input[0].x - 0.5, input[0].y - 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
gsout.pos = float4(input[0].x + 0.5, input[0].y - 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
此时,编译器将文件识别为完全有效的 HLSL 代码,并可以正常编译。
我正在尝试将几何着色器阶段添加到我的管道中,但是当我添加几何着色器函数时,即使是顶点着色器编译也会出于某种原因给出错误(顶点、像素和几何着色器在同一个文件中) ). 几何着色器中的代码似乎是导致问题的原因,因为我一删除它,顶点着色器就编译成功了。
我从来没有在任何 API 中处理过几何着色器,但在我看来,设置几何着色器应该和其他的一样简单,有一些 DX11 的几何着色器示例网上有,但不多。至少我能找到的所有这些都只显示了 hlsl 方面。
cbuffer TickConstantBuffer : register(b0)
{
matrix World;
matrix View;
}
cbuffer OnEvent : register(b1)
{
matrix Projection;
}
float4 VS( float4 Pos : POSITION ) : SV_POSITION
{
float4 OutPos;
OutPos = mul(Pos, View);
OutPos = mul(OutPos, Projection);
return Pos;
}
[maxvertexcount(4)]
void GS( point float4 input[1], inout TriangleStream<float4> OutputStream )
{
float4 v;
OutputStream.Append(float4(input[0].x + 0.5, input[0].y + 0.5, input[0].z, input[0].w));
OutputStream.Append(float4(input[0].x - 0.5, input[0].y + 0.5, input[0].z, input[0].w));
OutputStream.Append(float4(input[0].x - 0.5, input[0].y - 0.5, input[0].z, input[0].w));
OutputStream.Append(float4(input[0].x + 0.5, input[0].y - 0.5, input[0].z, input[0].w));
}
float4 PS( float4 Pos : SV_POSITION ) : SV_Target
{
return float4( 1.0f, 1.0f, 0.0f, 1.0f );
}
您的几何着色器没有与之关联的语义。因此,Direct3D 不知道如何将顶点着色器的输出传递给几何着色器,也不知道如何将几何着色器的输出传递给像素着色器。
要解决此问题,您的所有参数都需要具有与之关联的语义。对于输入,这很简单:更改
point float4 input[1]
到
point float4 input[1] : SV_POSITION
这将 link 顶点着色器的输出与几何着色器的输入。
到 link 从几何着色器到像素着色器需要更多的工作。由于您已将像素着色器定义为采用 SV_POSITION
的值,因此您需要输出一个附加了该语义的值。但是,您必须将该语义附加到 TriangleStream
的每个元素,并且不能将语义附加到类型,只能附加到变量,因此像 TriangleStream<float4 : SV_POSITION>
这样的东西将无法编译。
为了解决这个问题,我们将创建一个结构,其中包含一个具有 SV_POSITION
语义的成员变量:
struct GSOutput
{
float4 pos : SV_POSITION;
};
并将我们的 TriangleStream
从
inout TriangleStream<float4> OutputStream
至
inout TriangleStream<GSOutput> OutputStream
最后,我们需要修改生成点的方法,因为我们不再简单地将它们添加到列表中:
GSOutput gsout;
gsout.pos = float4(input[0].x + 0.5, input[0].y + 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
gsout.pos = float4(input[0].x - 0.5, input[0].y + 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
gsout.pos = float4(input[0].x - 0.5, input[0].y - 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
gsout.pos = float4(input[0].x + 0.5, input[0].y - 0.5, input[0].z, input[0].w);
OutputStream.Append(gsout);
此时,编译器将文件识别为完全有效的 HLSL 代码,并可以正常编译。