Webgl2 3D 纹理的最大尺寸?
Webgl2 maximum size of 3D texture?
我正在使用
在 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纹理的最大尺寸?
此致
很遗憾,没有办法知道有多少space。
您可以查询 GPU 可以处理的最大尺寸,但无法查询其可用内存量,就像您无法查询可用内存量一样 JavaScript。
也就是说,512*512*512*1(R)*4(32F) 至少是 0.5 Gig。您笔记本电脑的 GPU 有 0.5Gig 吗?您实际上可能需要至少 1gig 的 GPU 内存才能使用 .5gig 作为纹理,因为 OS 需要 space 用于您的应用程序的 windows 等...
浏览器对您可以使用的内存量也有不同的限制。
有些事情要检查。
你有多少GPU显存。
如果它不超过 0.5gig 你就不走运了
如果您的 GPU 超过 0.5gig,请尝试不同的浏览器
Firefox 的限制可能与 Chrome
不同
你能创建纹理吗?
使用gl.texStorage3D
,然后调用gl.getError
。它是否出现内存不足错误或崩溃。
如果gl.texStorage3D
不崩溃你能用gl.texSubImage3D
一次上传一点数据吗
我怀疑这不会起作用,即使 gl.texStorage3D
确实有效,因为浏览器仍然需要分配 0.5gig 来清除您的纹理。如果它确实有效,这就指向另一个问题,即上传纹理你需要 3x-4x 的内存,至少在 Chrome.
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
另一方面,您告诉驱动程序要开始的确切大小和 mip 数量,因此它不需要中间存储。
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);
}
我正在使用
在 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纹理的最大尺寸?
此致
很遗憾,没有办法知道有多少space。
您可以查询 GPU 可以处理的最大尺寸,但无法查询其可用内存量,就像您无法查询可用内存量一样 JavaScript。
也就是说,512*512*512*1(R)*4(32F) 至少是 0.5 Gig。您笔记本电脑的 GPU 有 0.5Gig 吗?您实际上可能需要至少 1gig 的 GPU 内存才能使用 .5gig 作为纹理,因为 OS 需要 space 用于您的应用程序的 windows 等...
浏览器对您可以使用的内存量也有不同的限制。
有些事情要检查。
你有多少GPU显存。
如果它不超过 0.5gig 你就不走运了
如果您的 GPU 超过 0.5gig,请尝试不同的浏览器
Firefox 的限制可能与 Chrome
不同
你能创建纹理吗?
使用
gl.texStorage3D
,然后调用gl.getError
。它是否出现内存不足错误或崩溃。如果
一次上传一点数据吗gl.texStorage3D
不崩溃你能用gl.texSubImage3D
我怀疑这不会起作用,即使
gl.texStorage3D
确实有效,因为浏览器仍然需要分配 0.5gig 来清除您的纹理。如果它确实有效,这就指向另一个问题,即上传纹理你需要 3x-4x 的内存,至少在 Chrome.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
另一方面,您告诉驱动程序要开始的确切大小和 mip 数量,因此它不需要中间存储。
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);
}