本文共 2931 字,大约阅读时间需要 9 分钟。
分享一下我老师大神的人工智能教程!零基础,通俗易懂!
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
转自:
简介
就如压缩 JPEG 图像可以让更多图像装入磁盘一样,纹理压缩也可让更多纹理装入图形硬件中,这在移动平台上尤其重要。 Mali GPU 内建了硬件纹理压缩,允许纹理在图形硬件中保持压缩状态,在所需的样本上实时解压缩。 通过在应用程序中利用压缩纹理,可以大幅减少所需的内存带宽量,因而能提高应用程序性能,降低功耗。
ETC
Ericsson 纹理压缩或 ETC 是由 Khronos 支持的开放标准,在移动平台中广泛采用。 它是一种为感知质量设计的有损算法,其依据是人眼对亮度改变的反应要高于色度改变。
ETC v1 具有一个小缺陷,以这种格式压缩的纹理会丢失任何 Alpha 通道信息,而且也没有透明区域。 由于在纹理中使用 Alpha 通道可以实现许多更聪明、更有趣的做法,许多开发人员因此采用其他纹理压缩算法,其中很多为硬件支持有限的专有格式。
支持 ALPHA 通道
下文阐述的所有方法和技巧都可在 和 中找到,其中提供了完整的源代码。
有许多技巧可供选用,以便在应用程序中支持透明并且依然采用 ETC 压缩。 本页阐述这些技巧。
提取 ALPHA 通道
这些方法中的第一步是从纹理中提取 Alpha 通道。 由于 Alpha 通道并不包装在压缩纹理中,因此必须与压缩纹理一起交付。 虽然大部分图形程序都可用于提取 Alpha 通道,但由于执行该任务比较费力,因此 中提供了相应的支持。 您可以通过在“压缩选项”对话框中选择 Alpha 处理选项,来选择是否提取 Alpha 通道和如何进行提取。
方法 1: 纹理拼图
Alpha 通道转换为可见的灰度图像,然后串联到原始纹理上,使得总体纹理图形更高。
益处
只有一个文件(对纹理加载代码的更改最少)
着色器代码改动需要较少(缩放)
缺点
纹理样本只能在一个方向上正确包裹。缩放会减慢着色器执行
方法
这是最容易实施的方法,因为在纹理拼图图像压缩后,代码中唯一需要的更改是在着色器中重新映射纹理坐标,例如:
1 | gl_FragColor = texture2D ( u_s2dTexture , v_v2TexCoord ) ; |
变为
1 2 3 | vec4 v4Colour = texture2D ( u_s2dTexture , v_v2TexCoord ) ; v4Colour . a = texture2D ( u_s2dTexture , v_v2TexCoord * vec2 ( 1.0 , 0.5 ) + v_v2TexCoord * vec2 ( 0.0 , 0.5 ) ) . r ; gl_FragColor = v4Colour ; |
这会缩放纹理坐标,以便使用图像的上半部分,然后移到下半部分以获取 Alpha 通道所处的第二样本。 本示例使用图像蒙版的红色通道来设置 Alpha 通道。
更为实际的做法是,可以向顶点着色器添加一个第二可变值。
让顶点着色器变为如下所示:
1 2 3 4 5 6 7 8 9 10 11 | attribute vec4 a_v4Position ; attribute vec2 a_v2TexCoord ; varying vec2 v_v2TexCoord ; varying vec2 v_v2AlphaCoord ; void main ( ) { v_v2TexCoord = a_v2TexCoord * vec2 ( 1.0 , 0.5 ) ; v_v2AlphaCoord = v_v2TexCoord + vec2 ( 0.0 , 0.5 ) ; gl_Position = a_v4Position ; } |
片段着色器接着可以使用这两个可变坐标:
1 2 3 4 5 6 7 8 9 10 11 | precision mediump float ; uniform sampler2D u_s2dTexture ; varying vec2 v_v2TexCoord ; varying vec2 v_v2AlphaCoord ; void main ( ) { vec4 v4Colour = texture2D ( u_s2dTexture , v_v2TexCoord ) ; v4Colour . a = texture2D ( u_s2dTexture , v_v2AlphaCoord ) . r ; gl_FragColor = v4Colour ; } |
这会将稍微多一点带宽用于额外的可变 vec2,但管线利用会更佳,尤其是大多数开发人员更加倾向于操作其片段着色器,而不是顶点着色器。 通过这些细小更改,大多数应用程序都能使用纹理拼图文件正常运行。
OpenGL ES SDK 示例“ETCAtlasAlpha”中提供了本示例的完整源代码列表。
不过,您可能会在某些情形中希望保留将纹理包裹到较大区域的能力。 下文中阐述了可实现此目的的其他两种方法。
方法 2: 单独包装 ALPHA
Alpha 通道作为第二包装的纹理交付。 两个纹理在着色代码中组合。
益处
更加灵活,允许混合和匹配 Alpha/颜色通道
允许以两个方向包裹纹理
缺点
着色器中需要第二个纹理采样器。
方法
要创建适合用于此方法的压缩图像,请在纹理压缩工具中选择“创建单独压缩的图像”。在加载第二个纹理时,请在 glBindTexture 和 glCompressedTexImage2D 之前调用 glActiveTexture(GL_TEXTURE1),以确保在不同的硬件纹理插槽中分配 Alpha 通道。
1 2 3 4 | glActiveTexture ( GL_TEXTURE0 ) ; loadCompressedMipmaps ( TEXTURE_FILE , TEXTURE_FILE_SUFFIX , & amp ; iTexName ) ; glActiveTexture ( GL_TEXTURE1 ) ; loadCompressedMipmaps ( ALPHA_FILE , TEXTURE_FILE_SUFFIX , & amp ; iAlphaName ) ; |
在设置着色器统一变量时,分配第二个纹理采样器,再绑定到第二纹理单元上:
1 2 3 4 | iLocSampler = glGetUniformLocation ( iProgName , "u_s2dTexture" ) ; glUniform1i ( iLocSampler , 0 ) ; iLocSamplerAlpha = glGetUniformLocation ( iProgName , "u_s2dAlpha" ) ; glUniform1i ( iLocSamplerAlpha , 1 ) ; |
然后在片段着色器中,再一次合并这两个样本,这一次从不同的纹理执行。
转载地址:https://blog.csdn.net/hddghhfd/article/details/84062380 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!