個別のスプライトを大きなテクスチャ1枚にまとめて、そこからテクスチャを貼り付けることで高速化できる。
1.テクスチャをバインドせよ(いまからこのテクスチャを使うよ) 2.ポリゴンを描画せよ1 3.テクスチャをバインドせよ(いまから新しいテクスチャを使うよ) 4.ポリゴンを描画せよ2 5.テクスチャをバインドせよ(いまから新しいテクスチャを使うよ) 6.ポリゴンを描画せよ3
この時のテクスチャのバインドに非常に時間がかかる。つまりポリゴン毎にテクスチャを指定するときテクスチャのバインド、ポリゴン描画を繰り返すので、描画コストは6となる。
テクスチャ3枚を大きな1枚にすることで、この描画時の処理負荷を減らすことができる。たとえばこんな感じで描画コストは4にすることができる
この場合、毎回異なるテクスチャから読み込んできた場合,2x20x20=800のコストとなるが 同一テクスチャの場合1 + 20x20 = 401となり、約半分のコストにまで下げることができる
大きなテクスチャをバインドするときには小さいテクスチャをバインドするよりも時間がかかる 最悪の場合、2倍のテクスチャサイズだった場合2倍かかることもありうる(ハードウェアにもよるっぽい)
画像の「Order」とは現在描画リクエストを行っている図形(スプライト含む)の数
「Sub」とは同一の図形描画のリクエスト数を表してる
Subに含まれるものの条件は以下。
この条件は、途中でレンダリング用のコマンドが変わらないことを示している。
この条件に当てはめて数をかぞえてみると、だいたい70%くらいがSubに含まれる。
本当は2247個の図形に対して2247個分のZソートを行って描画することになるが
Subに含まれているものはプライオリティが同じなので274個(2247-1973)個のオブジェクトに対してのみZソートをすればいいことになる。(厳密にはもう少し多くなるが)
もともとライブラリ側では同じリクエストが来た時にそのレンダリングコマンドを排除する仕様になっているので、描画時の負担はそんなに変わらないがCPUパワーでソートしている部分が少なくなると効率がいい。
Cocos2Dxなんかのスプライトバッチの特性(Zが制御出来ないが高速)をみていると、もしかしたらポリゴン描画時のレンダリングコマンドを最小化したものとしては同じやり方なのかもしれない。
いまのライブラリでソフトでポリゴンモデルの描画を行う場合、40000ポリゴン程度のものであっても、テクスチャ付き三角形の描画リクエストを40000個発行することになる。当然Zソートでもこの40000個は計算対象に入ってしまうため負荷は膨大だった。
ポリゴンモデルはモデルどうしてめり込まれるとそれはそれで厄介だし、そもそも2D用のライブラリで3Dゲームを作るのはナンセンスなのであるが、部分的にポリゴンに頼りたい時もある。そこで、自動的に前回の図形と同じものはZソートに含めず、同一プライオリティで描画してしまえばZソートのオーダーに含めずに描画できてしまう。
3Dゲームを2D座標に割り当てるのではなくスプライトの代わりに3Dモデルを動かすというのが技術的に完全に2Dのプライオリティに支配された3Dモデル表示となるため、これはこれでよだれがでる。つまりどんだけ立体的に描画しても、2Dの土俵におけるその3Dモデルはペラペラなのである。これはいい。完全に2Dゲームのプレイフィールで3Dモデルを表示できるのがいい。
横スクロールにおける、面倒な戦車の砲塔回転なんかで威力を発揮できそう。
調子にのってコマンドを7万個くらい発光したアタリから表示がバグりだした。そういえばインデックスバッファとか頂点バッファって65535個が限界だったような。。。さらに同じプリミティブの描画で再帰的に関数を読んでいたらスタックがオーバーフローした。スタックの件は必要のないローカル変数を外に出してしまえば問題は解決できる。