javascript - 使用 Webgl 时 Firefox "This operation requires zeroing texture data"警告

标签 javascript webgl

在 Firefox 中打开我的 (JS HTML5) 项目时,收到警告:“错误:WebGL 警告:drawArrays:此操作需要将纹理数据归零。这很慢。”

我被告知这是由于尝试读取超出范围的像素或类似的原因。

这是我的代码:

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);

然后浏览器会分配一 block width * height * format * type size的一 block 内存,将其清为0并传递给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,都是具有完整原型(prototype)链的 JavaScript 对象等。这些对象也有引用计数器,垃圾收集器必须随着时间的推移检查它们是否以及何时安全。自由。

换句话说,当通过 JavaScript 执行此操作时,还有更多的工作要做,因此警告是无意义的。

关于javascript - 使用 Webgl 时 Firefox "This operation requires zeroing texture data"警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54291868/

相关文章:

javascript - Three.js - 棋盘平面

javascript - 如何在 A-Frame 中呈现 HTML?

opengl - 渲染具有多个索引的网格

opengl-es - GLSL 优化 : check if variable is within range

javascript - WebGL 中高效的 VBO 分配

javascript - Webgl 将颜色变量传递给着色器

javascript - 放大子元素 PixiJS

php - Code Igniter : Js file is included successfully, 脚本不工作

asp.net - 服务器端代码执行后,从后面的 asp.net 代码调用 javascript 函数

safari 的 javascript fileReader 替代品(<6)