5

各パーティクルが単純なテクスチャを持つクワッドで構成されているパーティクル システム (OpenGL 2.0 ES を使用) を実装しようとしています。

赤いピクセルは透明です

赤のピクセルは透明です。各パーティクルには、50% から 100% までのランダムなアルファ値があります

ここでトリッキーな部分は、Photoshop の「オーバーレイ」のように各パーティクルにブレンドモードを持たせるのが好きで、glBlendFunc() でさまざまな組み合わせを試しましたが、うまくいきませんでした。

フラグメントの現在の色に関する情報が必要なので、フラグメント シェーダーでこれを実装する方法がわかりません。現在の色とテクスチャの色に基づいて新しい色を計算できるようにします。

フレーム バッファ オブジェクトを使用することも考えましたが、パーティクルがそれぞれ重なるときに計算されたフラグメント カラーが必要になるため、フレームごとにパーティクルごとにフレーム バッファ オブジェクトをテクスチャに再レンダリングする必要があると思います。他の。

オーバーレイ計算を再評価する数学およびその他の情報を見つけましたが、これを実装するためにどの方向に進むことができるかを理解するのに苦労しています。

私は次のような効果があることを望んでいます:

オーバーラップするパーティクルとそれらがどのようにブレンドされるか

4

3 に答える 3

11

iOS デバイスのフレーム バッファ内の現在のフラグメント カラーに関する情報を取得できます。プログラム可能なブレンディングは、iOS 6.0 以降 (そのリリースでサポートされているすべてのデバイス) でEXT_shader_framebuffer_fetch拡張機能を介して利用できます。フラグメント シェーダーでその拡張機能を宣言するだけで (ディレクティブを一番上に置くことによって#extension GL_EXT_shader_framebuffer_fetch : require)、現在のフラグメント データを に取得できますgl_LastFragData[0]

そして、はい、それをフラグメント シェーダーで使用して、Photoshop スタイルのすべてを含む任意のブレンド モードを実装できます。差ブレンドの例を次に示します。

// compute srcColor earlier in shader or get from varying
gl_FragColor = abs(srcColor - gl_LastFragData[0]);

この拡張機能は、2 つの色をブレンドしない効果にも使用できます。たとえば、シーン全体をグレースケールに変換できます。通常どおりにレンダリングしてから、最後のフラグメント データを読み取って処理するシェーダーでクワッドを描画します。

mediump float luminance = dot(gl_LastFragData[0], vec4(0.30,0.59,0.11,0.0));
gl_FragColor = vec4(luminance, luminance, luminance, 1.0);

GLSL では、フレームバッファ フェッチを使用せずにあらゆる種類のブレンド モードを実行できますが、そのためには、複数のテクスチャにレンダリングしてから、テクスチャをブレンドするシェーダーでクワッドを描画する必要があります。フレームバッファ フェッチと比較すると、余分なドロー コールと、共有メモリとタイル メモリの間で大量のピクセルをやり取りする必要があります。この方法ははるかに高速です。

その上、フレームバッファ データがカラーでなければならないということはありません... OpenGL ES 3.0 で複数のレンダー ターゲットを使用している場合、1 つのデータを読み取り、それを使用して別のデータに書き込むデータを計算できます。(ただし、GLSL 3.0 では拡張機能の動作が異なることに注意してください。上記の例は GLSL 1.0 であり、ES3 コンテキストで引き続き使用できます。シェーダーでフレームバッファー フェッチを使用する方法については、仕様を参照してください。)#version 300 es

于 2013-10-21T17:48:03.963 に答える
1

次の構成が必要だと思います: ソース: GL_SRC_ALPHA 宛先: GL_ONE。式: GL_ADD

そうでない場合は、取得したいフィルターの計算を説明していただけると助かります。

于 2013-10-18T21:41:36.127 に答える