一、简介

本文主要列举 OpenGL ES 3.0 中纹理格式有哪些,以及有效的内部格式、格式、类型组合。内容来自于 《OpenGL ES 3.0 编程指南 原书第2版》。

纹理格式主要应用于加载图像数据的相关接口,其中用于加载2D和立方图纹理的基本函数是 glTexImage2D,在 3.0 中还有多种替代方法指定 2D 纹理,如不可变纹理 glTexStorage2DglTexSubImage2D 的结合。

/**
 * @param target 目标纹理,即 GL_TEXTURE_2D、GL_TEXTURE_3D、GL_TEXTURE_2D_ARRAY 或 GL_TEXTURE_CUBE_MAP
 * @param level 指定要加载的mip级别。第一个级别为0,后续的mip贴图级别递增
 * @param internalformat 纹理存储的内部格式
 * @param width 图像的像素宽度
 * @param height 图像的像素高度
 * @param border 在OpenGL ES中忽略,保留是为了兼容桌面的OpenGL,传入0
 * @param format 输入的纹理数据格式
 * @param type 输入像素数据的类型
 * @param pixels 包含图像的实际像素数据
 */
void glTexImage2D(
        GLenum target, GLint level, GLint internalformat,
        GLsizei width, GLsizei height, GLint border,
        GLenum format, GLenum type, const GLvoid *pixels)

重点概念:

  • internalformat :纹理存储的内部格式
  • format :输入纹理的数据格式
  • type :输入像素的类型

二、有效的 internalformat、format 和 type 组合

1. 未确定大小的内部格式组合

使用未确定大小的格式指定纹理,则 OpenGL ES 实现可以自由选择纹理数据存储的内部表现形式。

内部格式格式类型输入数据
GL_RGBGL_RGBGL_UNSIGNED_BYTE8/8/8 RGB 24位
GL_RGBGL_RGBGL_UNSIGNED_SHORT_5_6_55/6/5 RGB 16位
GL_RGBAGL_RGBAGL_UNSIGNED_BYTE8/8/8/8 RGBA 32位
GL_RGBAGL_RGBAGL_UNSIGNED_SHORT_4_4_4_44/4/4/4 RGBA 16位
GL_LUMINANCE_ALPHAGL_LUMINANCE_ALPHAGL_UNSIGNED_BYTE8/8 LA 16位
GL_LUMINANCEGL_LUMINANCEGL_UNSIGNED_BYTE8L 8位
GL_ALPHAGL_ALPHAGL_UNSIGNED_BYTE8A 8位

2. 确定大小的内部格式组合

如果应用程序希望更多地控制数据的内存存储格式,那么可以使用确定大小的内部格式。在这种情况下,OpenGL ES 3.0 实现可以选择转换为较少的位数,或者使用具有更多位数的格式。

其中又分为如下类别:规范化纹理格式浮点纹理整数纹理共享指数纹理sRGB纹理深度纹理

规范化纹理格式

所谓 “规范化” 指的是从片段着色器中读取纹理时,结果将映射到 [0.0, 1.0] 范围内(或者在 *_SNORM 格式中映射到 [-1.0, 1.0] 范围)。例如无符号字节值(范围 [0, 255])在片段读取时将映射到 [0.0, 1.0] 的范围。

内部格式格式类型输入数据RF
GL_R8GL_REDGL_UNSIGNED_BYTE8位红色XX
GL_R8_SNORMGL_REDGL_BYTE8位红色(有符号)X
GL_RG8GL_RGGL_UNSIGNED_BYTE8/8 RGXX
GL_RG8_SNORMGL_RGGL_BYTE8/8 RG(有符号)X
GL_RGB8GL_RGBGL_UNSIGNED_BYTE8/8/8 RGBXX
GL_RGB8_SNORMGL_RGBGL_BYTE8/8/8 RGB(有符号)X
GL_RGB565GL_RGBGL_UNSIGNED_BYTE8/8/8 RGBXX
GL_RGB565GL_RGBGL_UNSIGNED_SHORT_5_6_55/6/5 RGBXX
GL_RGBA8GL_RGBAGL_UNSIGNED_BYTE8/8/8/8 RGBAXX
GL_RGBA8_SNORMGL_RGBAGL_BYTE8/8/8/8 RGBA(有符号)X
GL_RGB5_A1GL_RGBAGL_UNSIGNED_BYTE8/8/8/8 RGBAXX
GL_RGB5_A1GL_RGBAGL_UNSIGNED_SHORT_5_5_5_15/5/5/1 RGBAXX
GL_RGB5_A1GL_RGBAGL_UNSIGNED_SHORT_2_10_10_10_REV10/10/10/2 RGBAXX
GL_RGBA4GL_RGBAGL_UNSIGNED_BYTE8/8/8/8 RGBAXX
GL_RGBA4GL_RGBAGL_UNSIGNED_SHORT_4_4_4_44/4/4/4 RGBAXX
GL_RGB10_A2GL_RGBAGL_UNSIGNED_INT_2_10_10_10_REV10/10/10/2 RGBAXX

备注:

  • R = 格式可渲染
  • F = 格式可过滤
  • X 表示支持
浮点纹理格式

ES 3.0 引入了浮点纹理格式,大部分浮点格式由16位半浮点数据或者32位浮点数据支持。此外,还引入了 11/11/10 GL_R11F_G11F_B10F 这样的浮点格式,可提供更高精度的三通道纹理,同时仍保持每个纹素的存储量为32位,这种格式的使用可能达到比 16/16/16 GL_RGB16F32/32/32 GL_RGB32F 更高的性能。

内部格式格式类型输入数据RF
GL_R16FGL_REDGL_HALF_FLOAT16位红色(半浮点)X
GL_R16FGL_REDGL_FLOAT32位红色(浮点)X
GL_R32FGL_REDGL_FLOAT32位红色(浮点)
GL_RG16FGL_RGGL_HALF_FLOAT16/16 RG(半浮点)X
GL_RG16FGL_RGGL_FLOAT32/32 RG(浮点)X
GL_RG32FGL_RGGL_FLOAT32/32 RG(浮点)
GL_RGB16FGL_RGBGL_HALF_FLOAT16/16/16 RGB(半浮点)X
GL_RGB16FGL_RGGL_FLOAT16/16 RGB(浮点)X
GL_RGB32FGL_RGGL_FLOAT32/32/32 RGB(浮点)
GL_R11F_G11F_B10FGL_RGBGL_UNSIGNED_INT_10F_11F_11F_REV10/11/11(浮点)X
GL_R11F_G11F_B10FGL_RGBGL_HALF_FLOAT16/16/16 RGB(半浮点)X
GL_R11F_G11F_B10FGL_RGBGL_FLOAT32/32/32 RGB(浮点)X
GL_RGBA16FGL_RGBAGL_HALF_FLOAT16/16/16/16 RGBA(半浮点)X
GL_RGBA16FGL_RGBAGL_FLOAT32/32/32/32 RGBA(浮点)X
GL_RGBA32FGL_RGBAGL_FLOAT32/32/32/32 RGBA(浮点)
整数纹理格式

整数纹理格式允许纹理规范在片段着色器中以整数形式读取。即整数纹理中的值在片段着色器读取时仍然为整数,而不是转化为规范化浮点值。

内部格式格式类型输入数据RF
GL_R8UIGL_RED_INTEGERGL_UNSIGNED_BYTE8位红色(无符号整数)X
GL_R8IGL_RED_INTEGERGL_BYTE8位红色(有符号整数)X
GL_R16UIGL_RED_INTEGERGL_UNSIGNED_SHORT16位红色(无符号整数)X
GL_R16IGL_RED_INTEGERGL_SHORT16位红色(有符号整数)X
GL_R32UIGL_RED_INTEGERGL_UNSIGNED_INT32位红色(无符号整数)X
GL_R32IGL_RED_INTEGERGL_INT32位红色(有符号整数)X
GL_RG8UIGL_RG_INTEGERGL_UNSIGNED_BYTE8/8 RG(无符号整数)X
GL_RG8IGL_RG_INTEGERGL_BYTE8/8 RG(有符号整数)X
GL_RG16UIGL_RG_INTEGERGL_UNSIGNED_SHORT16/16 RG(无符号整数)X
GL_RG16IGL_RG_INTEGERGL_SHORT16/16 RG(有符号整数)X
GL_RG32UIGL_RG_INTEGERGL_UNSIGNED_INT32/32 RG(无符号整数)X
GL_RG32IGL_RG_INTEGERGL_INT32/32 RG(有符号整数)X
GL_RGBAUIGL_RGBA_INTEGERGL_UNSIGNED_BYTE8/8/8/8 RGBA(无符号整数)X
GL_RGBAIGL_RGBA_INTEGERGL_BYTE8/8/8/8 RGBA(有符号整数)X
GL_RGB8UIGL_RGB_INTEGERGL_UNSIGNED_BYTE8/8/8 RGB(无符号整数)
GL_RGB8IGL_RGB_INTEGERGL_BYTE8/8/8 RGB(有符号整数)
GL_RGB16UIGL_RGB_INTEGERGL_UNSIGNED_SHORT16/16/16 RGB(无符号整数)
GL_RGB16IGL_RGB_INTEGERGL_SHORT16/16/16 RGB(有符号整数)
GL_RGB32UIGL_RGB_INTEGERGL_UNSIGNED_INT32/32/32 RGB(无符号整数)
GL_RGB32IGL_RGB_INTEGERGL_INT32/32/32 RGB(有符号整数)
GL_RG32IGL_RG_INTEGERGL_INT32/32 RG(有符号整数)X
GL_RGB10_A2_UIGL_RGBA_INTEGERGL_UNSIGNED_INT_2_10_10_10_REV10/10/10/2 RGBA(无符号整数)X
GL_RGBA16UIGL_RGBA_INTEGERGL_UNSIGNED_SHORT16/16/16/16 RGBA(无符号整数)X
GL_RGBA16IGL_RGBA_INTEGERGL_SHORT16/16/16/16 RGBA(有符号整数)X
GL_RGBA32UIGL_RGBA_INTEGERGL_UNSIGNED_INT32/32/32/32 RGBA(无符号整数)X
GL_RGBA32IGL_RGBA_INTEGERGL_INT32/32/32/32 RGBA(有符号整数)X
共享指数纹理格式

共享指数纹理为不需要浮点纹理使用的那么多深度位数的大范围 RGB 纹理提供了一种存储方式。共享指数纹理通常用于高动态范围(HDR)图像,这种图像不需要半浮点或者全浮点数据。

OpenGL ES 3.0 中共享指数纹理的内部格式均为 GL_RGB9_E5。该格式中,3个 RGB 分量共享一个5位的指数。5位的指数隐含地由数值15调整,RGB 的每个9位的数值存储无符号位的尾数(因此必然为正)。

输入数据推荐直接地将16位半浮点数或者32位浮点数传递给 OpenGL ES,让它进行计算转换为 RGB9_E5。

内部格式格式类型输入数据RF
GL_RGB9_E5GL_RGBGL_UNSIGNED_INT_5_9_9_9_REV9/9/9 RGB 带5位指数X
GL_RGB9_E5GL_RGBGL_HALF_FLOAT16/16/16 RGB(半浮点)X
GL_RGB9_E5GL_RGBGL_FLOAT32/32/32 RGB(浮点)X
sRGB 纹理格式

sRGB 是一个非线性颜色空间,大约遵循一个幂函数。如果用于纹理的图像是以 sRGB 颜色空间创作的,那么为了正确地处理 sRGB 图像,应用程序应该使用一个 sRGB 纹理格式。

内部格式格式类型输入数据RF
GL_SRGB8GL_RGBGL_UNSIGNED_BYTE8/8/8 RGBX
GL_SRGB8_ALPHA8GL_RGBAGL_UNSIGNED_BYTE8/8/8/8 RGBAXX
深度纹理格式

深度纹理允许应用程序从帧缓冲区对象的深度附着中读取深度值(和可选的模板值)。这在各种高级渲染算法中很有用,包括阴影贴图。

内部格式格式类型
GL_DEPTH_COMPONENT16GL_DEPTH_COMPONENTGL_UNSIGNED_SHORT
GL_DEPTH_COMPONENT16GL_DEPTH_COMPONENTGL_UNSIGNED_INT
GL_DEPTH_COMPONENT24GL_DEPTH_COMPONENTGL_UNSIGNED_INT
GL_DEPTH_COMPONENT32FGL_DEPTH_COMPONENTGL_FLOAT
GL_DEPTH24_STENCIL8GL_DEPTH_STENCILGL_UNSIGNED_INT_24_8
GL_DEPTH32F_STENCIL8GL_DEPTH_STENCILGL_FLOAT_32_UNSIGNED_INT_24_8_REV
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐