新しいシェーダーモデルで、ターゲットフレームバッファーからピクセル値を読み戻すサポートがあるかどうか疑問に思いました。これは、描画パイプラインの後の(プログラム不可能な)段階ですでに行われていると思います。これにより、この機能がプログラム可能なパイプラインに追加された可能性があります。
テクスチャにバインドされたフレームバッファに描画してから、このテクスチャをシェーダーに送信できることを認識しています。同じ機能を実現するためのよりエレガントな方法を望んでいました。
新しいシェーダーモデルで、ターゲットフレームバッファーからピクセル値を読み戻すサポートがあるかどうか疑問に思いました。これは、描画パイプラインの後の(プログラム不可能な)段階ですでに行われていると思います。これにより、この機能がプログラム可能なパイプラインに追加された可能性があります。
テクスチャにバインドされたフレームバッファに描画してから、このテクスチャをシェーダーに送信できることを認識しています。同じ機能を実現するためのよりエレガントな方法を望んでいました。
Andrewが指摘しているように、フレームバッファへのアクセスは論理的にフラグメントシェーダーとは別のステージであるため、フラグメントシェーダーでフレームバッファを読み取ることはできません。これの理由(アンドリューの質問に答えるため)は、グラフィックスパイプラインのパフォーマンスと順序付けの要件の組み合わせです。レンダリングパイプラインの定義方法では、フレームバッファブレンディング操作は、パイプラインの先頭に入った三角形/プリミティブと同じ順序で実行する必要があります。一方、フラグメントシェーダーは、任意の順序で発生する可能性があります。したがって、それらを別々のステージにすることで、GPUは、入力が利用可能になったときに、それらの間で同期することなく、フラグメントシェーダーを可能な限り高速に実行できます。フラグメントシェーダーの出力を保持するのに十分なバフファースペースを維持している限り、
フラグメントシェーダーがフレームバッファーを読み取る方法がある場合、それらの読み取りが順番に行われるようにするために何らかの同期が必要になるため、処理速度が大幅に低下します。
いいえ。おっしゃるように、テクスチャへのレンダリングはその機能を実現する方法です。
GPUパイプラインのブロック図を見ると、ブレンディングステージ(フラグメントシェーダーの出力とフレームバッファーを組み合わせるもの)がフラグメントシェーダーとは別であり、機能が固定されていることがわかります。
私はGPUデザイナーではないので、その理由を推測することしかできません。おそらく、フレームバッファへのアクセスを高速に保ち、フラグメントシェーダーステージをフレームバッファから分離して、より適切に並列化できるようにすることです。マルチサンプリングなどの問題もあると思います。
(ほとんどの場合、固定機能のブレンドで「十分」であることは言うまでもありません。)
実際、これはDirect3D 11 SM 5.0で実行できるようになったと思います(テストはしていません)。
メソッドを使用してUAVの読み取りおよび書き込み操作を許可するために、UAVをPS5.0にバインドできますOMSetRenderTargetsAndUnorderedAccessViews
。
その場合、レンダリングするスワップチェーンのバックバッファーはフラグを使用して作成する必要がありますDXGI_USAGE_UNORDERED_ACCESS
(私は推測します)。
これは、DXSDKOIT11サンプルで使用されます。
Shader_framebuffer_fetch拡張子を使用して、フラグメントシェーダーのフレームバッファーの内容を読み戻すことができます。サポートをGPUに追加すると、パフォーマンスがいくらか低下する可能性があります。実際、私は最近、家電市場でよく知られているGPUブランドのOpenGLES2.0ドライバーにこの拡張機能のサポートを追加するために取り組んでいます。
(レンダーターゲットビューを使用して)テクスチャTEXに描画し、それを(シェーダーリソースビューを使用して)別のシェーダーへの入力としてバインドできます。TEXはpseduo-framebufferです。