次のような状況があります。私は OpenGL レンダラー (OpenGL 4.2 なので修正されたものはありません) で作業しています。シェーダーで行うあらゆる種類の画像効果に関連する理由から、ハードウェア ブレンディングは使用しません。2 種類の入力テクスチャを持っています。
1) アルファチャンネル付きの PNG 24。2) アルファチャンネル付きの DDS (DXT5)。
フラグメント シェーダーでは、出力前にアルファを事前乗算します。
フラグメント シェーダー:
outputColor=texture(colorMap,interpolateAtSample(uvsOut , gl_SampleID));
/////// PREMULTIPLY ALPHA //////////
outputColor.a *= alpha;
outputColor.rgb *= outputColor.a;
PNG ベースのテクスチャは問題なく動作します。
しかし、DDS は次のようになります。
光輪+黒縁が見えます。最初に考えたのは、アルファ乗算の問題でした。しかし、その後、DDS のテクスチャ フィルタリングを GL_LINEAR から GL_NEAREST に変更し、ハローとブラック エッジの両方を削除しました。この「ハック」によって問題は本質的に修正されましたが、GL_LINEAR が DDS 圧縮テクスチャにこの種の問題を引き起こす理由を理解したいと思います。
ほとんど忘れていました: pre-multiplication を削除すると、DDS の問題は解決しますが、PNG ベースのテクスチャ用に作成されます。
更新: MSAA 解決の後に来る別のパスがあり、それはブレンド パスです。前述したように、この場合はブレンドを行いませんが、ブレンド シェーダーの出力コードは次のようになります。
///Prevent background bleeding:
blendTex.rgb/=blendTex.a;
//base texture is the texture under the current one.
//This particular technique does "NORMAL" blend-just returns blendTex.
vec4 blendedRes=blendTechnique( baseTex , blendTex) ;
outputColor= vec4( blendedRes.rgb * blendTex.a, blendTex.a);