ETC 纹理压缩和 Alpha 通道处理

转自:http://malideveloper.arm.com/cn/develop-for-mali/sample-code/etcv1-texture-compression-and-alpha-channels/

简介

就如压缩 JPEG 图像可以让更多图像装入磁盘一样,纹理压缩也可让更多纹理装入图形硬件中,这在移动平台上尤其重要。 Mali GPU 内建了硬件纹理压缩,允许纹理在图形硬件中保持压缩状态,在所需的样本上实时解压缩。 通过在应用程序中利用压缩纹理,可以大幅减少所需的内存带宽量,因而能提高应用程序性能,降低功耗。

ETC

Ericsson 纹理压缩或 ETC 是由 Khronos 支持的开放标准,在移动平台中广泛采用。 它是一种为感知质量设计的有损算法,其依据是人眼对亮度改变的反应要高于色度改变。

ETC v1 具有一个小缺陷,以这种格式压缩的纹理会丢失任何 Alpha 通道信息,而且也没有透明区域。 由于在纹理中使用 Alpha 通道可以实现许多更聪明、更有趣的做法,许多开发人员因此采用其他纹理压缩算法,其中很多为硬件支持有限的专有格式。

支持 ALPHA 通道

下文阐述的所有方法和技巧都可在 OpenGL ES SDK for Linux on ARM 和 OpenGL ES SDK for Android 中找到,其中提供了完整的源代码。

有许多技巧可供选用,以便在应用程序中支持透明并且依然采用 ETC 压缩。 本页阐述这些技巧。

提取 ALPHA 通道

这些方法中的第一步是从纹理中提取 Alpha 通道。 由于 Alpha 通道并不包装在压缩纹理中,因此必须与压缩纹理一起交付。 虽然大部分图形程序都可用于提取 Alpha 通道,但由于执行该任务比较费力,因此Mali GPU Texture Compression Tool 中提供了相应的支持。 您可以通过在“压缩选项”对话框中选择 Alpha 处理选项,来选择是否提取 Alpha 通道和如何进行提取。

ETC 纹理压缩和 Alpha 通道处理_第1张图片

方法 1: 纹理拼图

Alpha 通道转换为可见的灰度图像,然后串联到原始纹理上,使得总体纹理图形更高。

纹理拼图

益处

只有一个文件(对纹理加载代码的更改最少)

着色器代码改动需要较少(缩放)

缺点
纹理样本只能在一个方向上正确包裹。

缩放会减慢着色器执行

方法

这是最容易实施的方法,因为在纹理拼图图像压缩后,代码中唯一需要的更改是在着色器中重新映射纹理坐标,例如:

变为

这会缩放纹理坐标,以便使用图像的上半部分,然后移到下半部分以获取 Alpha 通道所处的第二样本。 本示例使用图像蒙版的红色通道来设置 Alpha 通道。

更为实际的做法是,可以向顶点着色器添加一个第二可变值。

让顶点着色器变为如下所示:

片段着色器接着可以使用这两个可变坐标:

这会将稍微多一点带宽用于额外的可变 vec2,但管线利用会更佳,尤其是大多数开发人员更加倾向于操作其片段着色器,而不是顶点着色器。 通过这些细小更改,大多数应用程序都能使用纹理拼图文件正常运行。

OpenGL ES SDK 示例“ETCAtlasAlpha”中提供了本示例的完整源代码列表。

不过,您可能会在某些情形中希望保留将纹理包裹到较大区域的能力。 下文中阐述了可实现此目的的其他两种方法。

方法 2: 单独包装 ALPHA

Alpha 通道作为第二包装的纹理交付。 两个纹理在着色代码中组合。

单独包装 ALPHA

 

益处

更加灵活,允许混合和匹配 Alpha/颜色通道

允许以两个方向包裹纹理

缺点

着色器中需要第二个纹理采样器。

方法
要创建适合用于此方法的压缩图像,请在纹理压缩工具中选择“创建单独压缩的图像”。

在加载第二个纹理时,请在 glBindTexture 和 glCompressedTexImage2D 之前调用 glActiveTexture(GL_TEXTURE1),以确保在不同的硬件纹理插槽中分配 Alpha 通道。

在设置着色器统一变量时,分配第二个纹理采样器,再绑定到第二纹理单元上:

然后在片段着色器中,再一次合并这两个样本,这一次从不同的纹理执行。

OpenGL ES SDK 示例“ETCCompressedAlpha”中提供了本示例的完整源代码列表。

方法 3: 单独的原始 ALPHA

Alpha 通道作为原始的 8 位单通道图像提供,在着色器中和纹理数据合并。

单独的原始 ALPHA

 

优势

更加灵活,允许混合和匹配 Alpha/颜色信息

允许未经压缩的 Alpha,因为有损 ETC1 压缩中会导致失真

缺点

着色器中需要第二个纹理采样器

与压缩相比,未压缩的 Alpha 会占用更多空间和内存带宽(尽管与未压缩 RGBA 纹理相比要少得多)

方法

要创建适合用于此方法的压缩图像,请在纹理压缩工具中选择“创建单独压缩的图像”。 根据所选的其他选项,这会生成单个 PGM 文件,或者每个纹理映射级别一个 PGM 文件,或者在一个 KTX 文件中包含作为未压缩数据的所有纹理映射级别。

PGM 格式在 http://netpbm.sourceforge.net/doc/pgm.html 予以介绍。而 KTX 格式则在http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ 中予以说明。

实施新方法来加载和绑定此纹理,但基于纹理的未压缩本质,其加载是比较琐碎的:

与以前一样,允许纹理加载到独立的活动纹理中:

再一次将它们单独加载到片段着色器中:

然后在片段着色器中,合并这两个样本,还是从两个不同的纹理进行:

OpenGL ES SDK 示例“ETCUncompressedAlpha”中提供了本示例的完整源代码列表。

 

OpenGL ES SDKs






你可能感兴趣的:(ETC 纹理压缩和 Alpha 通道处理)