2017-09-14 14 views
1

テキストを含むキャンバスからテクスチャを生成していますが、テクスチャをレンダリングするときに透明部分が完全に無視されるという問題があります。Webglでテキストテクスチャを生成する:アルファが不透明です

comparision

私はそれが下のテキストのようになりますときには、トップのテキストのように見えるテクスチャをレンダリングします。

これは私がテクスチャを生成する方法である:

canvas.width = textRendBuffC.measureText(text).width*2; 
canvas.height = parseInt(fontStyle, 10)*1.5; 
c.clearRect(0, 0, canvas.width, canvas.height); 
c.font = fontStyle; 
c.fillStyle = colorStyle; 
c.fillText(text, 0, parseInt(fontStyle, 10)); 


var canvasTexture = gl.createTexture(); 

gl.bindTexture(gl.TEXTURE_2D, canvasTexture); 
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true); 

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas); 

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,gl.NEAREST); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,gl.NEAREST); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 
gl.bindTexture(gl.TEXTURE_2D,null); 

そして、これは私がテクスチャを描画する方法である:

gl.bindBuffer(gl.ARRAY_BUFFER, spritePlan.vertBuffer); 
gl.vertexAttribPointer(currentShader.sh.vertexAttribLocation, spritePlan.vertBuffer.itemSize, gl.FLOAT, false, 0, 0); 
gl.bindBuffer(gl.ARRAY_BUFFER, spritePlan.texCoordBuffer); 
gl.vertexAttribPointer(currentShader.sh.textureCoordAttribute, spritePlan.texCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); 
gl.bindBuffer(gl.ARRAY_BUFFER, spritePlan.colorBuffer); 
gl.vertexAttribPointer(currentShader.sh.colorAttribLocation, spritePlan.colorBuffer.itemSize, gl.FLOAT, false, 0, 0); 

gl.activeTexture(gl.TEXTURE0); 
gl.bindTexture(gl.TEXTURE_2D, tex); 
gl.uniform1i(currentShader.sh.sampler2DUniform, 0); 

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, spritePlan.indexBuffer); 
setMatrixUniforms(); 

gl.drawElements(gl.TRIANGLES, spritePlan.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0); 
gl.bindTexture(gl.TEXTURE_2D, null); 
gl.bindBuffer(gl.ARRAY_BUFFER, null); 
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 

そして、これは、フラグメントシェーダが通過するコードです:

vec4 tex = texture2D(sampler2DUniform, vTextureCoord); 
gl_FragColor = vec4(tex.rgb, tex.a); 

アイデア

+1

あなたの解決策を回答に追加し、それを受け入れ、質問から削除してください。[ツアー] –

答えて

1

UNPACK_PREMULTIPLY_ALPHA_WEBGLのパラメータをtruepixelStorei)に設定する必要があります。これは、アルファチャネルによって乗算されるカラーチャンネルの原因となる初期値はfalseある:

gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); 

WebGL Fundamentals - texturesを見る

これはgl.texImage2Dgl.texSubImage2Dにあらかじめ乗算アルファ値を供給するためのWebGLを伝えます。 gl.texImage2Dに渡されたデータがキャンバスの2Dデータのように既に事前に乗算されている場合、WebGLはそれを単に渡すことができます。

参照クロノス仕様Premultiplied Alpha, Canvas APIs and texImage2D

通過キャンバスのpremultipliedAlphaコンテキスト作成パラメータの設定及びUNPACK_PREMULTIPLY_ALPHA_WEBGL画素ストアパラメータに応じて、その後、texImage2D APIにWebGLのレンダリングキャンバスを渡します目的のWebGLコンテキストのピクセルデータは、事前に乗算された形式に変更する必要があります。


さらに、あなたはNEARESTとテクスチャPARAMTER TEXTURE_MAG_FILTERを設定します。

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,gl.NEAREST); 

Sampler ObjectのためのKhronos OpenGLのリファレンスを参照してください:

倍率フィルタはGL_TEXTURE_MAG_FILTERテクスチャによって制御され、パラメータ。この値は、GL_LINEARまたはGL_NEARESTです。 GL_NEARESTが使用されている場合、実装はテクスチャ座標に最も近いテクセルを選択します。これは一般に「ポイントサンプリング」と呼ばれます。 GL_LINEARが使用されている場合、実装は最も近い隣接サンプル間の加重線形ブレンドを実行します。

これは、NEARESTを使用すると、テクスチャの座標に従って最も近いテクセルがテクスチャから読み込まれることを意味します。これにより、外観が硬くて角張っています。
テクスチャパラメータTEXTURE_MAG_FILTERLINEARに設定すると、テクセルが補間され、指定された座標を囲む4つのピクセルの加重平均が計算されます。また

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,gl.LINEAR); 


参照:すべての

+0

私は解決策を見つけました:gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL、true); これは、WebGLに対して、gl.texImage2Dおよびgl.texSubImage2Dに事前に乗算されたアルファ値を供給するように指示します。 gl.texImage2Dに渡されたデータがキャンバスの2Dデータの場合のように既にプリミキシングされている場合、WebGLはそれを単に渡すことができます。 – Elias

2

まず、WebGLの中で透明性とアルファを使用するためにあなたが持っている結果はスムーズな外観です正しいブレンド方程式とのブレンドを可能にする。代表的なものは次のとおりです。

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

私はあなたが何をブレンド式を使用しない、他の場所でそれを設定しなかった、あなたのコード内でブレンドに関連するものを見ていませんか?

+0

答えの2番目の部分 - 「コードにブレンドに関連するものは何もありません。他の場所に設定しましたか、どのようなブレンド式を使用しますか?」 - あなたの答えの一部ではなく**質問へのコメントでなければなりません。 – Rabbid76

+1

完全にあなたに合っていますが、私はコメントを投稿するのに十分な評判がないので、どうすればいいですか? :) –

関連する問題