フォト

Google AdSense


  • AdSense
無料ブログはココログ

« Visual Studio 2012のノードベースのシェーダエディタのDGSLのファイルフォーマット | トップページ | 梅雨はどこへ行った? »

2012.07.10

DrawInstancedIndirectを使ったインスタンシング描画のカリングメモ

Direct3D11には、DrawInstancedIndirectというGPUから書き込んだバッファを引数に呼べるインスタンシングの描画命令があるのですが、Compute Shaderと連動して使うことはイマイチ使い方のシナリオがわかってませんでした。

この仕組みは、ジオメトリシェーダのストリームアウトプットとDrawAuto系命令の仕組みに近いです。

ID3D11DeviceContext::DrawInstancedIndirect
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476413(v=vs.85).aspx

GPU Experiments: Draw Indirect
http://gpuexperiments.blogspot.jp/2008/12/draw-indirect.html

最近、インスタンシングを書いていてようやく使い道がわかってきました。

インスタンシング描画の際に前のCompute Shaderパスでインスタンシングで描画する全インスタンスのカリングを行ってカリングのテストに通ったモノだけ描画する、みたいな使い方はできるんじゃないかと思います。どうやってデータのフローを構築するかは下記に荒いメモを作りました。

Instance
クリックすると大きなサイズになります


最近の、Tile-based Forward Renderingをやっていると荒いメモでもわかると思います。

まず、Compute Shaderでは視錘台カリング(View Frustum Culling)やオクルージョンカリングしますが、この際にStructured Bufferで全インスタンスのバウンディングボリュームデータを送ります。

Compute Shaderではこれを並列的にカリングテストをします。カリングテストの結果のうち、「カリングテスト通過数」をUAVのバッファに出力、「カリングテストの通過インデックス(インスタンスNo)」をAppend Bufferに登録してリストを作ります。Append Bufferはサイズ不定のバッファで、Compute ShaderからPushしていけるバッファですね。今回はサイズ不定ですが、カリング通過数はUAVに書き出してるので把握は出来ています。

Append and Consume Buffer
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476335(v=vs.85).aspx#Append_and_Consume

Compute Shaderが終わったら、DrawInstancedIndirectで描画します。このときに、「カリングテスト通過数」のバッファを引数にします。

カリングテストの通過インデックス(インスタンスNo)」のリストはBufferのShaderResourceViewとしてセットします。これは、SV_InstanceIDからアクセスします。SV_InstanceIDでBufferの中から現在描画するインスタンスインデックスを取ります。この「インスタンスインデックス」でStruturedBufferのインスタンスデータにアクセスして描画を行います。

とりあえず、かなり荒っぽいけどこれでインスタンシング描画にGPUカリングを付け加えて無駄な描画を押さえることが出来るんじゃないかと思います。

« Visual Studio 2012のノードベースのシェーダエディタのDGSLのファイルフォーマット | トップページ | 梅雨はどこへ行った? »

Programming」カテゴリの記事

画像付き」カテゴリの記事

コメント

That's exactly how I do it too... and as you said on twitter there is a problem when geometries are not instanced! For such reason my current engine does into a single dispatch both lights and geometry culling, (this needs CPU read back and so it is delayed of around 2 frames).
I tho am considering to rewrite the engine to support only instanced geometries.. this easily eats much more VRAM tho.
(ごめんなさい、日本語の書き方は、遅いですよ)
About the culling test I use a method inspired by crysis 3 and frostbite.. (but they do it all in CPU not CS) which uses the depth buffer ( also very similar to tile based light culling , as uses same frustum calculations ), and just a bounding sphere radius value of the instance.

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

« Visual Studio 2012のノードベースのシェーダエディタのDGSLのファイルフォーマット | トップページ | 梅雨はどこへ行った? »