アルファブレンドの罠
プログラムの話です。
アルファブレンド、といえばゲームを作る上で欠かせない合成方法ですよね。RGBでのカラーチャンネルに加えてアルファチャンネルを使う、アレです。
Photoshopだと「通常」という合成方法がそれなのですが、実はゲームでいうアルファ合成と、Photoshopのアルファブレンドは合成に使う計算式が微妙に異なります。
Photoshopの合成は正統派のアルファブレンドですが、DirectXとかOpenGLのアルファブレンドは簡易版です。背景画像に対して前景画像を重ねるとすると、正統派の方法では背景アルファと前景アルファの両方を考慮して合成後の色を決めますが、簡易版だと前景アルファだけ使い、背景アルファは無視します。また、合成後のアルファ値も異なります。正統派合成ではアルファの計算とRGBの計算には異なる式を使いますが、ゲームでの合成にはアルファとRGB全てで同じ式を使います。
わざわざ分けるのも面倒だし、アルファもRGBと同じ計算で合成しちゃおう、みたいな。
ちなみにアルファとRGBで異なる合成式を使いたい場合はセパレートブレンドという機能を使います(必ず使えるという保証はありません。利用可能かどうかは、DirectXなら D3DRS_SEPARATEALPHABLENDENABLE の値をチェックします)
これは個人的な想像ですが、こうなった理由は簡易版の式でも充分期待通りのRGBが得られるのと、そもそも画面の背景のアルファ値を考慮する必要がない、背景のアルファ値をキッチリ計算する必要がないからだと思います。画面の背景というのは文字通り一番奥の絵ですから、それが半透明になったとして一体何が透けてみえるの?という状況になるだけなんですよね。背景のアルファは使う機会がないんです。常に完全不透明扱いでOKですから。
ただ、これは画面をアルファ付きのスケリーンショットとして保存して、これを別の画像にアルファ合成しようとした時に問題になります。画面のアルファ値がわりと適当な値になっているので、思った通りには合成できません。
プログラムで、完全透明の背景に半透明の画像を何枚か重ねたものをpngで出力したものと、Photoshopで完全透明の背景に半透明のレイヤーを重ねたものをpngで出力したものは異なるという事です。
これをPhotoshopと同じ方法で合成させようとしたら自分でシェーダープログラムを書いて使うしかないので、気をつけてください(セパレートブレンドを使っても無理だったハズ)。
※ちなみにこれはDirectX9での話です。最新版だとどうなんですかね?