回答:
これはハードウェアの制限です。フラグメントシェーダーはプログラム可能なパイプラインの一部ですが、ターゲットバッファーとの最終的なカラーブレンドは、この時点で広く利用可能な/コモディティハードウェアでプログラムできません(ブレンドステートを介して構成可能ですが、任意に書き込むことはできません) GPUの組み込みのブレンド操作を置き換えるコード)。
このためにハードウェアが構築されていない理由は、おそらくGPUが超並列であるという事実に関係しています。一度に多くのフラグメントを処理します。これらのフラグメントのいくつかは最終的に宛先バッファ内で相互作用する可能性がありますが、フラグメント処理の非同期性のために、フラグメントが処理されて最終的な色が放出されるまではどのように知ることができません...常に決定論的に発生するわけではありません。
最終フレームでピクセルAがピクセルBの後ろにあるからといって、ピクセルAが常にフラグメント処理を完了し、特に複数のレンダリングフレームにわたってフラグメントBの前に宛先に書き込まれることを意味しません。そのため、ピクセルBの処理中に宛先バッファーから読み取られる値は、常にピクセルAであるとは限りません。クリアな値になる場合もあります。
そのため、フラグメントステージで直接宛先バッファーの読み取りを許可しないことは、シェーダープログラマーがブレンドステージを完全に作成する際の実際の技術的制限よりも、その読み取りから潜在的に非決定的な結果を取得することで足を撃つことを止めることとはるかに関係があると思いますプログラム可能。読み取り操作を厳密に制御することで(たとえば、深度テスト)、GPUは読み取り値で実行される操作が何らかの意味を持つようにします。
そうは言っても、コスト/便益の問題があるかもしれません。GPUパイプラインのその側面をプログラム可能にすると、チップ設計が多少複雑になり、宛先バッファーの読み取りの必要性/要求は他の機能と比較して比較的低くなります。
面倒なことですが、ハードウェアメーカーは、多くの透過的な方法でレンダリングプロセスを最適化する柔軟性を得ることができます。
たとえば、PowerVRハードウェア(長い間使用されていなかった)はレンダリングされるシーン全体が送信されるまで待機してから、ペインターアルゴリズムを使用して自動深度ソートを実行し、実際に生成する必要はありません深度バッファ。画面をタイルに分割し、それぞれを順番にレンダリングします。
次の理由により、ピクセルシェーダーは色および深度バッファーから読み取ることができません。
ピクセルAとBはハードウェアでまったく同じ瞬間にシェーディングされますが、Bは最終的にピクセルAの上(「後」)にレンダリングされます。
ハードウェアがBの前にAをシェーディングすることが保証されるようにした場合、ハードウェアの一部はAがシェーディングされている間は何もせずに動き、Bはシェーディングされている間はハードウェアの一部は何もせずに動きます。
考えられる最悪の場合、シェーディングしたすべてのピクセルが互いに重なり合ってレンダリングされ、1つを除く数千のGPUスレッドがアイドル状態になります。この1つのスレッドは、ピクセルA、B、Cを辛抱強くシェーディングします...