Webgl2 3D纹理的最大尺寸?

use*_*072 0 webgl

我正在 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 纹理的最大尺寸?

此致

gma*_*man 5

不幸的是,没有,没有办法知道有多少空间。

您可以查询 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 中是这样。

    1. JavaScript 中有你的数据

      data = new Float32Array(size);
      
      Run Code Online (Sandbox Code Playgroud)
    2. 该数据被发送到 GPU 进程

      gl.texSubImage3D (or any other texSub or texImage command)
      
      Run Code Online (Sandbox Code Playgroud)
    3. 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)