はかせのラボ

私の頭の中を書いていく雑記ブログです

プログラミング ジオメトリインスタンシング⑨

あいさつ

どうも、はかせです。
今回は前回やったシェーダーインスタンシングを色々試してみた話です。
ちなみにほぼ失敗談ですw

試そうとしたこと

前回やったシェーダーインスタンシングでは、
定数レジスタに固定長の行列配列を置き、
その値をSV_InstanceIDというシステムから自動で格納される値をキーにして
各オブジェクトごとの情報をシェーダーに渡すというものでした。

ここで発生した問題は
一度に生成できるオブジェクトに限りが生まれることです。

どうせやるなら状況に応じて生成数を変えたいものです。
ということで色々試してみました。

配列要素数を増やしてみた

これは単純に配列要素数を増やすことで
上限があるもののまぁこれだけあれば足りるでしょうみたいな
長さで置いてみたというものです。

cbuffer global
{
    matrix gWVP[2048];
};

端的に言えば数がそこまでないならできなくはないです。
ただ2048でコンパイルエラーが発生しました。(おそらく容量オーバー)
1024では通りました。

matrixはfloat4x4でfloat4x4はfloatの16倍のサイズです。
そしてfloatは4byteなので
4 * 16 * 2048 = 65,536byte
およそ65KBぐらいが定数レジスタの容量っぽいですね。
(厳密には入力レジスタとかの兼ね合いで変動しそうですが)

うーん・・・
正直1024程度じゃねぇといった感じですね。
なくはないですが、あまりいい方法ではなさそうです。

配列を変数でしてみた

cbuffer global
{
    int length;
    matrix gWVP[length];
};

こんな感じで定数レジスタに置く配列を可変長っぽくすることで
柔軟に対応ができるのではないかという試みです。

これは試したところコンパイルが通らなかったので
そもそもシェーダーとして破綻してるっぽいです(´;ω;`)

std::vectorで渡してみた

シェーダーの固定長は仕方ない。
ただしCPU側は領域を柔軟にしてもいいのではないかという判断のもと
渡すデータをvectorに格納してやってみました。

結果です。
f:id:hakase0274:20190612230557p:plain

はい、何も出ません。
まぁかたや固定長、かたや可変長
そも論データ型自体ちげーよって話ですよねw
(こうなるとは思っていた)

あとがき

今回はシェーダーインスタンシングで色々試してみた話でした。
やってみての感想はシェーダーインスタンシングはあまり実用的ではなさそうという感じです。

というのもわざわざインスタンシングするってことは
何万とオブジェクトを出したいんだと思うんです。
そんな状況下で同時に1024程度じゃ正直微妙かなと。

では、シェーダーインスタンシング以外で何があるんだという話ですよね。
今度はそれを探し、実装して、弄ってみたいと思います。
なんか入力レジスタが~みたいなのは見つけたので
あとは私の頭がどれだけ理解できるかにかかってますね。

それでは今回はこの辺でノシ