如何在WebGL2上处理3D纹理

问题描述

我试图在webgl2中使用3D纹理,并且我了解了

gl.texImage3D();

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


gl.texStorage3D()

然后

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

我只想知道两种方法之间的区别。我知道2D纹理也可以使用第二个选项,但是我不使用它来为目标提供数据。我知道子图像是为片段着色器创建纹理的子图像,但我不了解两种方法之间的区别。

解决方法

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

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

关于为什么一个或另一个。 texStorage2DtexStorage3D可以立即在GPU上分配内存。 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的纹理不能更改大小或内部格式。如果尝试在用texImage2D创建的纹理上调用texStorage2D,则会收到错误消息。

如果您首先很好地使用了texImage2D,则可能指定了第一个mip

gl.texImage2D(gl.TEXTURE_2D,// 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个mips的内部格式是否相同?您是否将MIP级别0更改为其他大小或内部格式? WebGL不知道下一个命令是什么,它必须等到您实际尝试绘制纹理后才能检查。使用texStorage,您可以预先确定所有mips的大小和格式,因此只需检查一次即可。使用texImage时,您无需事先告知所有内容,因此必须在绘制时再次检查是否有任何更改。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...