Firefox WebGL 2.0 RGBA纹理奇怪的行为

时间:2017-09-07 23:03:23

标签: firefox textures webgl alpha

我拼命寻找某个地方来讨论我在firefox中发现的这个奇怪的错误。但似乎很难见到一些mozilla工作人员。

上下文非常简单:WebGL 2.0,使用着名的fontmap技术和点精灵来绘制文本。

一张图片优于1000字:

Firefox vs Chromium

在右边的Chromium上,一切正常,在左边的Firefox ...和uhhggh?!

问题:

  • 为什么Firefox中的文字是黄色的,尽管它应该是白色的?

  • 为什么文本在firefox中有奇怪的黑色像素?

  • 这似乎是一种"锐化"过滤...但为什么?

一些细节:

  • 这两个浏览器的代码完全相同。

  • 使用" off-screen"生成fontmap纹理。画布,这是RGBA,RGB全白色和characteres打印在alpha通道。我在两个浏览器上验证了生成的图片,它们不完全相同,但都显示正常(没有奇怪的像素也没有黑色边框等等),问题似乎不在这里

  • WebGL纹理是RGBA / RGBA / UNSIGNED BYTE(像往常一样),MIN和MAG过滤到NEAREST,没有mipmap,WARP S / T Clamp到边缘(但这没什么改变,所以它没有&#39

  • 生成的纹理是NPOT,但我不认为问题在这里。

  • 用于呈现文本的Blend等式是(通常)SRC_ALPHA,ONE_MINUS_SRC_ALPHA

  • 我测试了混合设备SRC_ALPHA,ONE,在这种情况下,Firefox正常运行(但添加混合不是我想要的!)。

  • Firefox版本:55.0.2(64位)适用于Ubuntu的Mozilla Firefox

  • Chromium版本:60.0.3112.113基于Ubuntu构建,在Ubuntu 16.04(64位)上运行

这是片段着色器(使用Point-Sprite绘制每个char):

precision highp float;
in float chr_c;
uniform vec4 material_col;
uniform sampler2D spl2d_col;
vec2 chr_u; 
out vec4 fragColor;
void main(void) {
  chr_u.x = (gl_PointCoord.x + mod(chr_c, 48.0)) * 0.020833333;
  chr_u.y = (gl_PointCoord.y + floor(chr_c / 48.0)) * 0.020833333;
  fragColor = texture(spl2d_col, chr_u) * material_col;
}

以下是用于生成fontmap纹理的代码:

var i, s, x, y, m, w, h, a, o, mx, cv, ct;

mx = c*c; // 'c' is rows/columns count, (here: 48 rows * 48 cols)

cv = document.createElement('canvas');
ct = cv.getContext('2d');

x = 0;
y = 0;
m = 65535;

// determins the size for cells according chars size
for(i = 0; i < mx; i++) {
  s = String.fromCharCode(i);
  w = ct.measureText(s).width;
  h = ct.measureText(s).height;
  if(x < w) x = w;
  if(y < h) y = h;
  if(y < m && (y > 0)) m = y;
}

var r = Math.ceil((y+(y-m)>x)?y+(y-m):x);

w = r * c;
h = r * c;

cv.width = w;
cv.height = h;

ct.fillStyle = 'rgba(255,255,255,0.0)';
ct.fillRect(0, 0, w, h);

ct.font = 'normal ' + p + 'pt ' + f;
ct.fillStyle = 'rgba(255,255,255,1.0)';
ct.textAlign = 'left';
ct.textBaseline = 'top';

for(i = 0; i < mx; i++) {

  a = Math.floor(i % c); // cell Easting (Abscisse a = X)
  o = Math.floor(i / c); // cell Northing (Ordonnée o = y)

  ct.fillText(String.fromCharCode(i), (a*r)+3, (o*r)+2);
}

var gl = this._gl;
this._blank_fnt = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this._blank_fnt);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, ct.getImageData(0,0,w,h));
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);

cv.remove();

这是用于绘制文本的(简化)代码:

gl.enable(gl.BLEND);
gl.depthMask(gl.TRUE);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);

gl.useProgram(le_shader);
gl.activeTexture(gl.TEXTURE0);

gl.uniformMatrix4fv(le_uniform1, le_view.matrix);
gl.uniformMatrix4fv(le_uniform2, le_transform.matrix);
gl.uniform4fv(le_uniform3, le_text.color);

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.bindTexture(gl.TEXTURE_2D, this._blank_fnt);

gl.bindVertexArray(le_text.vao);
gl.drawArrays(gl.POINTS, 0, le_text.count);

0 个答案:

没有答案