フォト

Google AdSense


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

« モバイル用の13インチディスプレイを買ったので接続してみた | トップページ | AMD Radeon HD 7900シリーズのデモのメモ »

2012.01.30

Compute Shaderの話 Pixel Shaderに比べた優位性とか

最近、ようやく現役復帰してきたので、Compute Shaderなんかを書くことが増えてきました。

EA DICEのFrostbite 2.0とかわりとCompute Shaderを上手に使ったエンジンなどが出てきているわけですが、どの辺がCompute ShaderがPixel Shaderに対して優位かなどと言った点もわかってきました。そんなわけで、そんな話。

コンピュート シェーダーの概要
http://msdn.microsoft.com/ja-jp/library/ee417833(v=vs.85).aspx

・出力周り、UAVとか
Pixel Shaderでは、1つのプログラムが1つのピクセルの計算結果を出力する(Multiple Render Targets : MRTsを使えば複数のレンダーターゲットも行けます)わけですが、出力先の座標に関しては任意の場所に出力したり同じレンダーターゲットの複数のピクセルに出したりとかといったことはできません。

Compute Shaderの場合、Unordered Access View(UAV)というのがレンダーターゲットみたいなものなのですが、こちらは任意のアドレスに対してデータを書き込めて、読み込みもシェーダで出来ます。Pixel Shaderではこれから書き込みピクセルにすでに入っている値を読み出すことができません(一部のGPUだとレンダーターゲットテクスチャをセットしながら使えるかも)が、Compute Shaderでは実質的にはそれができます。

書き込みに関しては、1つのCompute Shaderプログラムが1つのアドレスに出力では無く複数の箇所に書き込んだりも出来ます。

ちなみに、実はPSでもUAVは1つだけ使えるのですが、PSには後述のスレッドグループの概念やスレッドグループ共有メモリなどは無いです。

・スレッド周り
Pixel Shaderでは1つのシェーダプログラムが扱うのは1つのピクセルの処理(MRTsの場合は、レンダーターゲットの数分)ですが、Compute Shaderでは1スレッドという単位になります。Compute Shaderでは、スレッドグループと言って複数のスレッドをまとめた概念があります。1つのスレッドグループはDirect3D11では、1024スレッドまでになります。

スレッドグループには32KBのスレッドグループ共有メモリがあって、スレッドグループ内のスレッドが読み書きして同期をとったりができます。ただ、複数のスレッドが読み書きするのでAtomic処理やメモリバリアなどの処理が発生します。この辺の話は次。

・1スレッドグループ = 1タイル
Battlefield 3のTile-based Deferred Renderingなどでは1つのスレッドグループが256スレッド、16x16ピクセル単位の処理をします。これはCompute Shader的には1スレッドグループですが1タイルと呼びます。BF3では、16x16ピクセルの1タイルの空間に何個のライトがライティング処理に使われるか計算することで、旧来のフルシーンでやるDeferred Renderingよりも効率的に計算を行います。

BF3では、16x16ピクセルの空間に対して、ライトのバウンディングボリュームが交差するかどうかを計算してカリングをしているようです。タイル単位でやることでPer-pixelでやるよりも計算量が減るメリットがあります。

テクスチャのようなものをCompute Shaderで処理する際には、アルゴリズムによってはタイル単位で処理することで、Pixel Shaderでフルシーンに対して同じ処理を行うよりも速くできることがあります。なお、Tile-based Deferred Rendering以外にもHorizon-Based Ambient Occlusion(HBAO)などもスレッドグループ共有メモリを使ったアルゴリズムの方が速いようです。

NVIDIA SDKのHorizon-Based Ambient Occlusion using Compute Shadersの概要を参照のこと
http://developer.nvidia.com/nvidia-graphics-sdk-11-direct3d

それから最近だとRadeon HD 7970のサンプルでもタイルベースの処理をしてるようです。

Specifically, this demo uses DirectCompute to cull and manage lights in a scene. The end result is a per-pixel or per-tile list of lights that forward-render based shaders use for lighting each pixel.

http://developer.amd.com/samples/demos/pages/AMDRadeonHD7900SeriesGraphicsReal-TimeDemos.aspx

Compute Shaderで流行ってるタイルベースの処理というのは、「周囲の近傍ピクセルでまとめてやった方がいいアルゴリズム」というのをスレッドグループ単位でスレッドグループ共有メモリを使って実現するということですね。

・まとめ
とりあえず、上のあたりの話題からデータの構造によってはCompute Shaderの方が便利な機能があって効率的ということですね。この辺の発想を使ったネタは海外ではどんどん出てきているので追いかけていかないと。ようやく最近、現役復帰してきたので置いてかれないようにしないと。

« モバイル用の13インチディスプレイを買ったので接続してみた | トップページ | AMD Radeon HD 7900シリーズのデモのメモ »

Programming」カテゴリの記事

コメント

コメントを書く

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

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

« モバイル用の13インチディスプレイを買ったので接続してみた | トップページ | AMD Radeon HD 7900シリーズのデモのメモ »