WebGL 上的错误 "Tex image TEXTURE_2D level 0 is incurring lazy initialization"
Error "Tex image TEXTURE_2D level 0 is incurring lazy initialization" on 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);
则此错误消息不再显示,我设法正确呈现。
这不是错误。这是一个警告。
Error: WebGL warning ...
前面写着"Error"真是太迷惑了,但即使只写了"warning"我也争论了很久,这是不好的警告。
警告是 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 正在分配 16 兆,它也清除了 16 兆。它还分配一个 Uint8Array
对象来跟踪该 16meg。该 Uint8Array
对象是一个复杂的 JavaScript 对象,可能是多个对象组合在一起的集合,例如还分配了一个 ArrayBuffer
对象。这些对象都有原型链,并且能够向它们添加属性和方法以及 getter 和 setter。 Uint8Array
和 ArrayBuffer
也必须被跟踪,以便它们可以在以后被垃圾收集,这意味着它们存在开销。更糟糕的是,如果浏览器是 Chrome 的多进程并且我相信 Firefox 正在努力,那么 JavaScript 中分配的 16meg 必须复制到 GPU 进程,这意味着首先 GPU 进程需要分配16meg 的 ram,数据必须从进程 运行 网页复制到 GPU 进程,以便它可以传递给图形驱动程序。更多的工作。
所以换句话说,让 Firefox 关闭它的警告实际上会使您的代码变慢并使用更多的内存,如果 firefox 只是默默地自行清除纹理。因此,为什么我说警告不应该存在
Firefox 的开发人员有这样的观点,即只要 WebGL 做了一些繁重的事情,他们就想给你一个警告。鉴于治愈方法会使您的代码更重,我不同意他们的 POV。 Chrome 不给出此警告。这也让开发人员感到困惑,因为他们认为自己做错了什么。他们没有做错任何事。
https://bugzilla.mozilla.org/show_bug.cgi?id=1478216
至于没有渲染的东西,在你发布的代码中你没有在纹理中放置任何东西,所以纹理当然是 0,0,0,0。
我在 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);
则此错误消息不再显示,我设法正确呈现。
这不是错误。这是一个警告。
Error: WebGL warning ...
前面写着"Error"真是太迷惑了,但即使只写了"warning"我也争论了很久,这是不好的警告。
警告是 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 正在分配 16 兆,它也清除了 16 兆。它还分配一个 Uint8Array
对象来跟踪该 16meg。该 Uint8Array
对象是一个复杂的 JavaScript 对象,可能是多个对象组合在一起的集合,例如还分配了一个 ArrayBuffer
对象。这些对象都有原型链,并且能够向它们添加属性和方法以及 getter 和 setter。 Uint8Array
和 ArrayBuffer
也必须被跟踪,以便它们可以在以后被垃圾收集,这意味着它们存在开销。更糟糕的是,如果浏览器是 Chrome 的多进程并且我相信 Firefox 正在努力,那么 JavaScript 中分配的 16meg 必须复制到 GPU 进程,这意味着首先 GPU 进程需要分配16meg 的 ram,数据必须从进程 运行 网页复制到 GPU 进程,以便它可以传递给图形驱动程序。更多的工作。
所以换句话说,让 Firefox 关闭它的警告实际上会使您的代码变慢并使用更多的内存,如果 firefox 只是默默地自行清除纹理。因此,为什么我说警告不应该存在
Firefox 的开发人员有这样的观点,即只要 WebGL 做了一些繁重的事情,他们就想给你一个警告。鉴于治愈方法会使您的代码更重,我不同意他们的 POV。 Chrome 不给出此警告。这也让开发人员感到困惑,因为他们认为自己做错了什么。他们没有做错任何事。
https://bugzilla.mozilla.org/show_bug.cgi?id=1478216
至于没有渲染的东西,在你发布的代码中你没有在纹理中放置任何东西,所以纹理当然是 0,0,0,0。