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