1

我正在将 OpenGL 应用程序移植到网络上,并发现 WebGL 1.0 不支持 3D 纹理(将在 2.0 中支持)。我使用 16 x 16 x 16 纹理作为一些简单模型的颜色信息(用于块状外观)。

现在不支持 3D 模型,我意识到我可以将 16 层分散到 4 x 4 平面上,如下所示:

0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

0 = layer

结果是 64 x 64“伪 3D”纹理。

这引出了我的问题:GPU 上的 3D 和 2D 纹理有什么区别?在可以使用 2D 纹理而不是 3D 纹理的情况下(如我的示例中),两者之间是否存在性能差异?

我猜 3D 纹理具有沿 z 轴插值的硬件支持,而对于 2D 纹理,则需要两个 texel 提取,并且在它们之间进行手动插值,以获得相同的结果。

4

1 回答 1

4

您是对的,我立即想到的最大区别与纹理过滤 3D 与 2D 有关。如果纹理坐标不精确地位于纹素的中心,则线性过滤必须对 4 个纹素进行采样(假设是 2D 图像),然后根据采样位置与提取的每个纹素的距离进行加权平均。这是一个非常基本的操作,硬件是专门为此构建的(更新的硬件甚至可以让您以指令的形式利用它gather4)。

如果您使用最近邻过滤器并自己计算权重因子等,您可以自己实现线性过滤(实际上,有时您必须进行多重采样纹理之类的事情),但它总是比硬件实现慢。

在您的情况下,如果您想在 3D 纹理上实现线性过滤,您实际上必须采样8 个纹理像素(2 3以处理所有 3 个维度的插值)。显然,硬件偏向于使用 2D 纹理,因为没有gather8说明……但您可以打赌,原生线性插值会比手动破解更快。

WebGL 甚至不公开gather4/ textureGather(因为这是 DX10.1 / GL4 功能),但硬件在很久以前就以这种方式工作,这是您可以在着色器中使用的指令。


如果您很聪明,您可能会想出一个折衷方案,您可以使用硬件的线性过滤功能在每个 2D 切片的ST方向上进行过滤,然后在切片之间执行您自己的线性过滤 ( R)。但是,在处理图像边缘的纹素时,您必须小心。确保虚拟 3D 纹理中的切片图像之间至少有 1 texel 的边界,这样硬件就不会跨切片进行插值。

于 2014-03-14T22:17:29.770 回答