DX10之GS生成篇
1.由三角形生成金字塔:
簡析:triangle GSPS_INPUT input[3]代表輸入的三角形
inout TriangleStream<GSPS_INPUT> TriStream 代表輸出的三角形流-即金字塔共12個頂點
第一個循環計算三個標出法向量的三角形,如圖所示。
第二個循環計算出三角形與輸入的三角形一樣,但平面的法向量剛好相反。
//--------------------------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------------------------
[maxvertexcount(12)]
void GS( triangle GSPS_INPUT input[3], inout TriangleStream<GSPS_INPUT> TriStream )
{
GSPS_INPUT output;
//
// Calculate the face normal
//
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;
//
// Calculate the face center
//
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;
//
// Output the pyramid
//
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.GS粒子
實現像煙花一樣的效果。
首先要了解五種基本粒子。
Launcher Particles 發射粒子:不移動也不死去,用來發射Shell粒子。一旦發射完Shell粒子,就重置時間。
Shell Particles 由發射粒子發射出隨機速度的的Shell粒子,在生命周期內不發射本類型的粒子,而發射出一些Ember1和Ember2類型的粒子。
Ember1 Particles 由Shell粒子發射,擁有很短的生命周期,隨著時間而淡出死去,并不發射粒子。
Ember2 Particles 由Shell粒子發射,在生命周期末發出Ember3粒子,第二次的爆炸源。
Ember3 Particles 類似Ember1粒子,除了有不同的顏色。
[maxvertexcount(128)]
void GSAdvanceParticlesMain(point VSParticleIn input[1], inout PointStream<VSParticleIn> ParticleOutputStream)
{
if( input[0].Type == PT_LAUNCHER )
GSLauncherHandler( input[0], ParticleOutputStream );
else if ( input[0].Type == PT_SHELL )
GSShellHandler( input[0], ParticleOutputStream );
else if ( input[0].Type == PT_EMBER1 ||
input[0].Type == PT_EMBER3 )
GSEmber1Handler( input[0], ParticleOutputStream );
else if( input[0].Type == PT_EMBER2 )
GSEmber2Handler( input[0], ParticleOutputStream );
}