gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
結果のアルファが
A_final = A_s * A_s + (1 - A_s) * A_d
あなたの例では、黒い三角形(alpha = 1)が描画された後、フレームバッファに描画されたピクセルのアルファは
1 * 1 + (1 - 1) * 0 == 1 + 0 == 1
したがって、完全に不透明になります。次に、白い三角形(alpha = .5)が描画された後、2つの三角形の交点にあるピクセルのアルファは
.5 * .5 + (1 - .5) * 1 == .25 + .5 == .75
つまり、最終的な色は部分的に透明として扱われ、ページと合成されると、ページの背景が透けて見えます。
コンテンツは通常、空の背景に対して合成されるため、これは通常のOpenGLではややまれな問題です。ただし、FBOに描画し、その結果をコンテキスト内の他のコンテンツと合成する必要がある場合に発生します。これに対処する方法はいくつかあります。
1つの方法は、アルファをとブレンドするgl.ONE
ことgl.ONE_MINUS_SRC_ALPHA
です。
A_final = A_s + (1 - A_s) * A_d
これは、アルファブレンディングで通常必要なものです。gl.SRC_ALPHA
ただし、色を、とブレンドする必要がありますgl.ONE_MINUS_SRC_ALPHA
。カラーブレンディング関数とアルファブレンディング関数を別々に設定する代わりに、gl.blendFuncSeparateを使用できます。gl.blendFunc
この場合、あなたは
gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
もう1つのオプションは、アルファが事前に乗算された色を利用することです( WebGLは、たとえば、テクスチャから色をサンプリングするときに、実際に使用していると想定しています)。アルファがすでに色に掛けられた状態で2番目の三角形を描画する場合(つまり、半分透明な白い三角形がにgl_FragColor
設定されているvec4(.5, .5, .5, .5)
場合)、ブレンドモードを使用できます。
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)
であり、混乱を招きます。