プログラミング ジオメトリインスタンシング③
あいさつ
どうも、はかせです。
DirectX11だけではないですけども、
手元にちゃんと動くサンプルがないと
なかなか思うように学習って進まないですよね。
今回はジオメトリインスタンシング実装に苦戦中の話です。
場所を弄りたい
パフォーマンスが落ちたということで
同一個所に同一のものを複数描画はできていると思われます。
つまり描画場所さえ弄れればいけそうなとこまで来たということになります。
ということでいくつか試してみました。
DrawIndexedInstancedでオフセット指定
DrawIndexedInstancedメソッドにはインスタンスのオフセットを指定できるようです。
つまりここに値を入れれば場所を弄れるのでは・・・?
さっそくやってみます。
//一番最後の引数がオフセット mDeviceContext->DrawIndexedInstanced(mDrawNum,10,0,0,10);
結果です。
うん、変わらないorz
シェーダーでポジションを弄る
hlslにSV_InstanceIDっていうものがあります。
これはシステム側からインスタンスを用いた時にシステムから
割り当てられるインスタンスIDを取得します。
システム側から自動で割り当てられるのでプログラマーが
入力レイアウトを弄る必要はないです。というかできませんw
この値を使って頂点シェーダーでポジションをずらしてみます。
// 定数バッファ(CPU側からの値受け取り場) cbuffer global { matrix gWVP; float4 gColor; }; Texture2D mTexture : register(t0); //テクスチャー SamplerState mSampler : register(s0); //サンプラー struct VS_INPUT { float4 Pos : POSITION; float2 Tex : TEXCOORD; uint InstanceId : SV_InstanceID; }; // 頂点シェーダから出力される構造体 struct VS_OUTPUT { float4 Pos : SV_POSITION; float2 TextureUV : TEXCOORD; }; // 頂点シェーダ VS_OUTPUT VS(VS_INPUT input) { VS_OUTPUT output; output.Pos = mul(mul(input.Pos, gWVP), input.InstanceId); output.TextureUV = input.Tex; return output; } // ピクセルシェーダ float4 PS(VS_OUTPUT input) : SV_Target { float4 tex = mTexture.Sample(mSampler, input.TextureUV); if (tex.a <= 0) discard; tex *= gColor; return tex; }
結果です。
なんか消えた・・・?
画面外にズレたということでしょうか・・・?
それにしてはタイトルロゴが微塵もずれていない・・・・
成功しているのかもしれませんが
ちょっと望む形とは違いそうです。
シェーダーでテクスチャUVを弄る
とりあえずインスタンスIDを使ってシェーダーから
表示を弄れそうな雰囲気を感じ取れました。
なので弄れるもう一つの値である
テクスチャUVを弄ってみます。
// 頂点シェーダ VS_OUTPUT VS(VS_INPUT input) { VS_OUTPUT output; output.Pos = mul(input.Pos, gWVP); output.TextureUV = mul(input.Tex, input.InstanceId); return output; }
さっきの頂点シェーダーの中身を少し変えました。
さて結果です。
増えたけどなんか違うorz
あとがき
今回はジオメトリインスタンシング実装で悪戦苦闘している話でした。
一番望む結果に近かったのはテクスチャUVですけど
サイズと位置がおかしかったのでこれも没ですね~
うーん・・・
理屈は散々ネット上に落ちてるんですけど
動く実装サンプルがないんですよね。
色々試行錯誤しながらまったりとやっていきますかね。
それでは今回はこの辺でノシ