Firefox "This operation requires zeroing texture data" 使用 Webgl 时出现警告
Firefox "This operation requires zeroing texture data" warning when using Web GL
在 firefox 中打开我的 (JS HTML5) 项目时,我收到警告:"Error: WebGL warning: drawArrays: This operation requires zeroing texture data. This is slow."
有人告诉我这是因为试图读取超出范围的像素或类似的东西。
这是我的代码:
var gl = Gra.gl
// texture
var tex = gl.createTexture()
gl.bindTexture( gl.TEXTURE_2D, tex )
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, AppImg )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR )
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 )
var bff_pos = BufferFromArr([
-1, -1,
1, -1,
-1, 1,
1, 1
])
var bff_tex = BufferFromArr([
0, 1,
1, 1,
0, 0,
1, 0
])
// buffer
var wd = 200
var ht = 200
// texture
var tex2 = gl.createTexture()
gl.bindTexture( gl.TEXTURE_2D, tex2 )
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, wd, ht, 0, gl.RGBA, gl.UNSIGNED_BYTE, null )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR )
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 )
// framebuffer
var frame = gl.createFramebuffer()
gl.bindFramebuffer( gl.FRAMEBUFFER, frame )
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2, 0 )
gl.viewport( 0, 0, wd, ht )
gl.bindTexture( gl.TEXTURE_2D, tex )
gl.bindBuffer( gl.ARRAY_BUFFER, bff_pos )
gl.vertexAttribPointer( Gra.shd_a_pos, 2, gl.FLOAT, 0, 0, 0 )
gl.bindBuffer( gl.ARRAY_BUFFER, bff_tex )
gl.vertexAttribPointer( Gra.shd_a_tex, 2, gl.FLOAT, 0, 0, 0 )
gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 )
gl.bindFramebuffer( gl.FRAMEBUFFER, null )
gl.viewport( 0, 0, Gra.cv.width, Gra.cv.height )
顶点着色器:
attribute vec2 a_pos;
attribute vec2 a_tex;
varying vec2 v_tex;
void main (void)
{
gl_Position = vec4( a_pos.x, a_pos.y, 1.0, 1.0 );
v_tex = a_tex;
}
片段着色器:
precision mediump float;
uniform sampler2D u_smp;
varying vec2 v_tex;
void main (void)
{
gl_FragColor = texture2D( u_smp, vec2( v_tex.x, v_tex.y ) );
}
这是实时页面:http://ssjstash.net/webgl_error
您也可以下载源码:http://ssjstash.net/webgl_error.zip
我不确定到底是什么问题,我认为这可能是 firefox 的问题。
如果有人知道如何解决该问题(如果可以解决),我将不胜感激
这是一条无意义的消息,Mozilla 声称正在修复或已经修复它
https://bugzilla.mozilla.org/show_bug.cgi?id=1478216
修复程序可能还没有发布到稳定的 firefox
如果您想摆脱它,请不要用 null
调用 gl.texImage2D
为什么是废话。
如果你这样做
gl.texImage2D(target, level, format, width, height, 0, format, type, null);
然后浏览器会分配一块width * height * format * type size的内存,清零后传给OpenGL驱动。警告是这种内存分配和清除速度很慢。
消息是废话的原因是 JavaScript 中唯一可能的修复实际上较慢。
解决方法是在 JavaScript 中自己分配一个缓冲区,例如
const zero = new Uint8Array(
width * height * bytesPerPixelForFormatType(format, type));
gl.texImage2D(target, level, format, width, height, 0, format, type, zero);
那么在这种情况下会发生什么?好吧,您分配了一个与浏览器无论如何都会分配的大小相同的缓冲区。该缓冲区被清零,就像浏览器无论如何都会有的一样,但除此之外,您现在有一个浏览器必须创建的 Uint8Array
ArrayBufferView。它还必须创建底层 ArrayBuffer
,两个具有完整原型链的 javascript 对象等。这些对象也有引用计数器,垃圾收集器必须随着时间的推移检查它们是否以及何时安全释放。
换句话说,从 JavaScript 执行此操作时还有很多工作要做,所以警告是无稽之谈。
在 firefox 中打开我的 (JS HTML5) 项目时,我收到警告:"Error: WebGL warning: drawArrays: This operation requires zeroing texture data. This is slow."
有人告诉我这是因为试图读取超出范围的像素或类似的东西。
这是我的代码:
var gl = Gra.gl
// texture
var tex = gl.createTexture()
gl.bindTexture( gl.TEXTURE_2D, tex )
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, AppImg )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR )
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 )
var bff_pos = BufferFromArr([
-1, -1,
1, -1,
-1, 1,
1, 1
])
var bff_tex = BufferFromArr([
0, 1,
1, 1,
0, 0,
1, 0
])
// buffer
var wd = 200
var ht = 200
// texture
var tex2 = gl.createTexture()
gl.bindTexture( gl.TEXTURE_2D, tex2 )
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, wd, ht, 0, gl.RGBA, gl.UNSIGNED_BYTE, null )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR )
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR )
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 )
// framebuffer
var frame = gl.createFramebuffer()
gl.bindFramebuffer( gl.FRAMEBUFFER, frame )
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2, 0 )
gl.viewport( 0, 0, wd, ht )
gl.bindTexture( gl.TEXTURE_2D, tex )
gl.bindBuffer( gl.ARRAY_BUFFER, bff_pos )
gl.vertexAttribPointer( Gra.shd_a_pos, 2, gl.FLOAT, 0, 0, 0 )
gl.bindBuffer( gl.ARRAY_BUFFER, bff_tex )
gl.vertexAttribPointer( Gra.shd_a_tex, 2, gl.FLOAT, 0, 0, 0 )
gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 )
gl.bindFramebuffer( gl.FRAMEBUFFER, null )
gl.viewport( 0, 0, Gra.cv.width, Gra.cv.height )
顶点着色器:
attribute vec2 a_pos;
attribute vec2 a_tex;
varying vec2 v_tex;
void main (void)
{
gl_Position = vec4( a_pos.x, a_pos.y, 1.0, 1.0 );
v_tex = a_tex;
}
片段着色器:
precision mediump float;
uniform sampler2D u_smp;
varying vec2 v_tex;
void main (void)
{
gl_FragColor = texture2D( u_smp, vec2( v_tex.x, v_tex.y ) );
}
这是实时页面:http://ssjstash.net/webgl_error
您也可以下载源码:http://ssjstash.net/webgl_error.zip
我不确定到底是什么问题,我认为这可能是 firefox 的问题。
如果有人知道如何解决该问题(如果可以解决),我将不胜感激
这是一条无意义的消息,Mozilla 声称正在修复或已经修复它
https://bugzilla.mozilla.org/show_bug.cgi?id=1478216
修复程序可能还没有发布到稳定的 firefox
如果您想摆脱它,请不要用 null
gl.texImage2D
为什么是废话。
如果你这样做
gl.texImage2D(target, level, format, width, height, 0, format, type, null);
然后浏览器会分配一块width * height * format * type size的内存,清零后传给OpenGL驱动。警告是这种内存分配和清除速度很慢。
消息是废话的原因是 JavaScript 中唯一可能的修复实际上较慢。
解决方法是在 JavaScript 中自己分配一个缓冲区,例如
const zero = new Uint8Array(
width * height * bytesPerPixelForFormatType(format, type));
gl.texImage2D(target, level, format, width, height, 0, format, type, zero);
那么在这种情况下会发生什么?好吧,您分配了一个与浏览器无论如何都会分配的大小相同的缓冲区。该缓冲区被清零,就像浏览器无论如何都会有的一样,但除此之外,您现在有一个浏览器必须创建的 Uint8Array
ArrayBufferView。它还必须创建底层 ArrayBuffer
,两个具有完整原型链的 javascript 对象等。这些对象也有引用计数器,垃圾收集器必须随着时间的推移检查它们是否以及何时安全释放。
换句话说,从 JavaScript 执行此操作时还有很多工作要做,所以警告是无稽之谈。