ドキュメントにあるように、アルファ合成に使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
していました(実際、Direct3Dドキュメントでも同じことが言われていました)。
GPU から結果をダウンロードして PNG 画像にするまでは、最初はすべて問題ありませんでした。結果のアルファ成分が間違っています。描画する前に、フレーム バッファを不透明な黒色でクリアしました。そして、半透明のものを描いたら、フレームバッファが半透明になりました。
まあ理由は明白です。ではglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
、宛先アルファ チャネルを実際に無視し、常に 1 であると想定します。フレーム バッファを不透明なものとして扱う場合、これは問題ありません。
しかし、正しいアルファ値が必要な場合はどうでしょうか? glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
ソースを事前に乗算します (事前にテクスチャ/頂点カラーを乗算するか、アルファ コンポーネントを gl_FragColor に設定する前にアルファ コンポーネントで乗算します)。
glBlendFunc は元の色成分を 1 つの係数で乗算することしかできませんが、アルファ合成では宛先に と の両方one_minus_src_alpha
を乗算する必要がありdst_alpha
ます。したがって、事前に乗算する必要があります。フレーム バッファで事前乗算を行うことはできませんが、ソースと宛先の両方が事前乗算されている限り、結果は事前乗算されます。つまり、最初に事前に乗算された色でフレーム バッファーをクリアし (たとえば、0.5, 0.5, 0.5, 0.5
の代わりに 50% 透明な白1.0, 1.0, 1.0, 0.5
)、事前に乗算されたフラグメントをその上に描画するとglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
、結果に正しいアルファ チャネルが含まれます。ただし、最終結果に望ましくない場合は、事前乗算を元に戻すことを忘れないでください。