私は通常SpriteBatch
、2D ゲームの XNA/Monogame で作業しており、最近では などの 3D 描画方法を詳しく調べていDrawUserIndexedPrimatives
ます。私は、アニメーターがスプライトとテクスチャをせん断する機能を持ちたいというプロジェクトに取り組んでいます。
を使用すると、オブジェクトの剪断を開始するためにSpriteBatch
マトリックスを渡すことができます。SpriteBatch
何かのようなもの:
//translate object to origin
Matrix translate1 = Matrix.CreateTranslation(-rectangle.X, -rectangle.Y, 0);
//skew the sprite 33 degrees on the X and Y axis
Matrix skew = Matrix.Identity;
skew.M12 = (float)Math.Tan(33 * 0.0174532925f);
skew.M21 = (float)Math.Tan(33 * 0.0174532925f);
//translate object back
Matrix translate2 = Matrix.CreateTranslation(rectangle.X, rectangle.Y, 0);
Matrix transform = translate1 * skew * translate2;
_spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied,
SamplerState.PointWrap, DepthStencilState.Default,
RasterizerState.CullCounterClockwise, null, transform);
_spriteBatch.Draw(_texture, rectangle, Color.White);
_spriteBatch.End();
SpriteBatch
これの明らかな欠点は、せん断されたスプライトごとに新しい開始呼び出しと終了呼び出しを行う必要があることです。SpriteBatch
現在、ゲームを開始するために必要な呼び出しは 2 つだけです。1 つは UI 用、もう 1 つはワールド用です。私たちのアーティストは、木を揺らしたり、生き物の足や手足をアニメートしたりするためにせん断を使用したいと考えていたので、オプションを与えると、その数が 10 以上の個別のバッチにジャンプすることがわかりました。
平均的なレベルには、それぞれ 10 ~ 20 のスプライトを含む約 250 の要素があります。
1000 個のスプライトで描画を呼び出す Android 用のテストを作成しました。1000 回、600 回、約 11 秒または約 53 fps でスキューなしですべてを描画できます。しかし、スプライトを 10 個ごとに歪ませる (100 個の新しいSpriteBatch
呼び出しを追加する) と、47 秒、つまり約 12fps かかります。
それは本当に悪いです。わずか 200 個のスプライト (10 個ごとに歪んだもの) の場合でも、テストは 28fps に低下します。
そのため、 で描画された Quads を使用して同じテストも作成しましたDrawUserIndexedPrimitives
。各クワッドはBasicEffect
、Game クラスで作成され、Sprite
クラス コンストラクターを介して渡される共有を使用します。pass.Apply()
次のように、それぞれの前に World Matrix と Texture を設定します。
if (_basicEffect != null)
{
foreach (EffectPass pass in _basicEffect.CurrentTechnique.Passes)
{
_basicEffect.World = Transform;
_basicEffect.Texture = _texture;
pass.Apply();
GraphicsDevice.DrawUserIndexedPrimitives
<VertexPositionNormalTexture>(
PrimitiveType.TriangleList,
_quad.Vertices, 0, 4,
_quad.Indices, 0, 2);
}
1000 個のスプライトの場合、スキューなしで、これにより 12 fps が得られます (1000 回のspriteBatch
呼び出しに似ていると思います)。それは本当に悪いです。しかし、10 番目のスプライトごとに歪んだ 200 のスプライトのみで、46 fps を取得しSpriteBatch
ますDrawUserIndexedPrimitives
。
- -私の質問 - -
DrawUserIndexedPrimitives
を継承する独自のクラスに含まれるスプライトを保持しながら、(または同様のもの)への呼び出しをバッチ処理するにはどうすればよいDrawableGameComponent
ですか? この最後の部分は、ゲーム エンジンの性質と、アニメーションやコリジョンなどを処理する方法のために非常に重要です。
Vertex Buffers と についてできる限り読んだことDrawIndexedPrimitives
がありますが、頭がまとまらず、この方法で描画されたスプライトに新しいテクスチャとワールド変換を割り当てる方法がわかりません。
SpriteBatch
これらの呼び出しをバッチ処理した場合と同等またはより優れたパフォーマンスが期待できますか?