今回は、多数の立方体を描画するためのメモリ使用量削減について検討しました。
具体的には
1.頂点法線の見直し
2.インデックスバッファの使用
3.GL_TRIANGLE_STRIPの使用
の3つです。
ひとつひとつ削減量を確認して行きます。
1.頂点法線の見直し
まず頂点法線ですが、これは主に3Dオブジェクトを滑らかに描画するために使用されます。いわゆるシェーディング表現のためが主です。
私がやろうとしてるのはマイクラのパクリです。マイクラの世界は四角形ばかりですよね?なので不要です。
ただし、明るさの情報は欲しいので追加します。
ひとつの頂点に必要な情報として、
4バイト x 3軸(位置) + 4バイト x 3軸(向き) + 4バイト x 2軸(テクスチャ) = 32バイト
が
4バイト x 3軸(位置) + 4バイト(明るさ) + 4バイト x 2軸(テクスチャ) = 24バイト
となるので、25%の情報を削減出来ます。
なお、明るさ情報だけで4バイトもいらないので、この部分には将来的に別の情報も追加出来ると思っています。
2.インデックスバッファの使用
前回、立方体を作るには、先ず3角形を2つ組み合わせて4角形を、4角形を6つ組み合わせて立方体を作ることとしました。頂点数は3*2*6=36となります。でも、これって無駄ですよね?
本来、立方体に必要な頂点数は4つで良いはずです。
技術的には、頂点バッファオブジェクトを使う場合は36必要ですが、インデックスバッファを使うと4つで済むようになります。
ただし、インデックスバッファ分が余分に増えます。
インデックスバッファのデータ型は、short(2バイト)にしたいのですが、これだと多数の立方体を作るには足りないので、long(4バイト)にします。
1つの立方体の情報量はインデックスバッファを使わない場合、
36(頂点数) * 24(1頂点あたりの情報量) = 864
で、使う場合は、
4(頂点数) * 24(1頂点あたりの情報量) + 36(インデックスバッファ) * 4(long) = 240
となり、約72%削減できます。
3.GL_TRIANGLE_STRIPの使用
インデックスバッファは、GL_TRIANGLEを使うと一つの立方体に36個必要ですが、GL_TRIANGLE_STRIPを使えば14個で済みます。詳しい話はしませんが済むんです。ただし、離れた立方体を描画するのに”区切り”の情報が欲しいのでもう1個(OpenGLES3.0の場合は区切り情報1個で済みます)必要です。ですので合計15個になります。
よって、
4(頂点数) * 24(1頂点あたりの情報量) + 36(インデックスバッファ) * 4(long) = 240
が
4(頂点数) * 24(1頂点あたりの情報量) + 15(インデックスバッファ) * 4(long) = 156
で、更に35%削減できます。
以上、1から3を全て行う前と後で比べると、
36(頂点数) * 32(1頂点あたりの情報量) = 1152バイト
が
4(頂点数) * 24(1頂点あたりの情報量) + 15(インデックスバッファ) * 4(long) = 156バイト
となるので、約86%の情報を削減出来ます。
これならば、例えば 100 * 100 * 100 で合計100万個の立方体を描画したとしても、
156 * 100 * 100 * 100 = 156MB
となり、iPhoneで動きそうですね。削減前だと1GB超えます。ただ、iPhone6sなら削減前でも動きそうです。
自分も思考するためのメモリ使用量を削減して、頭の中の少ないメモリを有効活用したいです。
★☆★ 次回の作業 ★☆★
メモリ量削減の構想に従って実装作業を行う。