Javascript “错误”;Tex图像纹理“2D级别0导致延迟初始化”;关于WebGL

Javascript “错误”;Tex图像纹理“2D级别0导致延迟初始化”;关于WebGL,javascript,webgl,Javascript,Webgl,我收到错误消息:错误:WebGL警告:抽屉元素:Tex图像纹理\u 2D 0级正在进行延迟初始化。在WebGL上,我想知道它的实际含义 在单线程应用程序中,延迟初始化怎么会是一个问题呢?我把它理解为在getter中初始化变量 我试图寻找我的错误信息,但没有找到任何好的信息 这是我处理纹理的代码: const images = await Promise.all(model.maps.map(map => new Promise((resolve, reject) =

我收到错误消息:
错误:WebGL警告:抽屉元素:Tex图像纹理\u 2D 0级正在进行延迟初始化。
在WebGL上,我想知道它的实际含义

在单线程应用程序中,延迟初始化怎么会是一个问题呢?我把它理解为在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)然后此错误消息不再显示,我成功地正确渲染。

这不是错误。这是一个警告

错误:WebGL警告

前面写着“错误”真是太让人困惑了,但即使它只写了“警告”,我已经争论了很长时间了,这是个坏警告

警告是WebGL需要做一些非琐碎的工作

当你制作一个纹理而不传递任何数据时,你将
null
作为最后一个参数传递给
texImage2D
,这意味着在某个时候WebGL必须清除纹理。假设纹理为2048x2048 RGBA/无符号_字节。实际上,WebGL必须分配16meg的ram(2048x2048x4),将16meg的ram清除为0,并在实际使用纹理之前调用
gl.texSubImage2D
在纹理中置零。如果他们不这样做,纹理中会有随机数据,这些数据可能是机密、密码、以前的图形内存(如照片)或其他数据

因此,警告告诉您发生了一些非琐碎的工作

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

换句话说,让Firefox闭嘴警告实际上会让你的代码更慢,占用更多的内存,如果Firefox只是自己默默地清除纹理的话。因此,我说警告不应该存在

Firefox的开发人员有一个观点,即每当WebGL做了一些重大的事情时,他们都会给你一个警告。考虑到解药会让你的代码更重,我不同意他们的观点。Chrome没有给出这个警告。这也让开发人员感到困惑,因为他们认为自己做错了什么。他们没有做错什么


至于没有渲染的东西,在你发布的代码中,你没有在纹理中放置任何东西,所以纹理当然是0,0,0,0

这是因为它让开发人员认为他们做错了什么,而他们没有这样做,而且解决方法会更糟糕、更繁重。如果他们想保留这些警告,我认为它们应该只在特殊的“检查性能”模式下显示,但即使这样,这些警告也是假的,因为停止这些警告的解决方法会使性能变慢并使用更多内存。感谢您的大力响应!似乎我忘了传递纹理,我认为警告与此有关。