Condividi tramite


SpriteBatchクラス その1

 SpriteBatchクラスはWindows/Xbox360上で効率的に2D描画をするために設計されています。SpriteBatchで使える機能としては以下のものがあります。

  • 回転とスケーリング
  • ソーステクスチャ領域の指定
  • カラーモジュレーション
  • バッチ処理とソーティング

スプライトの回転とスケーリングを使う場合に気をつける点はOriginパラメーターを指定しない場合は、回転、スケーリングはスプライトの左上を原点として扱います。

上図は、原点の違いによる回転結果の違いです。キャラクターなどをスプライトを使って描画する場合、特に多間接キャラクタなどを表現する場合はOriginを指定することが多いと思います。

また、テクスチャの一部分の矩形を指定できるので、一枚のテクスチャに複数のキャラクタのアニメーションを描いたり、ビットマップフォントなどで指定の文字の部分を描くといったことができます。

カラーモジュレーションはColorパラメーターで指定したカラーとテクスチャカラーを乗算した結果が描画されます。テクスチャのそのままの色を使う場合はColor.Whiteを使います。使用例としては夕焼けのシーンで赤い色をColorに指定したり、キャラクターが現れる時にカラーのアルファ値を時間と共に変更することで徐々に現れたり、消えたりといった演出にも使えます。

バッチ処理とソーティング

現在のGPUは、大量のポリゴンを描画するように設計されていますが、そのパフォーマンスを得るためにはテクスチャ変更といったレンダーステートの変更を極力少なくする必要があります。例えば木と岩の2枚のテクスチャがあった場合、木のテクスチャのスプライトを100枚続けて描いた後に岩のテクスチャのスプライトを100枚描くのと、岩と木のテクスチャを交互に切り替えて10枚(書き間違ではない)描いた方が遅いなんていうこともあります。

見下ろし型の2Dベースのゲームを作る場合、地面があり、その上に岩や木といったオブジェクトがあり、更にその上に半透明の雲があるようなシーンを作る場合、以下のようにSpriteBatchを使うことで実現できます。

地面部分を描く場合、その殆どがアルファブレンディングの必要がないので、SpriteSortMode.Textureを設定します。この時、SpriteBatchクラスはDrawで呼ばれたパラメーターを内部バッファに保持しておき、SpriteBatch.Endが呼ばれた時に使われているテクスチャの順に並び替えてから、まとめて描画します。テクスチャ変更の回数を少なくすることによって、GPUが効率的に描画することができます。

次に、木や岩といったオブジェクトを描く場合に重要なのは、オブジェクトの前後関係です。この場合、SpriteSortMode.BackToFront、またはSpriteSortMode.FrontToBackを使用します。スプライトはDrawメソッドのdepthLayer引数の値によって並び替えられた後に描画されます。depthLayer引数は0~1までの浮動小数点の値で、0が手前側(Front)、1が奥側(Back)になります。ですから、通常はSpriteSortMode.BackToFrontを指定します。

最後に雲の描画になるわけですが、これも単純にSpriteSortMode.BackFrontを使って、雲の高さをdepthLayerに指定することで実現できます。

             // 背景を描く
            spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Texture, SaveStateMode.None);
            spriteBatch.Draw(...);
            spriteBatch.End();

            // 木や岩といったオブジェクトを描く
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.None);
            spriteBatch.Draw(...);
            spriteBatch.End();

            // 雲を描く
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.None);
            spriteBatch.Draw(...);
            spriteBatch.End();

まとめると以上のようなコードになります。このようなケースではSpriteSortModeを指定するだけで実現できることが多いですが、ゲーム側で描画の順番などを制御したい場合はSpriteSortMode.Immediateを使います。SpriteSortMode.Immediateを使った場合、SpriteBatchは並び替えの処理などをせずにDrawを呼んだ順にスプライトを描きます。この場合でも、同じテクスチャが続けて使われている場合はバッチ処理の対象となるので、呼び出し側で調整することでパフォーマンスを得ることができます。

また、SpriteSortMode.Immediateと他のソートモードとの違いとして、スプライトを描画するのに必要なレンダーステートは、他のソートモードではSpriteBatch.End内で設定されるのに対して、SpriteSortMode.Immediateの場合はSpriteBatch.Begin内で設定されます。ですから、SpriteBlendModeで用意されているブレンドモード以外のものを使いたい場合などにSpriteSortMode.Immediateを設定することができます。

SpriteBatchは描画するのに必要なレンダーステートを設定しますが、その事については次回で詳しく説明します。