Buffer Object でシェーダーを実行し、シェーダーを使用して他のデータでそれを変更する方法はありますか?
言い換えれば、シェーダーで変更可能な均一なグローバル変数を作成する方法はありますか?
はい。ただし、ハードウェアによって異なります。これらのメカニズムはすべて、GL 3.x 以上に対応したハードウェアを必要とします。
フィードバックの変換
これにより、頂点処理の結果を1 つまたは複数のバッファー オブジェクトに取り込むことができます。
各頂点シェーダーは、入力として与えられた頂点データにしかアクセスできず、出力頂点にのみ書き込むことができるため、これは最も粗雑なメカニズムです。そのため、シェーダーはその前後の頂点にアクセスできません。また、出力の量はかなり制限されており、通常、GL 3.x クラスのハードウェアからの出力値は 4 つだけです。
ジオメトリ シェーダーを使用して、読み書き能力を向上させることができます。フィードバックは VS または GS の後に発生します。
バッファ オブジェクトにレンダリング
バッファ テクスチャは、保存にバッファ オブジェクトを使用するテクスチャです。それらは本当に大きな 1D テクスチャのようなものです。
テクスチャなので、Framebuffer オブジェクトに自由にアタッチしてレンダリングできます。
高さが 1 ピクセルの画像にレンダリングすることの難しさ以外に、この手法の欠点は、ラスタライザーを扱っていることです。完全に正確ではありません。を使用gl_FragCoord
してフラグメント内のどこにいるかを知ることができますが、画像のさまざまな領域に大幅に異なるデータを書き込みたい場合は、問題が発生する可能性があります。
もう 1 つの問題は、FBO のサイズがビューポートのサイズ (通常は 8192 から 16384 程度) によって制限されることです。せいぜい、65536 の個々のフロートを書き込むことができます (バッファ テクスチャがGL_RGBA32F
フォーマットを使用する場合)。したがって、実際に書き込むことができるデータの量は非常に制限されています。
画像のロード/ストア
GL 4.2 のコアであるARB_shader_image_load_storeは、画像データを任意に読み書きするシェーダーの機能を表します。バッファ テクスチャ(バッファ オブジェクトをストレージとして使用するテクスチャ)と組み合わせると、任意にバッファ オブジェクトを読み書きできます。
ハードウェア要件以外の大きな欠点は、無料のランチがないことです。Image Load Store を使用することで、OpenGL の自動メモリ同期システムのすべてを効果的に放棄できます。そのため、書き込みと読み取りのすべての同期を手動で行う必要があります。これは大きな苦痛であり、非常に簡単に台無しにして、理由の手掛かりがなくても未定義の動作が発生する可能性があります。あるプラットフォームでは動作するかもしれませんが、ユーザーのマシンでは動作しません。
このようなものには非常に注意する必要があります。
シェーダー ストレージ バッファー オブジェクト
シェーダー ストレージ バッファー オブジェクトは、実際にはバッファー テクスチャーからのイメージの読み込み/保存にすぎませんが、インターフェースがはるかに優れています。これは、構造体を定義してアクセスするだけのようなものです。
Image Load/Store と同じ欠点が適用されます。また、SSBO は本当に新しいものです。まだ NVIDIA だけがそれを実装しており、その場合でもベータ ドライバーでのみ実装されています。
私はそれがどのように行われたかについて正確にはあまり詳しくありませんが、シェーダーから VBO を変更することはTransform Feedbackと呼ばれることを知っています。OpenGL >=3.0、または OpenGL >= 2.0 にNV_transform_feedback
orEXT_transform_feedback
拡張子が必要です。
より一般的な計算能力が必要な場合は、いくつかのOpenCL/OpenGL 相互運用を試すことができます ...