0

フラグメントの色を変更したいフラグメントシェーダーを作成しました。たとえば、受け取った色が黒の場合は、青に変更する必要があります。

これは私が使用しているシェーダーです:

uniform sampler2D mytex;

layout (pixel_center_integer) in vec4 gl_FragCoord;

uniform sampler2D texture1;

void main ()
{
    ivec2 screenpos = ivec2      (gl_FragCoord.xy);
    vec4  color     = texelFetch (mytex, screenpos, 0);

    if (color == vec4 (0.0,0.0,0.0,1.0)) {
        color = (0.0,0.0,0.0,0.0);
    }

    gl_FragColor = texture2D (texture1, gl_TexCoord[0].st);
}

そして、ここに私が取得しているログがあります:

警告: -1:65535: 'GL_ARB_explicit_attrib_location': 拡張機能は現在の GLSL バージョンでは使用できません

警告: 0:1: 'texelFetch': 関数は現在の GLSL バージョンでは使用できません

私は警告を認識していますが、とにかくコンパイルするべきではありませんか? シェーダーは私がやりたいことをしていません。誰かが理由を説明できますか?

4

1 に答える 1

1

1 つには、GLSL 実装では使用できない関数を使用しています。これらを呼び出した結果は未定義です。

ただし、ここでのキッカーは、このシェーダーの値とgl_FragColorまったく関係がないことです。colorしたがって、texelFetch (...)ロジックが実際に正しく機能したとしても、 の値を変更しcolorても最終出力には何も影響しません。スマート コンパイラはこれをノーオペレーションと見なし、効果的にシェーダーを次のように削除します。


uniform sampler2D texture1;

void main ()
{
  gl_FragColor = texture2D (texture1, gl_TexCoord[0].st);
}


それが十分でない場合texelFetch (...)、このシェーダーではまったく不要です。シェーダーの現在のフラグメントに対応するテクセルをルックアップしたい場合、テクスチャが描画先のビューポートと同じ寸法を持っている場合は、実際に使用できます。texture2D (texture1, gl_FragCoord.xy);これは、GLSL のデフォルトの動作がgl_FragCoord、フラグメントの中心 (x+0.5, y+0.5) - これは、テクスチャ内の対応するテクセルの中心でもあるため (解像度が同じ場合)、テクスチャ フィルタリングによってサンプルが変更されることを心配することなく、従来のテクスチャ ルックアップを実行できます。結果。

texelFetch (...)正規化された座標を使用せずにテクスチャで明示的なテクセルを取得できます。これは、「成長した」長方形テクスチャのようなものです:) マルチサンプル テクスチャを使用していて特定のサンプルが必要な場合、またはバイパスしたい場合に一般的に役立ちます。テクスチャ フィルタリング (ミップマップ レベルの選択を含む)。この場合、それはまったく必要ありません。

これはおそらくあなたが本当に望んでいるものです (OpenGL 3.2):


#version 150

uniform sampler2D mytex;
uniform sampler2D texture1;

layout (location=0) out vec4 frag_color;
layout (location=1) out vec4 mytex_color;

void main ()
{
  mytex_color = texture2D (mytex, gl_FragCoord.xy);

  // This is not black->blue like you explained in your question...
  //   ... This is generally opaque->transparent, assuming 4th component = alpha
  if (mytex_color == vec4 (0.0,0.0,0.0,1.0)) {
    mytex_color = vec4 (0.0);
  }

  frag_color = texture2D (texture1, gl_TexCoord[0].st);
}

古い GLSL バージョンではglBindFragDataLocation (...)、データの場所を手動で使用および設定するか、変数gl_FragData[n]の代わりに使用する必要があります。out

ここでの本当の問題は、サンプリング元のテクスチャの色を変更したいように見えることです。それは機能しません。せいぜい 2 つのフラグメント データ出力を使用する必要があります。サンプリング元と同じテクスチャへの書き込みは、非常に制御された状況下で行うことができますが、一般的に行うことは、テクスチャ間でピンポンを行うことです。つまり、1 つのテクスチャからフェッチし、別のテクスチャに書き込み、元のテクスチャを参照する後続のすべてのレンダー パスを、書き込んだばかりのものと交換する必要があります。

複数のレンダリング ターゲットの描画の詳細については、 「フラグメント データの場所」を参照してください。

于 2013-08-14T19:10:37.830 に答える