2007/02/14
D3D10 GeometryShaderでsprite(2)
D3D10 GeometryShaderでspriteで書いた
1頂点を4点のポリゴンに展開する GeometryShader の例です。
VS_OUTPUT の Size には、xy に texcoord のサイズが、zw に右下の頂点座標が
入ります。この zw の計算は VertexShader で行っています。
VS_OUTPUT は VertexShader の出力、GS_OUTPUT はそのまま PixelShader の入力
になります。
struct VS_OUTPUT {
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Size : SIZE; // .xy=uvsize .zw=right/bottom
float4 Color : COLOR;
};
struct GS_OUTPUT {
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Color : COLOR;
};
[maxvertexcount(6)]
void GS_Main( point VS_OUTPUT In[1], inout TriangleStream<GS_OUTPUT> gsstream )
{
GS_OUTPUT Out;
// 左上三角
Out.Pos= In[0].Pos;
Out.Tex= In[0].Tex;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.x= In[0].Size.z;
Out.Tex= In[0].Tex; Out.Tex.x+= In[0].Size.x;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.y= In[0].Size.w;
Out.Tex= In[0].Tex; Out.Tex.y+= In[0].Size.y;
Out.Color= In[0].Color;
gsstream.Append( Out );
gsstream.RestartStrip();
// 右下三角
Out.Pos= In[0].Pos; Out.Pos.y= In[0].Size.w;
Out.Tex= In[0].Tex; Out.Tex.y+= In[0].Size.y;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.x= In[0].Size.z;
Out.Tex= In[0].Tex; Out.Tex.x+= In[0].Size.x;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.xy= In[0].Size.zw;
Out.Tex= In[0].Tex; Out.Tex.xy+= In[0].Size.xy;
Out.Color= In[0].Color;
gsstream.Append( Out );
gsstream.RestartStrip();
}
1頂点を4点のポリゴンに展開する GeometryShader の例です。
VS_OUTPUT の Size には、xy に texcoord のサイズが、zw に右下の頂点座標が
入ります。この zw の計算は VertexShader で行っています。
VS_OUTPUT は VertexShader の出力、GS_OUTPUT はそのまま PixelShader の入力
になります。
struct VS_OUTPUT {
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Size : SIZE; // .xy=uvsize .zw=right/bottom
float4 Color : COLOR;
};
struct GS_OUTPUT {
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Color : COLOR;
};
[maxvertexcount(6)]
void GS_Main( point VS_OUTPUT In[1], inout TriangleStream<GS_OUTPUT> gsstream )
{
GS_OUTPUT Out;
// 左上三角
Out.Pos= In[0].Pos;
Out.Tex= In[0].Tex;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.x= In[0].Size.z;
Out.Tex= In[0].Tex; Out.Tex.x+= In[0].Size.x;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.y= In[0].Size.w;
Out.Tex= In[0].Tex; Out.Tex.y+= In[0].Size.y;
Out.Color= In[0].Color;
gsstream.Append( Out );
gsstream.RestartStrip();
// 右下三角
Out.Pos= In[0].Pos; Out.Pos.y= In[0].Size.w;
Out.Tex= In[0].Tex; Out.Tex.y+= In[0].Size.y;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.x= In[0].Size.z;
Out.Tex= In[0].Tex; Out.Tex.x+= In[0].Size.x;
Out.Color= In[0].Color;
gsstream.Append( Out );
Out.Pos= In[0].Pos; Out.Pos.xy= In[0].Size.zw;
Out.Tex= In[0].Tex; Out.Tex.xy+= In[0].Size.xy;
Out.Color= In[0].Color;
gsstream.Append( Out );
gsstream.RestartStrip();
}
2007/02/14
D3D10 GeometryShader で sprite
Direct3D10 では、GeometryShader を使って頂点を増やすことができます。
従来任意の 2D の画像を描画する場合、描画には 4頂点分のデータが必要でした。
例えば x y u v color 等の5要素を 4頂点分使い、TriangleList の 2つの三角
ポリゴンとして描画します。
例
●頂点
0, 0, 0, 0, 0xffffffff,
32, 0, 1, 0, 0xffffffff,
0, 32, 0, 1, 0xffffffff,
32, 32, 1, 1, 0xffffffff,
●インデックス
0, 1, 2,
2, 1, 3,
そのため CPU 側で4頂点分の計算を行い4頂点分のデータを書き込む必要があります。
D3D10 では、GeometryShader を使うことでもっと簡単に描画できるようになります。
例えば頂点形式を x y w h u v us vs color の 8要素として、PointList を使い
0, 0, 32, 32, 0, 0, 1, 1, 0xfffffff,
となります。PrimitiveType が PointList なのでインデックスは不要です。
これを GeometryShader を使って、4頂点の矩形である 2ポリゴンに変換することが
できます。
昔の PointSprite のような感じです。
違いは uv を自由に指定できて大きさも任意であること。
特徴は 1頂点だけで制御できるので CPU 側の演算が不要でバッファも少なくて
済みます。
こんな風に、GeometryShader は工夫次第でハードウエアでカスタマイズできる
2D 向けの Sprite 機能としても活用できるわけです。
Shader でなんでもできるので、頂点に回転角度を入れて回転機能を持たせる
なんてことももちろん可能でしょう。
従来任意の 2D の画像を描画する場合、描画には 4頂点分のデータが必要でした。
例えば x y u v color 等の5要素を 4頂点分使い、TriangleList の 2つの三角
ポリゴンとして描画します。
例
●頂点
0, 0, 0, 0, 0xffffffff,
32, 0, 1, 0, 0xffffffff,
0, 32, 0, 1, 0xffffffff,
32, 32, 1, 1, 0xffffffff,
●インデックス
0, 1, 2,
2, 1, 3,
そのため CPU 側で4頂点分の計算を行い4頂点分のデータを書き込む必要があります。
D3D10 では、GeometryShader を使うことでもっと簡単に描画できるようになります。
例えば頂点形式を x y w h u v us vs color の 8要素として、PointList を使い
0, 0, 32, 32, 0, 0, 1, 1, 0xfffffff,
となります。PrimitiveType が PointList なのでインデックスは不要です。
これを GeometryShader を使って、4頂点の矩形である 2ポリゴンに変換することが
できます。
昔の PointSprite のような感じです。
違いは uv を自由に指定できて大きさも任意であること。
特徴は 1頂点だけで制御できるので CPU 側の演算が不要でバッファも少なくて
済みます。
こんな風に、GeometryShader は工夫次第でハードウエアでカスタマイズできる
2D 向けの Sprite 機能としても活用できるわけです。
Shader でなんでもできるので、頂点に回転角度を入れて回転機能を持たせる
なんてことももちろん可能でしょう。