【发布时间】:2012-02-11 15:56:45
【问题描述】:
我在 OpenGL ES 2.0 中找不到来自 OpenGL 的 glTexImage3D() 函数。那么如何使用 3-D 纹理,例如:.tga 文件?
有人知道如何在 OpenGL ES 2.0 中使用 3-D 纹理吗?
【问题讨论】:
标签: iphone ios opengl-es opengl-es-2.0
我在 OpenGL ES 2.0 中找不到来自 OpenGL 的 glTexImage3D() 函数。那么如何使用 3-D 纹理,例如:.tga 文件?
有人知道如何在 OpenGL ES 2.0 中使用 3-D 纹理吗?
【问题讨论】:
标签: iphone ios opengl-es opengl-es-2.0
OpenGL ES 1.x 和 2.x 不强制要求支持 3d 纹理 - 参见例如glBindTexture 的规范手册页,其中仅列出了 GL_TEXTURE_2D 和 GL_TEXTURE_CUBE_MAP 作为目标 - 而且 iOS 硬件没有提供任何合适的扩展。
我能想出的最佳解决方案是将 3d 纹理打包成 2d 纹理,因此您可以说是 128x128x128 3d 纹理,然后将其布置为 128 个单独的 128x128 图像单个 2d 纹理上的 16x8 网格。因此 2d 纹理为 2048x1024 像素,接近 iPhone 4 和 iPad 2 代设备以及之前的 ES 2.0 兼容 iOS 设备的硬件限制。
然后,您将 3d 纹理坐标提供给片段着色器,就像有一种方法可以在本地索引 3d 纹理一样,但需要快速计算一下以将其折叠为 2d。
所以,在 128x128x128 的例子中,你会做类似的事情(编码在这里,正如我所说,未经测试,):
texPos.x = sourceVarying.x / 16.0; // because we've packed 16 source images across,
texPos.y = sourceVarying.y / 8.0; // and 8 images down
// we'll multiply z by 16 since then, logically, the integer part is
// how many tiles across to index, and the decimal part is now many
// tiles down to index
texPos.z *= 16.0;
// figure out how many tiles across to index, with each tile being
// 1.0 / 16.0 in size
texPos.x += floor(texPos.z) / 16.0;
// remove the integer part of z, then multiply by 8 to do much what
// we just did to y
texPos.z = fract(texPos.z) * 8.0;
texPos.y += floor(texPos.z) / 8.0;
// now load the appropriate sample from texPos.xy
这可能不是实现这一目标的最有效方法,它是为(相对)清晰而编写的。您还看到了每个纹理读取依赖的显着性能劣势(即,GPU 无法预测片段着色器之外的访问,从而导致严重的管道困难)。但这要与使用 3d 纹理贴图以外的其他东西所必须花费的任何成本进行权衡。
还请注意,您正在执行一个与特定 z 切片相关联的访问。因此,您只能在至少一个维度上进行GL_NEAREST 类型的采样,除非您想进行两个样本并以更高的成本自己混合结果。我也没有对钳位做任何事情,你很可能想要解决这个问题。
Datanwolf(+1,顺便说一句)关于 mipmapping 是一个问题也是完全正确的;我最终只是禁用了它。
2013 年末附录:在撰写本文时,iOS 7、iPhone 5s、第二代 iPad Mini 和 iPad Air 都支持 ES 3.0。 3.0 引入了GL_TEXTURE_3D 目标。因此,您可以直接在这些设备上使用 3d 纹理,并且可能在所有未来的 iOS 设备上使用。而且,据记录,它在 Android 上也有类似的可用性,所有最近的 Nexus 设备、HTC One、一些最近的三星和其他设备都支持它。
【讨论】:
我在 OpenGL ES 2 中找不到 glTexImage3D 函数
因为 OpenGL-ES 不支持 3D 纹理。想一想:3D 纹理比 2D 纹理需要更多的内存。而内存是嵌入式/移动设备上非常稀缺的资源,这正是 ES 的目标。
我想也许有人知道使用 3d 纹理的算法?
与其说是算法问题,不如说是资源有限的问题。理论上,您可以使用多个纹理单元/采样器在那里上传图层,并在着色器中进行插值。但这会缺乏深度 mipmaping。
3d 纹理,例如:.tag 文件?
标签文件?抱歉,我不知道这种格式。你能给我一个阅读链接吗?谷歌没有找到有用的信息。你是说 TGA 吗?
【讨论】:
w 就像一个缩放参数。你不需要它。