我正在从包含文本的画布生成纹理,问题是当我渲染纹理时,文本的透明部分被完全忽略。
当我渲染纹理时,它看起来像顶部文本,它应该看起来像底部文本。
这就是我生成纹理的方法:
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);
有什么想法吗?
答案 0 :(得分:2)
首先,要在WebGL中使用alpha作为透明度,您必须使用正确的混合方程进行混合。典型的是:
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
我没有看到与您的代码中的混合相关的内容,您是否将其设置在其他位置,您使用了什么混合方程式?
答案 1 :(得分:1)
您必须将UNPACK_PREMULTIPLY_ALPHA_WEBGL
参数设置为true
(pixelStorei
)。这将导致颜色通道乘以Alpha通道,初始值为false
:
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
请参阅WebGL Fundamentals - textures:
这告诉WebGL向
gl.texImage2D
和gl.texSubImage2D
提供预乘的alpha值。如果传递给gl.texImage2D
的数据已经预先乘以Canvas 2D数据,那么WebGL就可以通过它。
参见Khronos规范Premultiplied Alpha, Canvas APIs and texImage2D:
将WebGL渲染的Canvas传递给texImage2D API时,根据传递的画布的premultipliedAlpha上下文创建参数的设置和目标WebGL上下文的
UNPACK_PREMULTIPLY_ALPHA_WEBGL
像素存储参数,像素数据可能会需要更改为或从预乘形式。
此外,您使用TEXTURE_MAG_FILTER
:
NEAREST
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_FILTER
设置为LINEAR
,则会对纹素进行插值,并计算给定坐标周围4个像素的加权平均值。结果是更平滑的外观:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,gl.LINEAR);
另见: