simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

六角柱を敷き詰めたマイクロワールドの構築(メッシュの結合とマルチマテリアル処理)

AIに身体性を与えるためのマイクロワールドの構築3です。

マルチマテリアル処理と、オクルージョンカリングについて記載します。
まずは、パフォーマンスにどれだけ差が出るか、一番簡単で頭の悪い実装を行ってみたいと思います。

以前パーリンノイズで、キューブオブジェクトを配置していくデモを見ましたね。
simplestar-tech.hatenablog.com

こちらのコードを参考に六角柱オブジェクトを配置していくデモシーンを作ってみましょう。

ざっと 180 x 40 個の六角柱を表示したところ 20fps で SetPass call が 14100 回という値でした。
f:id:simplestar_tech:20171009170254j:plain

では、カリングなしで、とりあえず全部同じ GameObject となるように修正してみます。
つまり、巨大な頂点バッファとインデックスバッファとUV座標バッファを構築して、描画するという手段を取ってみます。

先ほどと同じように 180 x 40 個の六角柱を表示したところ 77fps で SetPass call が 19 回という値でした。
パフォーマンスモニターで Draw に要した時間は 0.53 ms でした。
f:id:simplestar_tech:20171009222457j:plain

つまり、描画速度は 94倍アップしました。
さて、試してみてわかったことに、残念ながら全頂点を一つのメッシュに格納できなかったため
180 x 4 個の六角柱ずつ、計10 個のオブジェクトで描画することにしました。

マテリアルが一色なのは、サブメッシュカウントを1にしているためです。
続いて、深度によって色分けされるように追加実装してみます。

f:id:simplestar_tech:20171009230544j:plain

できました。

サブメッシュ数を増やすことで、SetPass call が 67 回と増えてしまいましたが
パフォーマンスモニターで Draw に要した時間を調べたところ 0.64 ms と、そこまでパフォーマンスは落ちませんでした。

対象 Unity シーンは HexRandomMap です。
GitHub にアップしましたので、実装が気になる方はこちらを見てみてください。

github.com

マルチマテリアル処理まで、確認しました。
引き続きオクルージョンカリングについて記載していきますよ!

続く…

2017/10/15 続きです。

まずオクルージョン処理に入る前にいくつか障害があります。
どういう障害なのかもわからないので、一つ一つ具体的にしていく作業から始めます。

なんとなく気づいたこととして
指定した幅と高さが感覚と合わない問題がありました。

これを頑張って解決しました。
以下の絵は 8x8 を指定したときのメッシュ結合結果です。

f:id:simplestar_tech:20171015164340j:plain

これで感覚に沿うようになりました。

X軸に六角形が 8 つ並び、Z軸方向は密に配置されるように交互にオフセットが入るようになっています。

f:id:simplestar_tech:20171015165124j:plain

頂点数と三角形数は、特にカリングが入っていないのでこのような数字となっています。

続いて、ワールドを構成する情報をもとにビジュアライズしていないという問題があります。
こちらも頑張って解決しまして

次のように3次元配列にブロックのあるなしを指定することで

        _mapData[0][0][0] = 1;
        _mapData[0][0][1] = 1;
        _mapData[0][0][2] = 0;
        _mapData[0][0][3] = 1;
        _mapData[1][0][0] = 1;
        _mapData[0][1][0] = 1;

f:id:simplestar_tech:20171015230428j:plain

3次元空間のブロックの積み重ねをメッシュ結合ともとに、ビジュアライズできるようにしました。

そして残るは、接合している表示されることのない三角形や、完全に埋もれてしまう頂点をメッシュから除去する仕組みが入っていない問題があります。

例えばこれ、8x8x8の結合メッシュですが
f:id:simplestar_tech:20171015231715j:plain

こんなに頂点数や三角形数はいらないはずなんです。

こちらを頑張って解決することにしました。

f:id:simplestar_tech:20171016232843j:plain

頑張ると、こんな感じで頂点数や三角形数が減りました。
これ以上減らすことは不可能なので、頑張るのはここまでにします。

試しに1000万ブロックを敷き詰めたマイクロワールドを描画してみました。
f:id:simplestar_tech:20171016231940j:plain
プロファイラーで確認したところ、81.8FPS の Wait for FPS が 91% の 11.79ms でした。
つまり、描画に要している時間は 0.92 ms ほどでした。
f:id:simplestar_tech:20171016233727j:plain
ブロック一つ一つにゲームオブジェクトを割り当てた最初の簡単なアプローチと比べて
大幅にパフォーマンスアップしました。

あとはコード整理ですが、ひとまず六角柱を敷き詰めたマイクロワールドの構築がイメージに近づいてきた
(マルチマテリアル処理と、オクルージョンカリングについて記載した)ので、次の記事に進みます。