Posted at

OpenGL(GLES2.0)のアルファブレンドで透過処理した画像が黒っぽくなる。

More than 1 year has passed since last update.


透過画像を表示したい

先週くらいからOpenGLに入門しているのですが、全然理解できません。

新人の頃に戻ったような気分で、この手探りな感じがまた良いですね。(趣味でやってるので)

ちなみに、環境はAndroidで、今のところ2Dのみ。


余談

入門中によく訪問しているサイト。

大変お世話になってます。

https://wgld.org/

http://tkengo.github.io/blog/2014/12/20/opengl-es-2-2d-knowledge-0/

https://bluefish.orz.hm/sdoc/opengles.html

あと、本買いました。

https://www.amazon.co.jp/dp/4877832947


本題


OpenGL(GLES2.0)のアルファブレンドで透過処理した画像が黒っぽくなる

お前は何を言っているのか?

アルファブレンドで透過処理した画像が黒っぽくなるんです。

とりあえず、やっていることは、


  • テクスチャを生成する

  • ビットマップを読み込む

  • テクスチャとビットマップを紐づける

  • テクスチャのサイズとかを設定

  • テクスチャを描画する

という、いたって普通(と思われる)手順で描画しています。


用意した画像

red.png

こんな感じの画像。

周りに広がるにつれて、透過しています。


このまま表示すると

アルファブレンドを有効にしないとこんな表示。

縦長になっているのは置いておいて。。

スクリーンショット 2018-07-09 15.26.22.png


透過させたい

こうすると良いよ、ってどっかに書いてあったのでコピペした。


draw.java

        GLES20.glEnable(GL_BLEND); //アルファブレンドを有効にする

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); //ブレンド方法を指定
// なんか描画
GLES20.glDisable(GL_BLEND); //無効にしておく

スクリーンショット 2018-07-09 15.30.36.png


黒っぽくない?

あー透過できたできた。

と思ったけど、ちょっと黒っぽい。

重ねるとこうだ。

スクリーンショット 2018-07-09 15.33.07.png

いや、黒いよね。これは。

なんか思ってた透過処理と違う!

OpenGLむずいわー。

やってらんねー。


GL_ONEというパラメータ

とか独り言を言いながら調べてたら、合成方法で違うパラメータを指定できそうだったので試してみた。


draw.java

    GLES20.glEnable(GL_BLEND); //アルファブレンドを有効にする

GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); //ブレンド方法を指定
// なんか描画
GLES20.glDisable(GL_BLEND); //無効にしておく

スクリーンショット 2018-07-09 15.35.57.png

おぉ!白っぽい!


重ねた時の違いは顕著

スクリーンショット 2018-07-09 15.37.55.png

あー。これこれ!

求めていたやつ!


青と赤でも


GL_SRC_ALPHAの場合

スクリーンショット 2018-07-09 16.17.57.png

黒い。。。


GL_ONEの場合

スクリーンショット 2018-07-09 16.18.37.png

やっぱこれだわ!


この挙動について

他にも色々指定できるようで、

まとめてくれている方がいました。

わりと何を言っているのか分からないんですが。。。


私なりの解釈


GL_SRC_ARPHAの時

元画像のRGBそれぞれに、元画像のアルファ値をホニャホニャした数値を乗算している気がする。

いや、正確には乗算しているかどうか分からないので、違うかもしれません。

例えばこんなRGBaがあったとして

(1.0, 0.0, 0.0, 0.5)

これは、アルファ0.5の赤色なわけですが、0.5がホニャホニャされた値が乗算されて

(0.5, 0.0, 0.0, 0.5)

とかそんな値になっているような。。。

だとすると、確かに黒に近づくので、挙動と一致している気がする。


GL_ONEの時

元画像のRGBそれぞれに、1を乗算しているっぽい。

ので、まぁ、そのままの色が出力される。


やりたいことはなんとなくできたので

一旦これでよしとします。

でも合ってるのか不安。多分、何か違うんでしょうね。

アプリの完成は遠いなぁ。。。