我正在使用
在webgl中创建3D纹理gl.bindTexture(gl.TEXTURE_3D,纹理){
const level = 0;
const internalFormat = gl.R32F;
const width = 512;
const height = 512;
const depth = 512;
const border = 0;
const format = gl.RED;
const type = gl.FLOAT;
const data = imagesDataArray;
......命令
使用32F值时,看起来512 * 512 * 512的大小有点麻烦,因为chrome(在笔记本电脑8 gb ram上运行)浏览器在上载此大小的3D纹理时崩溃,但并非总是如此。使用说尺寸为512 * 512 * 256的纹理似乎总是可以在我的笔记本电脑上使用。 有什么方法可以提前告知GPU可以适应与webgl2相关的3D纹理的最大大小吗?
最诚挚的问候
答案 0 :(得分:2)
不幸的是,没有办法无法告诉您有多少空间。
您可以查询GPU可以处理的最大尺寸,但无法查询GPU可用的内存量,就像无法查询JavaScript可用的内存量一样。
也就是说,512 * 512 * 512 * 1(R)* 4(32F)至少为0.5 Gig。您的笔记本电脑的GPU是否具有0.5Gig?实际上,您可能至少需要1gig的GPU内存才能使用.5gig作为纹理,因为操作系统需要为应用程序的窗口等留出空间...
浏览器还对可以使用的内存量设置了不同的限制。
一些要检查的东西。
您有多少GPU内存。
如果不超过0.5gig,则说明您不走运
如果您的GPU的容量超过0.5gig,请尝试使用其他浏览器
Firefox的限制可能与Chrome的限制不同
可以完全创建纹理吗?
使用gl.texStorage3D
,然后调用gl.getError
。它会出现内存不足错误还是在那里崩溃。
如果gl.texStorage3D
没有崩溃,您可以一次使用gl.texSubImage3D
我怀疑即使gl.texStorage3D
也能正常工作,因为浏览器仍必须分配0.5gig来清除纹理。如果它确实起作用,则表明另一个问题是,上传纹理需要的内存至少是Chrome的3x-4x。
JavaScript中有您的数据
data = new Float32Array(size);
数据被发送到GPU进程
gl.texSubImage3D (or any other texSub or texImage command)
GPU进程将数据发送到驱动程序
glTexSubImage3D(...) in C++
驱动程序是否需要1或2份副本,我不知道。有可能保持 在ram中复制一份并将其上传到GPU。它保留副本,以便可以 如果需要交换数据以腾出空间以供其他使用,请重新上传数据。 是否发生这种情况取决于驾驶员。
还请注意,虽然我认为这不是问题,但允许驱动器将纹理扩展到需要2gig的RGBA32F。可能不是这样做的,但是我知道过去已经模拟了某些格式。
注意:texImage
可能比texStorage
占用更多的内存,因为texImage
的语义意味着驱动程序直到绘制之前才能真正制作纹理,因为它不知道如果您以后要添加MIP级别。另一方面,texStorage
会告诉驱动程序确切的mips大小和数目,因此不需要中间存储。
function main() {
const gl = document.createElement('canvas').getContext('webgl2');
if (!gl) {
return alert('need webgl2');
}
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex);
gl.texStorage3D(gl.TEXTURE_3D, 1, gl.R32F, 512, 512, 512);
log('texStorage2D:', glEnumToString(gl, gl.getError()));
const data = new Float32Array(512*512*512);
for (let depth = 0; depth < 512; ++depth) {
gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, depth, 512, 512, 1, gl.RED, gl.FLOAT, data, 512 * 512 * depth);
}
log('texSubImage3D:', glEnumToString(gl, gl.getError()));
}
main();
function glEnumToString(gl, value) {
return Object.keys(WebGL2RenderingContext.prototype)
.filter(k => gl[k] === value)
.join(' | ');
}
function log(...args) {
const elem = document.createElement('pre');
elem.textContent = [...args].join(' ');
document.body.appendChild(elem);
}