【问题标题】:How to handle 3d texture on webgl2如何在 webgl2 上处理 3d 纹理
【发布时间】:2020-08-11 17:02:52
【问题描述】:

我正在尝试在 webgl2 中使用 3D 纹理,我开始了解

gl.texImage3D();

我有 2d 纹理的经验,我发现它非常方便,但是人们在互联网上使用另一种方法。


gl.texStorage3D()

然后,

gl.texSubImage3D() // with all offset of x,y and z as 0.

我只想知道这两种方法有什么区别。我知道第二个选项的等效项也可用于 2D 纹理,但我不使用它来向目标提供数据。我知道子图像是为片段着色器创建纹理的子图像,但我不明白这两种方法有什么区别。

【问题讨论】:

    标签: webgl webgl2


    【解决方案1】:

    简短的回答是texStorage2DtexStorage3D 预先分配所有纹理内存。其中texImage2DtexImage3D 一次分配一个mip 级别。

    texSubImage2DtexSubImage3D 不分配任何东西。他们只是将数据复制到之前使用上述函数之一分配的纹理 mip 级别。

    至于为什么选择其中一个。 texStorage2DtexStorage3D 可以立即在 GPU 上分配内存。 texImage2DtexImage3D 不能,因为他们不知道完整的纹理(所有 mip),直到你真正尝试用纹理绘制一些东西。换句话说,texStorage2D/3D 可能更高效,而texImage2D/3D 更灵活。


    为了使纹理真正可渲染,您要使用的所有 mip 级别都需要具有相同的内部格式和正确的大小。

    当您调用texStorage2D/3D 时,您会告诉mip 级别0(最大级别)的大小以及总共要分配多少个mip 级别。所以假设你告诉它gl.RGBA8 的内部格式,宽度和高度分别为 8 和 4 mip 级别。

    gl.texStorage2D(gl.TEXTURE_2D,
                    4,         // 4 levels
                    gl.RGBA8,  // internal format
                    8,         // width
                    8);        // height
                    
    

    它将分配 8x8x4、4x4x4、2x2x4、1x1x4 mip 级别,所有 4 个 mip 级别。它知道它们都是RGBA8。它知道它们的大小都是正确的。使用texStorage2D 分配的纹理大小或内部格式无法更改。如果您尝试在使用texStorage2D 创建的纹理上调用texImage2D,则会收到错误消息。

    如果您首先使用texImage2D,您可能会指定第一个mip

    gl.texImage2D(gl.TEXTURE_2D, 
                  0,         // mip level
                  gl.RGBA8,  // internal format
                  8,         // width
                  8,         // height
                  0,         // border
                  gl.RGBA,   // data format
                  gl.UNSIGNED_BYTE,  // data type
                  data);
    

    所以现在你只有 1 个 mip 级别,级别 #0。你会添加其他 3 个 mips 吗?它们的尺寸是否正确?其他 3 个 mip 是否具有相同的内部格式?您会将 mip 级别 #0 更改为其他内容、不同的大小或不同的内部格式吗? WebGL 不知道您的下一个命令将是什么,它必须等到您实际尝试使用纹理进行绘制才能检查。使用texStorage,您可以预先决定所有 mip 的大小和格式,因此只需检查一次。使用texImage,您不会提前告诉它所有内容,因此如果情况发生变化,它必须在抽奖时间再次检查。

    【讨论】:

    • 感谢您的回答。你的意思是texStorage预先为不同的级别分配内存,texImage2D在drawcall时分配,对吗?我不明白你为什么说 texStorage 高效,因为它可能会占用可能未使用的级别的内存空间,而且我不明白 texImage 比 texStorage 灵活。
    • 如果您仔细考虑 API 的含义,您可以自己解决这个问题,但我添加了更多信息。
    • 这是非常有用的信息,帮助我在很大程度上消除了我的困惑。非常感谢您的努力和时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 2019-10-11
    • 2017-08-22
    • 2017-09-17
    • 2016-05-10
    相关资源
    最近更新 更多