web-dev-qa-db-ja.com

フラグメントシェーダーとテクスチャのカラーリング

フラグメントシェーダーを使用してテクスチャの色を調整する意味があります。私のフラグメントシェーダーは非常にシンプルです。

uniform sampler2D sampler;

void main() {
  vec4 tex = texture2D ( sampler, uvVarying );
  gl_FragColor = vec4(tex.r, tex.g, tex.b, tex.a);
}

これにより、犬のテクスチャが期待どおりに描画されます。 normal dog

次にシェーダーを

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 1.0);

結果は私が期待したものであり、透明性情報は失われています:

no transparency

しかし、代わりに次のように設定した場合:

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 0.0);

私はそれが完全に消えることを期待していましたが、代わりに私は得ます:

green dog

何が起こっている??

そして私の元の問題に:私はテクスチャに小さな赤い色合いを追加したかった:

  gl_FragColor = vec4(tex.r + 0.5, tex.g, tex.b, tex.a);

今、私はそれが元のテクスチャと同じ透明度情報を持っていると期待していましたが、代わりにこれを取得します:

red dog

ここで何が欠けていますか。テクスチャはsrc = GL_ONE, dst = GL_ONE_MINUS_SRC_ALPHAであるエンジンのデフォルトのブレンドを使用しています。

18
vertti

描画モードは、通常は優れた選択である、乗算済みアルファを想定しています。ただし、RGB値にアルファ値を乗算する必要があります。アルファ値は、そのモードで着信フラグメントに追加される背景の量を制御するだけです。したがって、RGBを「フェードアウト」させるには、それらもアルファ値で変調する必要があります。

このアルファ値をいじって定数にすると、RGB値はその前乗算と一致しなくなります。代わりに、これを赤い色合いにしてみてください。

gl_FragColor = tex + vec4(0.5, 0, 0, 1)*tex.a;

これにより、アルファ変調された赤がテクスチャに追加されます。

画像が完全に消えると予想される場合は、GL_SRC_ALPHA、GL_ONE_MINUS_SRC_ALPHAなどの別の描画モードが必要になりますが、事前乗算されていないアルファ画像が必要になるか、シェーダーで事前乗算を補正します。

gl_FragColor = vec4(tex.rgb/tex.a, tex.a);
31
datenwolf