1

YUV チャンネルを受け取るコードがあり、OpenGLES を使用してそれらを描画しています。基本的に、それらを組み合わせたシェーダーがあります。

結果にシャープ フィルターを追加したいと思います (次の例を使用: http://igortrindade.wordpress.com/2010/04/23/fun-with-opengl-and-shaders/ )

実際の結果で別のシェーダーを実行する方法がわかりません (以前のシェーダーがすべてのチャネルを 1 つのフレームに結合した後に実行したいため)。

私の現在のコードは次のようになります。

            glUniform1i(texLum, 0);
            glUniform1i(texU, 1);
            glUniform1i(texV, 2);

            glEnableVertexAttribArray(positionLoc);
            glVertexAttribPointer(positionLoc, 
                                  4, 
                                  GL_FLOAT, 
                                  GL_FALSE, 
                                  0, 
                                  &vertices[0]);

            glEnableVertexAttribArray(texCoordLoc);
            glVertexAttribPointer(texCoordLoc, 
                                  2, 
                                  GL_FLOAT, 
                                  GL_FALSE, 
                                  0, 
                                  &texCoords[0]);


            glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_BYTE, &indices[0]);

最後の行 (glDrawElements) の直前に新しいシェーダーを追加する必要があると思いますが、それを呼び出す方法がわかりません。

私のシェーダーは次のようになります。

    static char const *frag = 
    "uniform lowp sampler2D texLum; \n"
    "uniform lowp sampler2D texU; \n"
    "uniform lowp sampler2D texV; \n"
    "varying mediump vec2 texCoordAtFrag; \n"
    "void main() { \n"
    "   lowp float Y = texture2D(texLum, texCoordAtFrag).r; \n"
    "   lowp float U = texture2D(texU, texCoordAtFrag).r; \n"
    "   lowp float V = texture2D(texV, texCoordAtFrag).r; \n"
    "   lowp float R = 1.164 * (Y - 16.0 / 256.0) + 1.596 * (V - 0.5); \n"
    "   lowp float G = 1.164 * (Y - 16.0 / 256.0) - 0.813 * (V - 0.5) - 0.391 * (U - 0.5); \n"
    "   lowp float B = 1.164 * (Y - 16.0 / 256.0) + 2.018 * (U - 0.5); \n"
    "   gl_FragColor = vec4(R,G,B,1); \n"
    "}\r\n";

    static char const *vert = 
    "varying mediump vec2 texCoordAtFrag; \n"
    "attribute vec4 Position; \n"
    "attribute vec2 TexCoord; \n"
    "void main() { \n"
    "   texCoordAtFrag = TexCoord; \n"
    "   gl_Position = Position; \n"
    "}\r\n";

texLum、texU、texV は、チャネルを保持するテクスチャです。

4

1 に答える 1

1

Sharpen は畳み込みフィルターであるため、9 つの入力値を読み取って 1 つの出力値を生成します。そのため、その前に別のシェーダーが発生し、一度に 1 つのピクセルを操作する場合、2 つのステップ (最初に YUV 変換、2 番目にシャープ化) でそれらを実行して、計算の繰り返しをなくすことには十分な議論があります。シェーダーを閉じたボックスとして組み合わせる最も簡単な方法でもなかった場合.

それらをライブで結合する場合は、YUV 変換を別の関数に分割し、シャープ フィルターで の代わりにその関数を呼び出しますtexture2D。GL シェーダー コンパイラーには、関数を再利用するための通常のプログラミング ルートに従うことができるように、コンパイルされたプログラムを正確に作成するために相互にリンクできるソース ファイルの数に制限はありません。

1 つを実行してからもう 1 つを実行したい場合は、中間のレンダリングからテクスチャへの段階を使用します。YUV 変換を実行し、バッファを切り替えて、その出力をシャープへの入力として使用します。

実際には、前者は実際には後者よりも高速である可能性があります。これは、YUV 変換がおそらく高速な操作であるためです (たとえば、YUV から RGB への変換は 1 つの行列乗算です)。すごく高価。パフォーマンスが問題になる場合は、おそらくプロファイリングする必要があります。

編集:したがって、現在のメインからそれを適応させることができます(ここに入力しました。エラーを許してください):

"uniform lowp sampler2D texLum; \n"
"uniform lowp sampler2D texU; \n"
"uniform lowp sampler2D texV; \n"
"varying mediump vec2 texCoordAtFrag; \n"
"lowp vec4 yuvTexture2D(mediump vec2 coord) { \n"
"   lowp float Y = texture2D(texLum, coord).r; \n"
"   lowp float U = texture2D(texU, coord).r; \n"
"   lowp float V = texture2D(texV, coord).r; \n"
"   lowp float R = 1.164 * (Y - 16.0 / 256.0) + 1.596 * (V - 0.5); \n"
"   lowp float G = 1.164 * (Y - 16.0 / 256.0) - 0.813 * (V - 0.5) - 0.391 * (U - 0.5); \n"
"   lowp float B = 1.164 * (Y - 16.0 / 256.0) + 2.018 * (U - 0.5); \n"
"   return vec4(R,G,B,1.0); \n"
"}\r\n

次に、sharpen フィルターで、 への呼び出しを への呼び出しに置き換えますtexture2D(<whatever>, coord)yuvTexture2D(coord)これは、sharpen シェーダーのソース リストにフラグメントを含めるか、プログラムにリンクするかのいずれかです。マトリックスアプローチの使用への切り替えに関しては、あなたが望むと思います(入力を簡単にするために、文字列定数以外の形式にします):

uniform lowp sampler2D texLum;
uniform lowp sampler2D texU;
uniform lowp sampler2D texV;
varying mediump vec2 texCoordAtFrag;

const mediump mat4 yuvToRgb = 
mat4(   1.164,  1.164,  1.164,  -0.07884, 
        2.018, -0.391,    0.0,  1.153216,
        0.0, -0.813,    1.596,  0.53866, 
        0.0,      0.0,    0.0,  1.0);

lowp vec4 yuvTexture2D(mediump vec2 coord) {
   lowp vec4 yuv = 
         vec4(
             texture2D(texLum, coord).r,
             texture2D(texU, coord).r,
             texture2D(texV, coord).r,
             1.0)
   return yuvToRgb * yuv;
}
于 2012-04-12T21:50:59.087 に答える