Pentanium Reactor Blog

ゲーム、アニメ、CG、プログラミング

アルファブレンディング

2009年12月22日 02時01分04秒 | プログラミング
なにやらあらぬ誤解が広まっている(?)ようなので書いてみる。
何かというと、iPhoneではアルファブレンディングがおかしいんじゃないか、という話。
もちろん全くそんなことはないんですが、恐らく全ての元凶はこれ。
image = [UIImage imageNamed:@"Sprite.png"].CGImage;
width = CGImageGetWidth(image);
height = CGImageGetHeight(image);
data = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
context = CGBitmapContextCreate(data, ..., kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context, ...);
CGContextRelease(context);
...
glTexImage2D(..., data);


Appleのサンプルでよく使ってるビットマップを取得する処理。一部長いので省略。
iPhoneはPNGをリソースに入れると勝手に最適化されてRGBa8888ではなくなったりする。
そこでオフスクリーンバッファに描画することで、手軽にリサイズもできて適当なビットマップをゲッツ!というとても便利な方法。
ただひとつ注意すべき点があって、このコンテキストは kCGImageAlphaPremultipliedLast だということ。
つまりこれで取得できるビットマップは既にカラーにアルファが乗算された状態になっている
なので、glBlendFuncは(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)ではなくて(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)を使う。
超端折って説明すると、背景がDSTでカラーをCd、アルファをAdとする。
そして今描こうとしてるポリゴンがSRCでカラーをCs、アルファをAsとする。
そうすると、アルファブレンディングの結果は Cs*As + Cd*(1.0 - As) にしたい。
変換したカラーをCs'とするとPremultipliedなので Cs' = Cs*As。
従って Cs' + Cd*(1.0 - As) になればOK。
よってBlendFuncは(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)になる。

で、これだとアルファを指定してフェードとかがうまくできないよ、ということになるわけだがちょっと工夫すれば良い。
描画するときにブレンドの指定にあわせてカラーの指定を少しかえてやる。例えば、
glColor4f( red * alpha, green * alpha, blue * alpha, alpha );
glDrawArray(...);


というようにPremultipliedになるようにカラーにアルファをかける。
これでいわゆるアルファブレンディングと同じようになるはず。

ちなみによくあるようにglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)でやりたい場合はPNGをやめれば確実。
TIFFとかPVRとかから直接ビットマップを読み込んでやればPremultipliedにならない。
そのへんはAppleのPVRTextureLoaderとか木下氏のマイコムの連載のタワーディフェンスの作り方が参考になる。

という訳で駆け足でしたが以上で、PowerVRは悪くないッ!
たかが携帯電話ごときにFBOがついてる上に、最新型にいたってはGLSLまで使わせてくれるGPUが悪い子な訳がないッ!!
というお話でした。


最新の画像もっと見る

4 コメント

コメント日が  古い順  |   新しい順
ありがとうございました (whitedev)
2009-12-22 03:25:33
私があらぬ噂を流してしまった超本人です。スミマセン。。

詳細な解説ありがとうございました!
大変参考になりましたし、長いあいだ悩んでた問題が解決しました。
返信する
気にしないで下さい (c5h12)
2009-12-22 09:40:44
お役に立てたようでなによりです。

しかし寝る前に勢いに任せて書いたので誤字や変な言い回しが多くて恥ずかしいですね。
あとで少し直します。
返信する
ありがとうございます! (ruckygames)
2009-12-22 22:33:41
あらぬ噂が流れるきっかけになった張本人です。

丁度悩んでたタイミングなので、本当にありがとうございました!
返信する
たいしたものではないですが (c5h12)
2009-12-23 03:22:11
こんなものでお役に立てば幸いです。

またステキなアプリができるのを祈ってますw
返信する

コメントを投稿