避免在Firefox中使用texImage2D进行CPU端转换 [英] Avoid CPU side conversion with texImage2D in Firefox
问题描述
每当我在webgl Firefox中使用纹理时(确切地说,是OSX的Firefox Developer Edition 50.0a2),都会在控制台中输出以下警告:
Whenever I use textures in webgl Firefox (Firefox Developer Edition 50.0a2 for OSX, to be excact) outputs these warnings in the console:
错误:WebGL:texSubImage2D:发生CPU端转换,即 非常慢
错误:WebGL:texSubImage2D:发生了CPU像素转换, 这非常慢
错误:WebGL:texSubImage2D:选择的格式/类型 重新格式化的费用很高:0x1908/0x1401
Error: WebGL: texSubImage2D: Incurred CPU-side conversion, which is very slow
Error: WebGL: texSubImage2D: Incurred CPU pixel conversion, which is very slow
Error: WebGL: texSubImage2D: Chosen format/type incurred an expensive reformat: 0x1908/0x1401
有什么办法可以避免这种情况?我已经尝试了texImage2D
调用的所有允许的格式和类型的组合,但是无论尝试如何,我都可以在CPU上进行转换.
Is there any way to avoid that? I have tried all combinations of allowed formats and types for the texImage2D
call, but I get conversion on the CPU no matter what I try.
以下是显示我在做什么的一个最小示例:
Here is a minimal example showing what I am doing:
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 />
推荐答案
您的示例在OSX的firefox 48中不会打印警告,所以我只能猜测,但是
Your sample doesn't print warnings in firefox 48 on OSX so I can only guess but
2D画布使用预乘alpha.默认情况下,WebGL对纹理使用未预乘的Alpha.这意味着要传输画布纹理的内容,必须将其转换为预乘alpha,具体取决于实现方式可能很慢.
A 2D canvas uses premultiplied alpha. WebGL, by default, uses un-premultipled alpha for textures. That means in order to transfer the contents of the canvas texture it has to be converted to premultiplied alpha which depending on how that's implemented could be slow.
如果不需要在纹理中使用未预乘的alpha,则可以通过调用gl.pixelStorei
告诉WebGL在调用texImage2D
和texSubImage2D
时要预乘的数据,并像这样告诉它
If you don't need un-premultiplied alpha in your texture then you can tell WebGL you want premultiplied data when called texImage2D
and texSubImage2D
by calling gl.pixelStorei
and tell it like this
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
在这种情况下,浏览器可能只能按原样使用画布数据.这可能会使警告消失.请注意,如果您只是上传一次,则可能不必理会.如果您要上传每一帧,那么也许应该.
In this case the browser can possibly just use the canvas data as is. This might make the warning go away. Note if you're just uploading once you probably shouldn't care. If you're uploading every frame then maybe you should.
请注意,尽管gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
会影响所有纹理上传,包括原始数据.例如
Be aware though that gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
effects ALL texture uploads including raw data. For example
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]
.
if UNPACK_PREMULTIPLY_ALPHA_WEBGL
is true
the browser will do the premultiplication before uploading the texture so [255, 255, 255, 128]
will become [64, 96, 128, 128]
.
UNPACK_FLIP_Y_WEBGL
可能还会影响上传速度,具体取决于在浏览器中的实现方式.
UNPACK_FLIP_Y_WEBGL
might also affect upload speeds depending on how it's implemented in the browser.
这篇关于避免在Firefox中使用texImage2D进行CPU端转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!