Webgl:设备似乎报告了不正确的gl.MAX_TEXTURE_SIZE值



我正在处理一个涉及大纹理的webgl场景。我一直在查询以确定给定设备支持的最大纹理大小,如下所示:

var gl = document.createElement('canvas').getContext('webgl')
console.log(gl.getParameter(gl.MAX_TEXTURE_SIZE))

在我的 2015 Macbook Pro 上,我可以很好地使用返回尺寸的纹理。但是,在 2015 MacBook Air 上,当我尝试将返回大小的纹理作为统一传递给着色器时,出现错误:

[.WebGL-0x7fcb4489200]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION :
glGenerateMipmap <- 来自先前 GL 命令的错误

但是,如果我使用大小gl.getParameter(gl.MAX_TEXTURE_SIZE)/2的纹理,MacBook Air可以很好地渲染场景并且没有错误。

MacBook Air是否有可能错误地报告了其gl功能?还是我尝试错误地确定最大纹理大小?我的目标是查询当前浏览器设备支持的最大纹理。其他人可以就如何最好地实现这一目标提供的任何建议将完全欢迎!

我在Chrome 78和Safari 13中观察到了上述行为。

发布一些代码!无法保证您可以分配最大大小的纹理,因为系统可能内存不足。

MAX_TEXTURE_SIZE x 1或 1 x MAX_TEXTURE_SIZE 的纹理可能不会耗尽内存。MAX_TEXTURE_SIZE x MAX_TEXTURE_SIZE 当MAX_TEXTURE_SIZE为 2^14 时,如果是 RGBA/UNSIGNED_BYTE,则至少需要 1 GB 的 vram。使用mips,这将是1.4g的vram。最重要的是,浏览器可能会分配 1.4GB 的 vram 来尝试清除纹理,驱动程序本身可能会分配 1.4gig 的 ram 来备份纹理或准备将其上传到 GPU 或两者兼而有之。很多机会耗尽内存。如果是RGBA/FLOAT纹理,则需要5.6gig。

这是分配最大 x 1 的测试

const gl = document.createElement('canvas').getContext('webgl');
const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
const maxRenderbufferSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
console.log('max texture size:', maxTextureSize);
console.log('max renderbuffer size:', maxRenderbufferSize);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
maxTextureSize,
1,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
null);
gl.generateMipmap(gl.TEXTURE_2D);
console.log('GL ERROR:', glEnumToString(gl, gl.getError()));
function glEnumToString(gl, value) {
const keys = [];
for (const key in gl) {
if (gl[key] === value) {
keys.push(key);
}
}
return keys.length ? keys.join(' | ') : `0x${value.toString(16)}`;
}

最新更新