ofxTips-JP

openFrameworksに関する様々なTipsを紹介するブログです。

ofFbo上でのアルファブレンディング

ofFboのバッファ内でアルファブレンディングを行う際、ウィンドウに直接描画するのと同じ方法ではうまくいかない場合があります。

まずはこちらのソースコードと、キャプチャをご覧ください。

ofEnableBlendMode(OF_BLENDMODE_ALPHA);
ofBackground(0, 0, 0);
ofSetColor(255, 255, 255,100);
for (int i = 0;i < 10;i++){
	ofRect(i*30, i*30, 50, 50);
}

f:id:of_tips:20130901175437p:plain

上記ソースを、ウィンドウとFboにそれぞれ描画しています。
左がウィンドウに直接描画したもの、右がFboに描画した後、ウインドウに再度描画したものです。
既に結果が違ってしまっています。アルファ値が、Fboの方が小さいように見えますが、そういうことではありません。次にウィンドウ側の背景色を変更してみます。

f:id:of_tips:20130901175826p:plain

Fbo側では黒い背景に白い四角形を描画したにも関わらず、四角形が赤みがかっています。
これはFbo自体のα値がブレンディングされてしまうため、バッファ自体が半透明になってしまっているのです。

ofEnableBlendMode(OF_BLENDMODE_ALPHA);では、内部的に以下のようなopenGLの命令を呼び出しています。

glEnable(GL_BLEND);
#ifndef TARGET_OPENGLES
	glBlendEquation(GL_FUNC_ADD);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

RGBAについて、アルファブレンドを適用するため、始め背景色のαを最大にしても、Fboに半透明な四角形を描画した場合はその影響でFbo自体のα値が下げられてしまいます。

ではどうすればいいかというと、α値のブレンディングをアルファ合成から加算合成に変更する必要があります。
oFにそのようなメソッドは無いため、直接openGLの命令を書いてあげる必要があります。以下のように記述します。

/*ofEnableBlendMode(OF_BLENDMODE_ALPHA);と差し替える*/
glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,GL_ONE);

通常、ブレンドの係数はglBlendFuncという命令を使っていますが、glBlendFuncSeparateではRGBのブレンド係数とαのブレンド係数を別々に指定します。
αのブレンド係数を加算にしてあげることで、後ろの背景が透けることなくFboを表示することができます。

f:id:of_tips:20130901181637p:plain
適用した状態。赤みが無くなって、後ろの赤が透けなくなったことがわかります。