纹理压缩简介 DXT PVR ETC

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了纹理压缩简介 DXT PVR ETC相关的知识,希望对你有一定的参考价值。

参考技术A

参考
为什么需要纹理压缩
移动端纹理压缩格式
干货:Unity游戏开发图片纹理压缩方案
Creator使用压缩纹理
常用纹理和纹理压缩格式
移动设备的纹理压缩方案
各种移动GPU压缩纹理的使用方法

在软件开发,特别是三维应用中,纹理随处可见,但受限于网络环境和硬件能力,纹理也是一大瓶颈。而且在一般的三维应用中,纹理所占大小基本都会在1/2以上,模型中往往超过2/3。或许你会说,纹理不就是一张图吗,有那么重要吗?如下两张对比图,可能你会认为前者逼格高,但对于正常人而言,后者显然要好很多。正是有了纹理,如同在骨架上赋予了皮肤,让我们的应用更加的逼真,贴近现实。

而你能想象到吗?如上的模型一共有三张纹理,其中之一效果如下:

纹理的拼接是纹理压缩的开始,采用不同的压缩方式对纹理最终的大小影响也是显著的。比如上面的这张纹理在不同压缩格式下的大小差别也是非常显著的(原始文件为tga格式,通过Photoshop转换为其他格式,默认选项):

不同于png、jgp这种硬盘压缩方式而言,DXT,ETC等纹理压缩方式可以在游戏运行中无需CPU解压就被GPU直接采样,可以极大的减少内存和带宽的占用,提升运行效率,对移动游戏而言更是如此。

1.DXT

DXT是一种有损纹理压缩算法,微软的Direct中支持,DXT的格式包括DXT1~DXT5,其中DXT1和DXT5较为多见,后面会做详细讨论。可以说DXT是目前应用最广泛的纹理压缩格式,可以认为所有的PC端显卡都支持DXT压缩,维基百科记录,该专利有效期到2017年10月2号。

DXT算法非常容易理解,而且整体看上去效果不错,但如果对局部特写,会发现在细节上会有很多丢失,这也是算法本身导致的,毕竟每个块只有两个颜色,而其他颜色都是在这两个颜色区间的差值,如果当前区域内还有其他显著颜色则必然会有丢失。

另外一个问题就是DXT3和DXT5之间的对比,相比DXT1不支持透明度(但支持是否透明),DXT5要大一倍(多了64bit),和之前颜色保存方案一样对透明度也保存了两个16位的颜色和对应的调色板,对RGBA的效果也得到了保证,但DXT3思路不一样,它是对每一个像素保存了4bit的透明度,同样也是多了64bit,但此时毕竟只有16个透明度选项,相比DXT5,在压缩率上相当,但对透明色的处理不够细腻,因此在实用性上并不推荐DXT3。

尽管DXT在细节上有明显硬伤,在总体效果不错,而且确实是一种强大的压缩方式,所以在多数纹理压缩选择中都是最佳方案,几乎可以认为是PC下的标准压缩格式。

2.PVR&ETC
也许是出于专利和商业角度,也许确实DXT在移动端确实无法满足要求,DXT并没有在移动端得到很大的支持,相反,在iOS设备中支持的是PVR压缩,在Android中支持的是ETC压缩。

DXT在细节上缺陷明显,最重要的原因是当把纹理分为4*4像素的区域块后,每个块之间都是独立的,尽管这极大的简化了压缩算法,但却丢失了相邻块之间这种普遍的相似性。这是算法本身导致的,而PVR则会考虑该区域块对应的右侧,下侧和右下侧的三个区域块的关联性。

从现实的角度来看,受制于专利和硬件厂商,我们并没太多选择的余地,android下就要用ETC,ios下只能PVR,而在PC上不用DXT估计就要被嘲讽了。但这也是一个很棘手的问题,比如在WebGL下,特别是Android下差异化很大,是否支持纹理压缩,甚至在同一个设备不同的浏览器,因为驱动的不一致,可能系统自带的会支持ETC压缩,而微信等QQ浏览器下并不支持。而且华为的手机貌似在浏览器级别下都不支持ETC(硬件支持,还是驱动的问题)。而如果在移动设备上不用压缩,显存是有限的,除非你在数据量上做出牺牲,怎么解决都很矛盾,相比而言,iOS下则要舒服很多。

Unity官网对每个平台默认的纹理压缩格式以及使用建议给出了 详细描述 ,需要注意的是:在不同移动GPU平台下选择GPU支持的压缩纹理,就可以在不需要CPU解压的情况下直接被GPU采样,节省CPU内存和带宽,也可以节省存储的体积。 如果目标平台不支持设置的压缩格式,纹理将解压为RGBA32或者RGB24,浪费CPU时间和内存

参考 几种主流贴图压缩算法的实现原理
从IOS9(A8架构)Apple 手机开始支持ASTC压缩格式 ,如果考虑放弃Apple 6代之前的手机兼容问题了,可以直接使用了。相对于PVRTC2/4而言,ASTC(4X4)的压缩比会增加到0.25,不过显示效果也会好很多,而且不需要把图片设置为方形。

Using ASTC Texture Compression for Game Assets 说明的比较详细,也给出了一些使用上的建议,即针对不同贴图类型给出不同的压缩方案。

1. laya问答 H5游戏能使用压缩纹理(ETC,PVR等)吗?
Q:H5游戏能使用压缩纹理(ETC,PVR等)吗?
A:部分浏览器会不支持(比如safari)
Q:那laya里面能根据不同浏览器(或不同平台)使用不同压缩格式的纹理吗?
A:你自己是可以获取到当前是哪个浏览器的,自行处理即可

2. LAYA Runtme目前支持 ETC/DXT或者PVR这类格式吗?在文档中没有找到这类的说明
LayaAir目前暂时还不支持ETC/DXT/PVR这类格式!关注layaAir的版本引擎更新日志即可,支持了我们会及时告知!

3. Egret 内存分析-RES加载资源后存在双份内存无法释放的问题
支持pvr、etc已经在计划中。

Android NDK。从.PVR文件加载ETC1压缩纹理

由于PVR文件格式和PVRTexTool实用程序支持ETC压缩 - 我想在Android项目中将它用于我的纹理。

不幸的是,我发现没有libs或示例如何从PVR文件加载ETC1 OpenGL纹理。

我有一个来源是iOS的Objective-C PVR加载器。但我需要一些关于Android NDK的C ++示例。

答案

不幸的是,似乎没有太多关于此的信息,但有一些事情。 http://www.brokenteapotstudios.com/android-game-development-blog/2011/05/loading-opengl-textures-in-c-and-etc1-texture-compression.html提供了所需的大部分信息。如果您想使用标题版本,请在此处描述标题格式http://www.mhgames.org/2012/03/android-development-loading-etc1-textures-from-ndk/

希望这有用:)

另一答案

首先阅读关于android:http://developer.android.com/guide/topics/graphics/opengl.html上压缩纹理的内容(向下滚动到“OpenGL版本和设备兼容性”一章)

还有ETC1Util类(如上面的链接所示):http://developer.android.com/reference/android/opengl/ETC1Util.html

逻辑上要做的是使用ETC1Util.isETC1Supported()来查看您的设备是否支持ETC1,如果不支持,则提供后备选项。

我还建议你看一下(如果你还没有这样做)在PowerVR android sdk:http://www.imgtec.com/powervr/insider/sdkdownloads/index.asp我自己没有看过它,但我确信它有你想要的东西。

所以,我认为不需要Objective-C ......

祝好运!

以上是关于纹理压缩简介 DXT PVR ETC的主要内容,如果未能解决你的问题,请参考以下文章

Unity ETC 压缩

DXT 纹理压缩?

OpenGL RGB DXT1压缩纹理mipmap上传

在硬件中高效实现 DXT1 纹理解压

(转)Unity 图片压缩技巧

UE4 材质纹理必要设置