避免在Firefox中使用texImage2D进行CPU端转换 [英] Avoid CPU side conversion with texImage2D in Firefox

查看:102
本文介绍了避免在Firefox中使用texImage2D进行CPU端转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我在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在调用texImage2DtexSubImage2D时要预乘的数据,并像这样告诉它

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_WEBGLtrue,则浏览器将在上传纹理之前进行预乘法,因此[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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆