我正在将OpenGL应用程序移植到Web上,并发现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纹理,需要两个纹素提取,并在它们之间进行手动插值,以获得相同的结果。
答案 0 :(得分:3)
你是对的,我脑海中最大的不同就是纹理过滤3D与2D。如果纹理坐标不精确地位于纹理元素的中心,则线性滤波必须采样4个纹素(假设2D图像),然后基于样本位置与所获取的每个纹素的距离进行加权平均。这是一个基本的操作,硬件是专门为此构建的(更新的硬件甚至可以让你以gather4
)等指令的形式利用它。
你可以自己实现线性过滤(实际上,你有时必须使用多重采样纹理),如果你使用最近邻滤波器并自己计算加权因子等,但它总会慢于硬件实现。
在您的情况下,如果您想对3D纹理实施线性过滤,您实际上必须采样 8纹素 (2 3 处理所有3个维度的插值)。显然硬件偏向于使用2D纹理,因为没有gather8
指令......但你可以打赌原生线性插值比你的手动黑客更快。
WebGL甚至没有公开gather4
/ textureGather
(因为这是DX10.1 / GL4功能),但硬件以这种方式工作 long 之前是您可以在着色器中使用的指令。
如果您聪明,可以使用硬件的线性过滤功能在每个2D切片的S
和T
方向进行过滤,然后执行在切片之间拥有线性过滤(R
)。但是,在处理图像边缘的纹素时,您必须要小心。确保虚拟3D纹理中的切片图像之间至少有1个纹素标注边框,这样硬件就不会在切片之间进行插值。