半透明の要素を描いたFBOを描画する際のハマりポイント
TL;DR
不透明ピクセルに半透明ピクセルをアルファブレンディングした結果は半透明だから気をつけような!
現象
- FBOを背景色(不透明)でクリアする
- FBOに半透明の要素を描画する
- FBOをウィンドウに描画する
- ウィンドウ背景色が透過して見える
例:黒でクリアしたFBOに白い半透明の矩形を描き、赤背景のウィンドウに描画した結果
何が問題なのか・どうなってほしいのか
FBOの背景色が不透明なのに、ウィンドウ背景色が見えているのが問題
ウィンドウ背景が透けてほしくない
原因
不透明要素の上に半透明要素をアルファブレンディングした結果が半透明であること。
つまりFBO内の半透明要素を描画した領域のアルファ値は1より小さくなること。
アルファブレンディングの計算式(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
の場合)
out = src\cdot src_a+dst\cdot (1-src_a)\\
(src: 描画色, dst: 背景色, out: 結果)
アルファ値のみに着目すると
out_a = src_a\cdot src_a+dst_a\cdot (1-src_a)\\
つまり$dst_a$が1(背景が不透明)の場合、
out_a = src_a^2-src_a+1 \qquad (dst_a=1)\\
\therefore \left\{
\begin{array}{ll}
out_a \lt1 & (0\lt src_a\lt 1) \\
out_a = 1 & (src_a=\{0,1\})
\end{array}
\right.
となり、半透明要素を描画するとその結果が半透明となることがわかる。
ちなみに以下は背景色と描画色とから結果のアルファ値がわかるグラフ
https://www.desmos.com/calculator/azbx3o4tn9
対処
対処1 : アルファ値の計算に別の式を使う(OpenGL)
FBOに半透明要素を書き込む際に以下のどちらかを指定しておく。
不透明背景に描く場合はどちらでも結果は1になるので変わらない。
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,GL_ONE);
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE);
参考:
ofFbo上でのアルファブレンディング - ofxTips-JP
Alpha Blending の2種類の算出方法と使い分け – NEAREAL
対処2 : FBOをブレンディングなしで描画する
FBOの背面に何も描画しない場合はこちらがシンプル。
glDisable(GL_BLEND);
fbo.draw();
Author And Source
この問題について(半透明の要素を描いたFBOを描画する際のハマりポイント), 我々は、より多くの情報をここで見つけました https://qiita.com/nariakiiwatani/items/df3eb6a49be0fa431387著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .