几何着色器是DX10中刚刚加入的内容,在DX9中从未有过,其渲染过程中是介于顶点着色器与像素着色器之间。
几何着色器的使用主要目的是为了可以在着色器程序中改变顶点的数量和类型。
下面是一个几何着色器的定义
[maxvertexcount(N)]
void ShaderName (
PrimitiveType InputVertexType InputName [NumElements],
inout StreamOutputObject<OutputVertexType> OutputName)
{
// Geometry shader body...
}
在这段代码中
maxvertexcount(N)定义了返回的最大顶点数,N为最大顶点数
NumElements则定义了输入的顶点个数,PrimitiveType定义了输入的顶点的构成类型。InputVertexType则定义了输入顶点的自定义类型
其中PrimitiveType种类有
point: 输入顶点为点类型
line: 输入顶点构成线状.
triangle: 输入顶点构成三角形.
lineadj: 带有邻接信息的顶点构成线状.
triangleadj:带有邻接信息的顶点构成三角形.
inout StreamOutputObject<OutputVertexType> OutputName则定义了输出的的顶点,StreamOutputObject是顶点输出的构成类型,OutputVetexType是顶点的自定义输出类型。
StreamOutputObject则有类型:PointStream,LineStream,TriangleStream.分别为点,线,三角形。
以下为hlsl代码:
struct GSPS_INPUT
{
float4 Pos : SV_POSITION;
float3 Norm : TEXCOORD0;
float2 Tex : TEXCOORD1;
};
[maxvertexcount(12)]
void GS( triangle GSPS_INPUT input[3], inout TriangleStream<GSPS_INPUT> TriStream )
{
GSPS_INPUT output;
//
// 计算面的法线
//
float3 faceEdgeA = input[1].Pos - input[0].Pos;
float3 faceEdgeB = input[2].Pos - input[0].Pos;
float3 faceNormal = normalize( cross(faceEdgeA, faceEdgeB) );
float3 ExplodeAmt = faceNormal*Explode;
//
// 计算面的中心
//
float3 centerPos = (input[0].Pos.xyz + input[1].Pos.xyz + input[2].Pos.xyz)/3.0;
float2 centerTex = (input[0].Tex + input[1].Tex + input[2].Tex)/3.0;
centerPos += faceNormal*Explode;
//
// 输出金字塔
//
for( int i=0; i<3; i++ )
{
output.Pos = input[i].Pos + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = input[i].Norm;
output.Tex = input[i].Tex;
TriStream.Append( output );
int iNext = (i+1)%3;
output.Pos = input[iNext].Pos + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = input[iNext].Norm;
output.Tex = input[iNext].Tex;
TriStream.Append( output );
output.Pos = float4(centerPos,1) + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = faceNormal;
output.Tex = centerTex;
TriStream.Append( output );
TriStream.RestartStrip();
}
for( int i=2; i>=0; i-- )
{
output.Pos = input[i].Pos + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = -input[i].Norm;
output.Tex = input[i].Tex;
TriStream.Append( output );
}
TriStream.RestartStrip();
}
这段代码是根据输入的三个顶点输出一个金字塔。
首先根据任意2个顶点为边外加中心顶点构成3个三角形,再根据本身的三个顶点构成一个底部三角形。
其中append函数为给输出顶点序列中添加一个顶点,RestartStrip则重新开始输出顶点的序列,比如三角形顶点序列调用此函数重新开始三角形序列的计算。
以上就是几何着色器的简单应用。