2012-07-17 7 views
5

WebGLキャンバスに平面色とテクスチャを描画しています。私の色とテクスチャはアルファ値が異なり、正しくブレンドしたいと思っています。私は透明な背景が必要です(キャンバスの下にあるHTMLコンテンツとブレンドする必要があります)。 WebGLのでWebGLのHTML背景との融合

、私は、HTMLの背景が黒である場合には、正しく動作

gl.clearColor(0, 0, 0, 0); 
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 
gl.enable(gl.BLEND); 

を使用しています。しかし、背景としてJPGパターンを設定すると、黒い三角形(アルファ= 1)と白い三角形(アルファ= 0.5)を描くので、三角形が交差する場所で背景パターンを見ることができます。これは正しい動作ですか?

答えて

11

私の以前の回答は実際には間違っていました。そのです。

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)は、得られるアルファはあなたの例で

A_final = A_s * A_s + (1 - A_s) * A_d 

ある(アルファ= 1)黒三角形が描画された後、フレームバッファに描画された画素が

1 * 1 + (1 - 1) * 0 == 1 + 0 == 1 
のアルファを有することを意味します

これで完全に不透明になります。 (アルファ= 0.5を有する)を白色の三角形が描画された後、次に、二つの三角形の交点のピクセルは、最終的な色は、部分的に透明として扱われることを意味

.5 * .5 + (1 - .5) * 1 == .25 + .5 == .75 

のアルファを有するであろう、そしてページと合成されると、ページの背景が表示されます。

通常、コンテンツは空の背景に対して合成されるため、通常のOpenGLではやや珍しい問題です。しかし、FBOに描画して、結果を他のコンテンツと合成する必要があります。これに対処するにはいくつかの方法があります。

一つの方法は、そう、あなたは通常、アルファブレンドで欲しいものである

A_final = A_s + (1 - A_s) * A_d 

を取得gl.ONE_MINUS_SRC_ALPHAgl.ONEであなたのアルファブレンドを持つことです。しかし、あなたの色はまだgl.SRC_ALPHAgl.ONE_MINUS_SRC_ALPHAと混ざりたいです。 gl.blendFuncの代わりにgl.blendFuncSeparateを使用して、カラーブレンド機能とアルファブレンディング機能を別々に設定することができます。このケースでは、

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

別のオプションがあらかじめアルファが乗算された色を活用することで呼び出します(これWebGL actually already assumes you are using、例えば、テクスチャから色をサンプリングする場合)。あなたがアルファを持つ第2の三角形を描く場合は、すでにカラー(その半分透明の白い三角形がvec4(.5, .5, .5, .5)gl_FragColorセットを持っているでしょう)、あなたがブレンドモード

gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) 

を使用することができますし、それはあなたが必要として動作しますを通じて掛け色とアルファの両方のために。

2番目のオプションはWebGLの例でよく見られるものです(前述のように、WebGLはすでに色が事前に乗算されていると仮定しています)(vec4(1., 1., 1., .5)はガモット外、レンダリング出力は未定義、ドライバ/ GPU必要な狂った色を出力することができます)。普通のOpenGLの例ではgl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)を見るのがはるかに一般的です。これは混乱を招きます。

+0

非常にありがとう、あなたは素晴らしいです! :) gl.blendFuncSeparate()を使うことにしました。 私はあらかじめ乗算されたアルファを使用しようとしましたが、私のテクスチャはあらかじめ乗算されていないので変です。私はgl.texImage2D(gl.TEXTURE_2D、0、gl.RGBA、gl.RGBA、gl.UNSIGNED_BYTE、bd.image)を使用します。 ?どのように私はそれを事前に変更することができますか? –

+0

デフォルトでは、テクスチャはロードされても事前に生成されません。テクスチャをインポートするときにブラウザが自動的に色をアルファで掛けるようにするには、texImage2Dを呼び出す前にテクスチャパラメータを設定する必要があります。上にリストしたtexImage2Dコールの前に 'gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL、true);を呼び出すでしょう。 WebGL仕様のピクセルストレージパラメータノートを参照してください。http://www.khronos.org/registry/webgl/specs/latest/#PIXEL_STORAGE_PARAMETERS –