OpenGL:アルファブレンディング

opengl-blending.png

List of pages tagged with alpha-blending:

基本

glBlendFunc(srcにかかる係数,dstにかかる係数);

ブレンドしないのに等しいものはこれ

glBlendFunc(GL_ONE,GL_ZERO);

普通はこうする

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

属性グループ

属性をオン・オフしたければこうする

glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);

デプステストとアルファブレンディング

デプステストを有効にしてるとアルファブレンディングが変になる問題。
デプステストON ブレンドON デプステストOFF ブレンドON
opengl-blending.png no-depth-blend.jpg

デプステストOFFのほうが、多少不自然でも見た目がごまかせる。

どんな風に変になるか?
背景色とかぶってるのだ。図のように

zバッファは透けて見えるかどうかなんて考えて判定しないのである。
「より手前でなければ無視」という決まりに従うだけの装置なのだ。

解決策

先に不透明なものをzバッファを使って描く。
残った半透明なものをzソート法を使って描く。
半透明同士のものは、zソートして描く。
不透明同士のものはzバッファを使って描く。
不透明より奥にある半透明はzテストで捨てる。
半透明のものを描く時は
glDepthMask(GL_FALSE);
を入れるとうまくいく!!(zバッファにzの値を書かない、ということだと思う。)
これをした後は
glDepthMask(GL_TRUE);にするのをお忘れなく!
関連ページ隠面消去,デプスマスク

理論

ソース(SRC)とは、これから来るフラグメントのこと。現在処理中のフラグメントの色
Destinationとは、既にフレームバッファに詰められている色のこと。背景色と思っていい。
$(R_s,G_s,B_s,A_s)$…..ソースカラーglColor()で渡す色
$(R_d,G_d,B_d,A_d)$….背景色、既にフレームバッファに入っている色
$(S_r,S_g,S_b,S_a)$….ソースカラーに対する計算方程式
$(D_r,D_g,D_b,D_a)$….デスティネーションに対する計算方程式
アルファブレンディングとは次式の様になる。

(1)
\begin{equation} result=(R_sS_r+R_dD_R,G_sS_g+G_dD_g,B_sSb+B_dD_b,A_sS_a+A_dD_a) \end{equation}

この、うち
$(S_r,S_g,S_b,S_a)$….ソースカラーに対する計算方程式
$(D_r,D_g,D_b,D_a)$….デスティネーションに対する計算方程式
を、glBlendFunc()を使って指定してあげるのだ。

単色の場合

glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glColor4f(r,g,b,a);
glDisable(GL_BLEND);
(2)
\begin{equation} result=(r*a+R_d(1-a),g*a+G_d(1-a),b*a+B_d(1-a),a*a+A_d(1-a)) \end{equation}

光り輝くかんじ

glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_DST_ALPHA );
glColor4f(r,g,b,a);
glDisable(GL_BLEND);
(3)
\begin{equation} result=(r*a+R_d*A_d,g*a+G_d*A_d,b*a+B_d*A_d,a*a+A_d*A_d) \end{equation}

テクスチャの場合

透過bmpはむり。pngじゃないとだめ。

テクスチャの設定

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
 
//以下の2つがあった方がいい。じゃないと拡大した時に変な補間されちゃうから。
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
 
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

その他色々なパターン

multiply:乗算

GLES20.glBlendFunc(GLES20.GL_ZERO, GLES20.GL_SRC_COLOR);

GLES20.glBlendFunc(GLES20.GL_ONE_MINUS_DST_COLOR, GLES20.GL_ONE);

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

GLES20.glBlendFunc(GLES20.GL_ZERO, GLES20.GL_SRC_COLOR);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);

サポートサイト Wikidot.com