我正在 webgl 中创建 3D 纹理
gl.bindTexture(gl.TEXTURE_3D, texture) {
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;
...... command
Run Code Online (Sandbox Code Playgroud)
使用 32F 值时,512 512 512的大小似乎有点影响,因为 chrome(在笔记本电脑 8 GB RAM 上运行)浏览器在上传此大小的 3D 纹理时会崩溃,但并非总是如此。使用尺寸为 512 512 256 的纹理似乎总是适用于我的笔记本电脑。有没有办法提前知道与 webgl2 相关的 GPU 可以容纳的 3D 纹理的最大尺寸?
此致
不幸的是,没有,没有办法知道有多少空间。
您可以查询 GPU 可以处理的最大尺寸,但无法查询其可用的内存量,就像无法查询 JavaScript 可用的内存量一样。
也就是说,512*512*512*1(R)*4(32F) 至少为 0.5 Gig。您的笔记本电脑的 GPU 有 0.5Gig 吗?实际上,您可能需要至少 1gig 的 GPU 内存才能使用 0.5gig 作为纹理,因为操作系统需要空间用于应用程序的窗口等...
浏览器还对可以使用的内存量设置了不同的限制。
有些事情要检查。
你有多少 GPU 内存。
如果不超过 0.5gig 你就不走运了
如果您的 GPU 超过 0.5gig,请尝试其他浏览器
Firefox 可能有与 Chrome 不同的限制
你能创造出纹理吗?
使用gl.texStorage3D然后调用gl.getError。是否出现内存不足错误或崩溃。
如果gl.texStorage3D没有崩溃,你可以一次上传一点数据吗gl.texSubImage3D
我怀疑即使gl.texStorage3D有效也不起作用,因为浏览器仍然需要分配 0.5gig 来清除纹理。如果它确实有效,则表明另一个问题,即上传纹理需要 3 到 4 倍的内存,至少在 Chrome 中是这样。
JavaScript 中有你的数据
data = new Float32Array(size);
Run Code Online (Sandbox Code Playgroud)该数据被发送到 GPU 进程
gl.texSubImage3D (or any other texSub or texImage command)
Run Code Online (Sandbox Code Playgroud)GPU进程将该数据发送给驱动程序
glTexSubImage3D(...) in C++
Run Code Online (Sandbox Code Playgroud)
我不知道驱动程序是否需要 1 份或 2 份副本。它可能会在 RAM 中保留一份副本并将其上传到 GPU。它保留副本,以便在需要交换数据以为其他内容腾出空间时可以重新上传数据。是否发生这种情况取决于驾驶员。
另请注意,虽然我认为这不是问题,但允许驱动器将纹理扩展到需要 2gig 的 RGBA32F。它可能没有这样做,但我知道过去某些格式被模拟。
注意:texImage可能会占用更多内存,texStorage因为语义texImage意味着驱动程序直到绘制之前才能真正制作纹理,因为它不知道稍后是否要添加 mip 级别。texStorage另一方面,您告诉驱动程序开始时的确切大小和 mip 数量,因此不需要中间存储。
data = new Float32Array(size);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1639 次 |
| 最近记录: |