繁体   English   中英

如何在 webgl2 上处理 3d 纹理

[英]How to handle 3d texture on webgl2

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

gl.texImage3D();

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


gl.texStorage3D()

接着,

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

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

简短的回答是texStorage2DtexStorage3D分配所有纹理 memory 。 其中texImage2DtexImage3D分配一个 mip 级别。

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

至于为什么其中之一。 texStorage2DtexStorage3D可以立即在 GPU 上分配 memory。 texImage2DtexImage3D不能,因为它们不知道完整的纹理(所有 mips),直到您实际尝试使用纹理绘制一些东西。 换句话说, 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您不会提前告诉它所有内容,因此如果情况发生变化,它必须在绘制时间再次检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM