本文介绍了如何在 iOS 中使用 3-D 纹理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 OpenGL ES 2.0 中找不到来自 OpenGL 的 glTexImage3D() 函数.那么如何使用 3-D 纹理,例如:.tga 文件?

I can't find the glTexImage3D() function from OpenGL in OpenGL ES 2.0. So how can I use a 3-D texture, eg: a .tga file?

有人知道如何在 OpenGL ES 2.0 中使用 3-D 纹理吗?

Does someone know how to use a 3-D texture in OpenGL ES 2.0?

推荐答案

OpenGL ES 1.x 和 2.x 不要求支持 3d 纹理 - 参见例如glBindTexture,它只列出了 GL_TEXTURE_2DGL_TEXTURE_CUBE_MAP 作为目标——而且 iOS 硬件没有提供任何合适的扩展.

OpenGL ES 1.x and 2.x doesn't mandate support for 3d textures — see e.g. the canonical man page for glBindTexture, which lists only GL_TEXTURE_2D and GL_TEXTURE_CUBE_MAP as targets — and the iOS hardware doesn't provide any suitable extension.

我能想出的最佳解决方案是将 3d 纹理打包成 2d 纹理,因此您可以说是 128x128x128 3d 纹理,然后将其布置为 128 个单独的 128x128 图像单个 2d 纹理上的 16x8 网格.因此 2d 纹理为 2048x1024 像素,接近 iPhone 4 和 iPad 2 代设备以及之前的 ES 2.0 兼容 iOS 设备的硬件限制.

The best solution I've been able to come up with is packing a 3d texture as though it were a 2d texture, so you've got say a 128x128x128 3d texture and you lay it out as 128 separate 128x128 images in an 16x8 grid on a single 2d texture. So the 2d texture is 2048x1024 pixels, getting close to the hardware limit on the iPhone 4 and iPad 2 generation of devices and the ES 2.0 compatible iOS devices that preceded them.

然后,您将 3d 纹理坐标提供给片段着色器,就像有一种方法可以在本地索引 3d 纹理一样,但需要快速计算一下以将其折叠为 2d.

You then feed a 3d texture coordinate to your fragment shader exactly as if there were a way to index 3d textures natively, but do a quick bit of maths to collapse it to 2d.

所以,在 128x128x128 的例子中,你会做类似的事情(编码在这里,正如我所说,未经测试,):

So, in the 128x128x128 example, you'd do something like (coded here, as I talk, untested, ):

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 纹理贴图以外的其他东西所必须花费的任何成本进行权衡.

That's probably not the most efficient way to achieve that, it's written for (relative) clarity. You're also looking at the significant performance disadvantage of every texture read being dependent (ie, the GPU can't predict the accesses outside of the fragment shader, causing significant pipeline difficulties). But that's to be weighed against whatever costs you would have to expend to use something other than 3d texture maps.

还请注意,您正在执行一个与特定 z 切片相关联的访问.因此,您只能在至少一个维度上进行 GL_NEAREST 类型的采样,除非您想进行两个采样并以更高的成本自行混合结果.我也没有对钳位做任何事情,你很可能想要解决这个问题.

Notice also that you're doing one access that's tied to a particular z slice. So you're limited to GL_NEAREST-type sampling in at least one dimension unless you want to do two samples and mix the result yourself at even greater cost. I've also done nothing about clamping, which you'll quite possibly want to address.

Datanwolf(+1,顺便说一句)关于 mipmapping 是一个问题也是完全正确的;我最终只是禁用了它.

Datenwolf (+1, incidentally) is also entirely correct about mipmapping being an issue; I ended up just disabling it.

2013 年末附录:在撰写本文时,iOS 7、iPhone 5s、第二代 iPad Mini 和 iPad Air 都支持 ES 3.0.3.0 引入了 GL_TEXTURE_3D 目标.因此,您可以直接在这些设备上使用 3d 纹理,并且可能在所有未来的 iOS 设备上使用.而且,据记录,它在 Android 上也有类似的可用性,所有最近的 Nexus 设备、HTC One、一些最近的三星和其他设备都支持它.

Late 2013 addendum: at the time of writing, iOS 7, the iPhone 5s, the second generation iPad Mini and the iPad Air all support ES 3.0. 3.0 introduces the GL_TEXTURE_3D target. So you can use 3d texturing directly on those devices and, probably, all future iOS devices. And, for the record, it's seeing similar availability on Android, having been supported in all the recent Nexus devices, the HTC One, a few of the recent Samsungs and others.

这篇关于如何在 iOS 中使用 3-D 纹理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!