私は現在、OpenGL とシェーダーについていくつかの調査を行っていglBlendMode
ますが、シェーダーで独自のブレンド モードを使用することと、独自のブレンド モードを作成することの間に根本的な違いがあるかどうかはわかりません。
前者または後者を選択する理由は何ですか? どちらかを選択することで、パフォーマンスのボトルネックはありますか? それとも、これは単に個人的な好みの問題ですか?
私は現在、OpenGL とシェーダーについていくつかの調査を行っていglBlendMode
ますが、シェーダーで独自のブレンド モードを使用することと、独自のブレンド モードを作成することの間に根本的な違いがあるかどうかはわかりません。
前者または後者を選択する理由は何ですか? どちらかを選択することで、パフォーマンスのボトルネックはありますか? それとも、これは単に個人的な好みの問題ですか?
glBlendFunc を使用した従来のブレンドは、シェーダーで複製できません。ブレンディングでは、宛先フレームバッファを変更する前にサンプリングする必要がありますが、これは現在のハードウェアでは実行できません。
現在、色のみを渡すことができ、フレームバッファに書き込む前に GPU のラスタライザによって適用される限定されたブレンド モード (glBlendFunc/glBlendEquation) の 1 つを選択できます。
シェーダーが同じテクスチャーに同時にレンダリングしている間にテクスチャーから読み取る場合、結果は未定義です。これが、glBlendFunc および glBlendEquation を使用した「従来の」または固定機能のブレンディングが役立つ理由です。
従来のブレンドを使用して 2 つのイメージをミックスするには、最初のイメージをレンダリングし、ブレンド モード、関数、方程式を設定して、2 番目のイメージをレンダリングします。これにより正しい結果が得られることが保証されており、通常、透明度などの効果を実現する最速の方法です。
シェーダーで同じ効果を得るには、最初の画像を補助テクスチャにレンダリングし、シェーダーを変更して、2 番目の画像を実際のフレーム バッファーにレンダリングし、フラグメント シェーダーの最終ステップとしてブレンドを行う必要があります。これは通常、テクスチャ読み取りの余分なオーバーヘッドが原因で遅くなり、補助テクスチャにより多くの GPU メモリを使用することになります。
最新のハードウェアでは、2 つの手法の違いはほとんどありません。
私が認識している 3 つの状況では、シェーダー内から OpenGL ブレンディングをシミュレートすることが可能です。
Direct3D11 または OpenGL に相当するものがあり、レンダー ターゲットをピクセル シェーダーで読み取り/書き込みテクスチャとしてバインドします。これにより、任意の複雑なブレンディング操作が可能になりますが、単純なブレンディングでは GPU の特別なハードウェアをバイパスしているため、単純なブレンディングでは高いパフォーマンスが得られません。
エキゾチックな「タイルベース」の GPU があり、単純なブレンドも「アルファ シェーダー」によって行われます。この場合、OpenGL の単純なブレンドと同等のシェーダー コードとの間にパフォーマンスの違いはありません。しかし、そのような GPU を持っている可能性は低く、とにかく OpenGL はこの機能を公開していません。
固定機能のハードウェア ラスタライズ パイプライン全体を回避し、「コンピューティング シェーダー」の複合体として独自のパイプラインを記述します。これを実現できれば、「アルファ シェーダー」のようなものがタイル ベースのパイプラインの一部になりますが、そこに到達するのは大変な作業であり、アルファ ブレンディングは気にする必要はありません。
これは、テクスチャ バリア関数を使用した gl 3.0 拡張機能を使用して実際に実現できます。
http://www.opengl.org/registry/specs/NV/texture_barrier.txt
基本的に、バックグラウンドを書き込んだ後、TextureBarrierNV() 関数を使用してテクセルがフラッシュされていることを確認してから、単一のシェーダー ステージで読み取り/書き込み操作を実行できます (実際には書き込み操作は 1 回だけなので、マルチサンプリング バッファーを避けるようにしてください)。許可されています)。