1ポリゴンスプライトのメリットとデメリット

素晴らしいパフォーマンスを見せてくれた直角三角形1ポリゴンのスプライト描画だが、単純に採用できるものではない。
それについて考えてみる。


メリットは頂点データが減ることによる負荷低減だが、デメリットはXo式 実験室さまでも指摘されている、テクスチャに途中の1部分を切り出して使えないことだ。
なぜかというと、直角三角形は左上・右上・左下を指定した形であり、四角が収まるサイズにするためには絵のサイズの倍の幅と高さが必要で、その頂点に指定するtu、tvは(0,0)、(2,0)、(0,2)となっていて、つまり描画するテクスチャの倍、わざとはみ出した位置を指定する必要があるからだ。
右と下に別の画像があったら、三角形の消えて欲しい部分にも絵が描画されてしまう。
ということは、スプライトごとに別のテクスチャを用意する必要がある。
違う絵を描画すると、100%SetTextureでテクスチャ切り替えが発生する、ということだ。


DXRubyで実現するとすれば、Imageオブジェクトを作るたびにCreateTextureして中身をコピーしていけばよいのだが、ユーザーが1つの画像にまとめたとしても関係なく、常に別々のテクスチャになってしまう。
無理矢理まとめようと思うと、画像1枚につき、同じサイズの空白が右と下に必要になる。
テクスチャサイズが大きくなり、メモリ帯域が単純に倍必要になってしまって、もともとメモリ帯域が厳しいものだからそれは辛い。
そうすると、やっぱり三角形の余り部分は参照するテクスチャが無いほうが望ましい。
無いほうがいいが、例えばテクスチャサイズが2の累乗じゃなかった場合、2の累乗に切り上げられるから、その部分は透明色が置かれてしまっていて、知らないうちにメモリ帯域は食われる。
640*480の1枚絵の背景を描画しようものなら、それはそれは恐ろしいことになると想像できる。
昨日の結果だけを見て諸手を上げて採用できるものではないのだ。
残念なことに。


でもこれのおかげでボトルネックになっている部分はハッキリわかった。
ある程度以上のポリゴンを描画しようと思うとDrawPrimitiveUPは遅く、だから、DrawPrimitiveがあるのだ。
問題になるのはDrawPrimitiveUPの発行回数ではなく、頂点数のようだ。
ということは、現在TriangleFanプリミティブで頂点4つで1スプライト描画しているのを、テクスチャが同じである限りTriangleListでまとめてDrawPrimitiveUPするというアイデアは意味がなさそうに思える。
頂点数が1スプライトあたり6個に増えてしまうからだ。
可能性としては頂点ストリームバッファを作ってDrawPrimitiveする方法ぐらいか。
そしてその方法でパフォーマンスを出そうと思うと、テクスチャを自動でまとめる機能は必須になる。
どういう道筋を辿ったとしても、結局はみんなそこに行き着くことになるということか。