WebGL上出现错误“ Tex图像TEXTURE_2D级别0导致延迟初始化”

时间:2019-08-31 01:48:40

标签: javascript webgl

我在WebGL上收到错误消息:Error: WebGL warning: drawElements: Tex image TEXTURE_2D level 0 is incurring lazy initialization.,我想知道实际上是什么意思。

无论如何,惰性初始化在单线程应用程序中还是一个问题?我理解为您在getter中初始化变量时的理解?

我试图查找错误消息,但实际上并没有找到任何好的信息。

这是我处理纹理的代码:

            const images = await Promise.all(model.maps.map(map => new Promise((resolve, reject) => {
                const image = new Image();

                image.src = map;
                image.onload = event => {
                    const texture = gl.createTexture();

                    gl.bindTexture(gl.TEXTURE_2D, texture);
                    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.FLOAT, null);
                    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);

                    gl.bindTexture(gl.TEXTURE_2D, null);

                    resolve(texture);
                };

                image.onerror = error => {
                    console.log(error);
                    resolve(null);
                };
            })));

我的绘画功能的相关部分基本上是:

gl.bindTexture(gl.TEXTURE_2D, textures[material.textureIndex]);
gl.activeTexture(gl.TEXTURE0);
gl.drawElements(gl.TRIANGLES, material.faceCount * 3, gl.UNSIGNED_SHORT, drawnCount);

话虽如此,如果我使用6个参数语法:gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.FLOAT, image);,则此错误消息将不再显示,并且我将正确渲染。

1 个答案:

答案 0 :(得分:1)

这不是错误。这是警告。

  

错误:WebGL 警告 ...

它在前面说“错误”非常令人困惑,但是即使我只说了“警告”也很久了,这是一个糟糕的警告。

警告是WebGL需要做一些不平凡的工作。

制作纹理时,如果不传递任何数据,则将null作为最后一个参数传递给texImage2D,这意味着WebGL必须在某个时候清除纹理。假设纹理为2048x2048 RGBA / UNSIGNED_BYTE。有效地,WebGL必须分配16meg的ram(2048x2048x4),将16meg的ram清除为0,并在实际使用纹理之前调用gl.texSubImage2D将零放入纹理中。如果他们不这样做,则纹理中将包含随机数据,这些数据可能是机密,密码,以前的图形内存(如照片)等。

因此,警告告诉您发生了一些不重要的工作。

此警告的问题在于,停止警告的解决方法比警告本身更糟。解决方法是让您自己清除纹理。为此,您需要像new Uint8Array(2048 * 2048 * 4)中那样在JavaScript中分配16meg。这意味着JavaScript正在分配16meg,它也清除了16mcg。它还分配了一个Uint8Array对象来跟踪该16meg。该Uint8Array对象是一个复杂的JavaScript对象,可能是多个组合在一起的对象的集合,例如,也分配了ArrayBuffer对象。这些对象既具有原型链,又具有向其添加属性和方法以及获取器和设置器的能力。还必须跟踪Uint8ArrayArrayBuffer,以便以后可以对其进行垃圾回收,这意味着甚至存在开销。更糟糕的是,如果浏览器是Chrome的多进程浏览器,并且我相信Firefox正在开发,那么必须将JavaScript中分配的16meg复制到GPU进程,这意味着首先GPU进程也需要分配16meg的ram,数据必须从运行网页的进程复制到GPU进程,以便可以传递到图形驱动程序。甚至还有更多工作。

因此,换句话说,让Firefox关闭其警告实际上会使您的代码变慢并且占用更多的内存,而FireFox只是默默地清除了其纹理。因此,为什么我说警告不应该存在

Firefox的开发人员拥有POV,只要WebGL做任何繁重的事情,他们都希望向您发出警告。鉴于这种解决方案会使您的代码更沉重,因此我不同意他们的POV。 Chrome不会发出此警告。这也使开发人员感到困惑,因为他们认为自己做错了什么。他们没有做错任何事情。

https://bugzilla.mozilla.org/show_bug.cgi?id=1478216

对于未渲染的东西,在您发布的代码中,您没有在纹理中放置任何内容,因此纹理当然是0,0,0,0。