每当我在webgl Firefox中使用纹理(Firefox Developer Edition 50.0a2 for OSX,要进行激励)时,在控制台中输出这些警告:
错误:WebGL:texSubImage2D:发生了CPU端转换,即 非常慢
错误:WebGL:texSubImage2D:发生CPU像素转换, 这很慢左错误:WebGL:texSubImage2D:选择格式/类型 招致了一次昂贵的重新格式化:0x1908 / 0x1401
有没有办法避免这种情况?我已经尝试了texImage2D
调用允许的格式和类型的所有组合,但无论我尝试什么,我都可以在CPU上进行转换。
这是一个显示我正在做的事情的最小例子:
var gl = document.querySelector('canvas').getContext('webgl');
var textureSize = 512;
var canvas = document.createElement('canvas');
canvas.width = textureSize;
canvas.height = textureSize;
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(0, 1, 0, 0.0)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fillRect(0, 0, 400, 400);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
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);

<canvas />
&#13;
答案 0 :(得分:1)
您的示例在OSX上的firefox 48中没有打印警告,所以我只能猜测,但
2D画布使用预乘alpha。默认情况下,WebGL对纹理使用非预乘alpha。这意味着为了传输画布纹理的内容,它必须转换为预乘alpha,这取决于实现的方式可能会很慢。
如果你不需要在纹理中使用非预乘alpha,那么你可以通过调用texImage2D
告诉WebGL你想要预乘数据texSubImage2D
和gl.pixelStorei
并告诉它像这样
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
在这种情况下,浏览器可能只是按原样使用画布数据。这可能会使警告消失。请注意,如果您只是上传一次,那么您可能不应该关心。如果您要上传每一帧,那么也许您应该这样做。
请注意,gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
会影响所有纹理上传,包括原始数据。例如
gl.texImage2D(
gl.TEXTURE_2D, 0, gl.RGBA,
1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([128, 192, 255, 128]));
如果UNPACK_PREMULTIPLY_ALPHA_WEBGL
为true
,浏览器会在上传纹理之前进行预乘,以便[255, 255, 255, 128]
成为[64, 96, 128, 128]
。
UNPACK_FLIP_Y_WEBGL
也可能会影响上传速度,具体取决于它在浏览器中的实现方式。