ブレンドファクター

実行結果

今回のサンプルの実行結果

様々なブレンディング

前回はアルファブレンディングを行なうために、ブレンディングやブレンドファクターの基礎について解説しました。ブレンディングを有効にして様々な設定を行うことで、半透明処理やエフェクト処理を実装できるということがわかっていただけたと思います。

今回は、このブレンディングという奥の深い世界の、さらにさらに深淵へと足を踏み入れます。今回の内容をしっかり理解できれば、あとは創意工夫で様々な演出効果を創出できます。前回と同じように若干わかりにくい部分があると思いますが、がんばって習得してください。

さて、それではまずはおさらいです。

ブレンディングは、色と色を混ぜ合わせる処理の総称で、WebGL では特に、描画元と描画先の二つの色を混ぜ合わせることを主にブレンディングと呼びます。

描画元とは、これから描画されようとしているフラグメントの情報です。逆に描画先とは、既に設定(あるいはレンダリング)済みのフラグメントの情報ですね。描画元の色をどう扱うのか、あるいは描画先の色をどう扱うのか、これらを個別に設定することができるのでしたね。

色をどう扱うのかを決めるのがブレンドファクターでした。ブレンドファクターには様々な種類があり、これらの組み合わせ次第で描画結果は大きく変化します。工夫次第では、透過処理はもちろん、加算合成や反転合成、それ以外にも様々な合成処理を行うことが可能です。

今回のテキストでは、このブレンドファクターの設定方法について、前回よりもさらに細かく見ていきます。また、今回のサンプルでは、手軽にこれらのブレンドファクターを組み合わせることができるような、汎用的なプログラムを作ってみます。

blendFuncSeparate メソッド

前回のテキストでは、ブレンドファクターを設定する方法として blendFunc メソッドを紹介しました。このメソッドを使うと、描画元と描画先にそれぞれ異なるブレンドファクターを設定することが可能でしたね。

実は、WebGL には blendFunc よりもさらに詳細にブレンドファクターを設定できるメソッドが存在します。それが blendFuncSeparate メソッドです。このメソッドは[ Separate ]の語句が示すとおり、何らかの区別を行ないながらブレンドファクターを設定することができます。

それでは、いったい何と何とを区別して、ブレンドファクターを設定するのでしょうか。

そのヒントは、前回のサンプルにあります。

本来、アルファブレンドでは透明度を設定したモデルが半透明で描画されるとき、ブレンドされた結果の色は以下の画像の右側のようになってほしいはずです。ですが、前回のサンプルでは左側のような結果になっていました。

アルファブレンドの比較

前回のサンプルの結果では、半透明でレンダリングしたモデルの色が、少し明るい色になってしまっていますね。どうしてこのようなことが起こってしまったのでしょうか。

実は blendFunc メソッドによって設定されるブレンドファクターは、RGB カラーのほか、アルファ値にも同様のものが適用されます。つまり、RGBA の全ての要素が blendFunc メソッドで指定されたブレンドファクターによって計算されるわけです。これにより、レンダリングされるモデルのアルファ値が影響を受けてしまい、結果的にレンダリング結果がおかしくなってしまっていたのですね。

これを回避するためには、RGBA という色を表す要素のうち、RGB と A とを区別しながらブレンディングを行なう必要があります。そして、これを行なうためのメソッドこそが先ほど書いた blendFuncSeparate メソッドなのです。

このメソッドは引数を四つ取ります。第一、第二引数は、RGB カラーに対するブレンドファクターを指定するために使います。第三、第四引数がアルファ値を扱うためのブレンドファクターを指定する項目になります。

blendFuncSeparate メソッド

第一引数:描画元(SRC)のカラー値に対するブレンドファクター

第二引数:描画先(DST)のカラー値に対するブレンドファクター

第三引数:描画元(SRC)のアルファ値に対するブレンドファクター

第四引数:描画先(DST)のアルファ値に対するブレンドファクター

アルファブレンディングを行なう際の記述例:

gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE);

このように、RGB カラー値とアルファ値をそれぞれ別のブレンドファクターによって処理することで、今まで使っていた blendFunc メソッドよりもさらに多くの演出効果を行うことが可能になります。もちろん blendFunc メソッドだけで事足りる場合もあるでしょうが blendFuncSeparate メソッドを使うことでその可能性はさらに広がります。

色の合成計算方法

少し話が逸れますが、ブレンディングの際にどのように色の計算が行なわれるのか、憶えているでしょうか。これは、以下のような計算でしたね。

最終出力色 = 描画元の色 * sfactor + 描画先の色 * dfactor

描画元の色と、描画先の色とが、ブレンドファクターによって影響を受けた後に足し算されて最終出力の色が決まります。でも、たとえばこの足し算されている現状を、引き算にしたいと考えたとしたらどうでしょうか。

3D レンダリングの世界で、光の表現などによく使われる加算合成という手法があります。これは読んで字の如く、色を加算(足し算)によって計算します。これと似たような手法の一つに、減算合成があります。先ほどの加算合成とは逆に、描画元の色を、描画先の色から減算(引き算)することによって減算合成は行なわれます。

ブレンディングの際の最終出力色は、先ほども示したように加算によって計算されます。これでは、減算合成を行なうことが難しいですね。※もちろん無理ではありませんけども……

色をどのように演算するのかのルールを加算から減算に変更することができたとしたら、減算合成が非常に簡単に行なえそうな気がしますね。そして、WebGL には、キチンとそのためのメソッドも用意されています。それが blendEquation メソッドです。

このメソッドは、引数を一つ受け取ります。引数には、どのように色の演算を行なうのかを表す定数を渡します。定数には三つの種類があり、以下のようになっています。

blendEquation メソッドに指定できる組み込み定数

gl.FUNC_ADD:描画元 + 描画先

gl.FUNC_SUBTRACT:描画元 - 描画先

gl.FUNC_REVERSE_SUBTRACT:描画先 - 描画元

減算合成を行なう場合には、もともと描かれている色から、これから描かれようとしている色を減算処理します。ですから、計算方法としては gl.FUNC_REVERSE_SUBTRACT を指定した場合が正しいことになります。

さて、この色の計算方法ですが、実は blendFunc メソッドがそうであったように、RGB 値とアルファ値を別々に指定できないと困ってしまう場合があります。今回例に挙げた減算処理についても、アルファ値まで減算処理の対象にしてしまうとレンダリング結果がおかしなことになってしまいます。

これに対処するためには blendEquation メソッドの拡張である blendEquationSeparate メソッドを使います。このメソッドを用いれば、色の計算方法を RGB と A とに分けて個別に設定できます。指定できる引数は二つ、第一引数が RGB を扱う演算方法、第二引数がアルファ値を扱う演算方法です。尚、このメソッドに使用できる組み込み定数は blendEquation メソッドのときと全く同じです。

前回のサンプルを blendEquationSeparate メソッドを使って減算合成に切り替えてみると次のようなレンダリング結果が得られます。色が減算されて暗くなっているのがわかりますね。

減算合成

まとめ

少々ややこしい内容でしたが、いかがでしたでしょうか。

今回登場したメソッドは、大別すると[ ブレンドファクターを指定するためのメソッド ]と[ 色を演算する方法を指定するためのメソッド ]に分けることができます。そして、それぞれに、RGB と A 、つまりカラー情報とアルファ情報を別々に処理するための拡張メソッドが存在するのでしたね。

基本的なブレンディングだけであれば、RGB 値とアルファ値を個別に処理する必要はないかもしれません。しかし、アルファブレンディングを正しく行なうという観点だけで見ても、結局はカラー値とアルファ値は別々に処理しなければなりません。

非常に複雑に見えるこれらの指定は、確かに少々難解であると個人的には思います。ただしその反面、プログラマに与えられた自由度や裁量が大きいとも言えます。落ち着いて考えれば理解できる内容だと思いますし、いろいろと変更しながらプログラムを走らせてみれば得られるものも多いと思います。

今回用意したサンプルプログラムでは、HTML の DOM を用いてブレンドファクターや色の演算方法、そのほかモデルのアルファ値などを自由に変更できる仕様になっています。テキストの最後にリンクが貼ってありますので、是非自分で動作させて確認してみてください。

サンプルのソースについては、前回のものに DOM 関連の処理を付け足した感じなのであえて詳細については解説しません。気になる人は実際にソースを見てみてください。

さて、次回は四元数についてやります。四元数はクォータニオンなどと呼ばれ、3D プログラミングの世界では比較的よく見聞きする概念です。少々数学寄りな話になりますが、できる限りわかりやすく解説します。

ブレンディングに定数値を使う

若干わかりにくい部分でもありますので補足として書いておきます。

今回のサンプルでは、ブレンディングに定数値を使うことができるようになっています。というのも、ブレンドファクターの一覧のなかにある gl.CONSTANT_COLOR など、CONSTANT と名の付くブレンドファクターに関してはあらかじめ設定してあった定数値を参照するからです。

今まで解説してきたなかでは gl.SRC_COLOR gl.DST_COLOR など、全て描画元や描画先が関係するブレンドファクターを使ってきました。CONSTANT 系のブレンドファクターは描画元や描画先の色とは関係なく、あらかじめ設定してあった色を使ってブレンディングを行なう際に必要になります。

ブレンディングのための色の定数値を設定する際は blendColor メソッドを使います。このメソッドには単純に RGBA の各要素を表す四つの引数を与えます。尚、既定値として WebGL に設定されている色の定数値は(0.0, 0.0, 0.0, 0.0)で、全て 0 となっています。

色の定数値を指定する記述例は以下のようになりますね。

gl.blendColor(1.0, 1.0, 1.0, 1.0);

上記のようなコードが実行されると、不透明な白がブレンディングの色の定数値に設定されます。CONSTANT 系のブレンドファクターが指定された際にはここで指定された色がブレンディングに使われるようになります。

entry

PR

press Z key