我应该使用哪种 OpenGL ES 纹理格式来在 iPad 上获得更好的动态范围?

Posted

技术标签:

【中文标题】我应该使用哪种 OpenGL ES 纹理格式来在 iPad 上获得更好的动态范围?【英文标题】:What OpenGL ES texture format should I use for better dynamic range on iPad? 【发布时间】:2011-04-18 14:24:00 【问题描述】:

我正在开发一些使用纹理贴图来存储几何图形的软件。使用 GL_RGB 作为内部格式会产生很多混叠,我假设是因为默认情况下纹理被压缩到 GL_RGB4。

在桌面上,我可以使用 GL_RGB16 或 GL_RGB32F(等)来设置内部格式,但在 OpenGL ES 2.0 下似乎没有任何这些格式。 ios 下是否有可供我使用的替代方案或扩展程序?

【问题讨论】:

【参考方案1】:

根据 Apple(以及我自己的经验),GL_RGB 和 GL_UNSIGNED_BYTE 使用 8:8:8 存储。要降低颜色精度,您需要指定 GL_UNSIGNED_SHORT_5_6_5 类型或将多个通道打包成一个短通道的其他类型之一。

如果精度问题仍然存在,那么检查GL_OES_texture_float and GL_OES_texture_half_float 扩展可能是明智之举。您仅限于 GL_NEAREST 过滤,但我希望这就是您正在使用的内容,因为这是一个数据存储练习,您可以上传每像素 16 或 32 位的源通道。

编辑:直接从项目中提取的示例用法(正在上传 1 通道/像素图像,但你明白了):

GLfloat *integralImage;

/* <lots of stuff to allocate storage and fill integralImage here> */

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_LUMINANCE,
    256, 256, 0,
    GL_LUMINANCE, GL_FLOAT, 
    integralImage);

【讨论】:

我可能会误解这里的东西,但我认为 GL_FLOAT 只指定了输入格式(即传入的内容).. 并且 internalFormat(glTexImage 的参数 3)指定了它的存储方式纹理记忆。在我的笔记本电脑上,如果我使用 GL_RGB 作为 internalFormat 我会得到混叠,但如果我切换到 GL_RGB16 或 GL_RGB32F(即每个通道为 16/32 位),那么混叠就会消失(两者都使用 GL_FLOAT 作为类型)。 我认为这些含义可能与它们在桌面上的原意有所偏离;至少在 ES 中,内部格式仅用于区分您提供的通道。我在 ES 规范中的任何地方都找不到指定的输入格式将始终被 GPU 支持的声明,但可以根据经验告诉您它将在 iOS 上使用 float 扩展名。从中获取代码的项目上传了一个单通道纹理,其值将覆盖 24 位整数范围,我肯定会在着色器中获得全部范围。 哦,另外,我无法立即找到关于 RGB/UNSIGNED_CHAR 为 8:8:8 的明确参考,但您可以在devforums.apple.com/thread/94627?tstart=15等官方论坛答案中看到它隐含的说明【参考方案2】:

因此,经过一番研究,您可以获得浮动纹理(如 @Tommy 所述)。您不能做的是从 IOS 下的顶点着色器访问它们,从而无法使用它们来存储几何图形。

【讨论】:

以上是关于我应该使用哪种 OpenGL ES 纹理格式来在 iPad 上获得更好的动态范围?的主要内容,如果未能解决你的问题,请参考以下文章

绘制到纹理后的Opengl ES 2.0 glDeleteFramebuffers

OpenGL ES 压缩纹理

OpenGL 纹理格式 GL_R11F_G11F_B10F - 选择数据类型

Android OpenGL ES 纹理映射/绘图问题 - 倾斜图像

哪些 OpenGL ES 2.0 纹理格式可进行颜色、深度或模板渲染?

我应该始终对 OpenGL 中的所有纹理使用 GL_ARGB 格式吗?