News:Stage3D compressed textures
原文:http://www.bytearray.org/?p=4472
Starling中文站 翻译整理
目录 |
Stage3D中的压缩纹理 - 介绍ATF SDK
我们从去年开始就一直在介绍Stage3D,它从来没有停止过增长的势头,但是有一个领域,我们一直没有透露所有的细节。这就是ATF格式。它在很多地方被人问起,那么它现在有更新了吗?你们中的一些人,可能已经看到了在Stage3D的文档中关于压缩纹理的描述,但我们一直没有分享任何工具,来创建早已名声在外的ATF格式。
在ATF工具正式被整合到AIR SDK之前,我很高兴在这里预先分享一下ATF工具,这样您可以现在就开始使用ATF格式!
那么ATF到底是何方神圣呢?
首先,让我们开始讨论一下压缩纹理的由来和原理。
无论使用哪种语言去做GPU编程,您在纹理处理上都有两个选择:您可以使用压缩的纹理,或未被压缩的纹理,很简单。那么,它们之间的区别是什么呢?
- 当使用未压缩的纹理,比如使用古老的未压缩文件格式PNG,将这种格式上传给GPU
- 由于GPU本身不支持这种格式,您的纹理实际上是被存储在RAM中,而不是GPU中
- 同样这种情况也适用于JPEG图片,是的,图形芯片组不知道任何关于JPEG的信息。
- 当然,每个平台支持不同的压缩纹理格式,取决于它的芯片组
这是很有趣的,下面的表格说明了这种情况:
为什么要使用ATF格式?
您可以想象一下,如果您要开发一个可以运行在iOS, Android和桌面的游戏,您就需要为每一个平台压缩对应的纹理格式。就像下面这样:
- leaf.png 编码为 DXT格式,用于 Windows 和 MacOS
- leaf.png 编码为 ETC1 或 DXT 格式,用于 Android (Nvidia)
- leaf.png 编码为 PVRTC格式,用于 iOS (ImgTech)
当然,这个过程是非常痛苦的:要为所有的平台提供不同版本的纹理,并且在运行时检测平台,然后上传对应的纹理。如果有这么一个东西就太酷了:它可以作为一个单一的容器,来包装所有的纹理,然后每一个平台的Flash Player或AIR会自动从其中提取所需的纹理。很酷吧?所以ATF格式诞生了。
ATF格式解析
事实上,ATF格式是存储有损压缩图像的容器。下面的图片,展示了一个默认的压缩过的ATF格式的简单结构:
默认情况下,需要把所有的纹理格式(PVRTC(4bpp),ETC1和DXT1/5)嵌入到ATF文件中,以便在任何平台上,AIR或Flash Player都可以自动提取到对应的纹理。但是在某些情况下,如果您的目标是移动设备,那么为什么还要为桌面嵌入纹理呢?或者如果您的目标是iOS,那么为什么还要为Android嵌入纹理呢?为了弥补这一点,您可以只在ATF文件中嵌入PVRTC格式的纹理,以减小文件尺寸。
下图说明了这样的想法:
以此类推,如果您的目标是Android设备,可以只应用ETC1格式:
如果您了解ETC1,可能会问,我们该如何处理透明度呢?我们使用的是双ETC1方式,有两个纹理,一个是透明度通道,一个是颜色。
最后如果只支持桌面,可以只提供DXT格式:
要知道DXT1和DXT5对于透明度的支持是不同的。DXT1不支持透明度,而DXT5支持。自动化的ATF工具,将检测您的图像是否具备透明度,然后为您选择合适的DXT版本。另外请注意,ATF格式不是透明度预先相乘的。
现在,如果您想在ATF中存储未压缩的纹理,您也可以做到这一点:
您可能会问,为什么我们要这样做呢?答案是,您在一些情况下(比如充分利用cubemap,自动化mipmap支持,或纹理流的支持),可能会想使用未压缩的纹理。
好了,除了上面硬件的需求,如果这些纹理被压缩,还可以为我们带来什么价值?
那么这些特性为我们带来了什么?
- 更快的渲染
- 更少的存储空间占用 (在譬如iPad1这样的设备上,这个特性是非常重要的)
- 更快的纹理上传速度
- 自动产生所有的mip-map映射 (注意如果需要的话,你可以关掉它).
- 此外,使用压缩纹理,可以让您在同等内存占用的情况下,使用更高分辨率的纹理
好了现在的问题是,您该如何创建ATF格式呢?这并不难,我们提供了一些命令行工具来帮助您。来看看他们是如何工作的吧。
如何使用这些工具
您主要需要了解的是png2atf工具,正如您猜到的,它可以将一个PNG文件转换为ATF文件:
//package leaf.png with all 3 formats (DXT5, PVRTC and ETC1x2) C:\png2atf.exe -c -i leaf.png -o leaf.atf [In 213KB][Out 213KB][Ratio 99.9703%][LZMA:0KB JPEG-XR:213KB] //package specific range of mipmaps C:\png2atf.exe -c -n 0,5 -i leaf.png -o leaf0,5.atf [In 213KB][Out 213KB][Ratio 99.8825%][LZMA:0KB JPEG-XR:213KB] //package only DXT format C:\png2atf.exe -c d -i leaf.png -o leaf_dxt5.atf [In 85KB][Out 85KB][Ratio 100.045%][LZMA:0KB JPEG-XR:85KB] //package only ETC1 format C:\png2atf.exe -c e -i leaf.png -o leaf_etc1.atf [In 85KB][Out 85KB][Ratio 100.045%][LZMA:0KB JPEG-XR:85KB] //package only PVRTC format C:\png2atf.exe -c p -i leaf.png -o leaf_pvrtc.atf [In 42KB][Out 42KB][Ratio 100.089%][LZMA:0KB JPEG-XR:42KB]
如果我要在ATF中使用未压缩的纹理该怎么办呢? 别急, 只需去除 -c 参数即可:
//package as uncompressed (RGBA) format C:\png2atf.exe -i leaf.png -o leaf_rgba.atf [In 341KB][Out 43KB][Ratio 12.8596%][LZMA:0KB JPEG-XR:43KB]
另一个很酷的特性是,ATF可以处理纹理流,您可以这样操作来生成3个子文件:
png2atf -m -n 0,0 -c -i cubecat0.png -o cubecat_c_high.atf png2atf -m -n 1,2 -c -i cubecat0.png -o cubecat_c_med.atf png2atf -m -n 3,20 -c -i cubecat0.png -o cubecat_c_low.atf
注意,从Flash Player 11.3和AIR 3.3的版本开始才支持纹理流。当您想使用纹理流的时候,别忘了使用Texture.createTexture()接口的streamingLevel参数。
如果您已经使用苹果的工具生成了PVR纹理,那么用法是相同的。还有一个叫做pvr2atf的工具,它也是一个命令行工具,来把PVR纹理转换为ATF文件。这个工具的用法和png2atf是类似的,您需要提供一个PVR的纹理作为输入。
要转换PVR 文件为 RGB 或 RGBA格式的 ATF 文件,只需要运行下面的命令:
C:\> pvr2atf -i test.pvr -o test.atf [In 4096KB][Out 410KB][Ratio 10.0241%][LZMA:0KB JPEG-XR:410KB]
同样,您可以使用ATF来处理 cubemap texture:
//to create a ATF for cubemap texture, //prepare png file for each side of the cube as: // -X: cube0.png //+X: cube1.png // -Y: cube2.png //+Y: cube3.png // -Z: cube4.png //+Z: cube5.png C:\png2atf.exe -c -m -i cube0.png -o cube.atf
ATFViewer是一个用于预览和检查ATF文件的图形化的工具。它的主要作用是检查DXT1,ETC1和PVRTC的压缩情况。您可以通过“Open...”菜单,打开和查看一个ATF文件,或者把一个文件拖拽进来。片段预览区域,向您展示了一个如何在ActionScript 3的Stage3D代码中加载ATF文件的例子。
下面是一个例子,使用了Starling框架中的一个测试文件,您可以预览这个纹理的所有格式,并且在底部有一段示例代码,告诉您如何在ActionScript 3和Stage3D中使用它。
注意当您打开了一个只包含特定格式的ATF纹理,比如在下图中我们打开的ATF文件只包含DXT纹理,您可以看见ETC1和PVRTC的部分全部是灰色显示。
让我们来看看如何使用Stage3D 的接口来解析ATF纹理.
在Stage3D中使用压缩纹理
要在Stage3D中使用压缩纹理,您需要使用这个接口:Texture.uploadCompressedTextureFromByteArray,并确定使用由Context3DTextureFormat定义的两种格式中的某一个:(Context3DTextureFormat.COMPRESSED_ALPHA 和 Context3DTextureFormat.COMPRESSED):
class Example { [Embed( source = "mytexture.atf", mimeType="application/octet-stream")] public static const TextureAsset:Class; public var context3D:Context3D; public function init():void{ var texture:Texture = context3D.createTexture(256, 256, Context3DTextureFormat.COMPRESSED_ALPHA, false); var textureAsset:ByteArray = new TextureAsset() as ByteArray; texture.uploadCompressedTextureFromByteArray(textureAsset, 0); } };
如果是cubemap texture, 您可以这样写:
var texCubemap:CubeTexture = context3D.createCubeTexture(256, Context3DTextureFormat.COMPRESSED_ALPHA, false); var textureAsset:ByteArray = new TextureAsset() as ByteArray; texCubemap.uploadCompressedTextureFromByteArray(textureAsset, 0);
同样, 根据纹理的格式, “dxt1” 或 “dxt5” 需要您在片段着色器中作出相应的设置:
- 如果是Context3DTextureFormat.BGRA, 什么都不需要
- “dxt1” 格式需要 Context3DTextureFormat.COMPRESSED (包括 DXT, PVRTC, 或 ETC1)
- “dxt5” 格式需要 Context3DTextureFormat.COMPRESSED_ALPHA (包括 DXT, PVRTC, 或 ETC1)
您可以参考这个《 Starling对于ATF格式的支持》 看看它的生成过程。
和Starling的整合
好消息是,Starling中以及增加了对ATF格式的支持,接口是Texture.uploadAtfData。下面是一个简短的例子:
[Embed(source="starling.atf", mimeType="application/octet-stream")] public static const CompressedData:Class; var data:ByteArray = new CompressedData(); var texture:Texture = Texture.fromAtfData(data); var image:Image = new Image(texture); addChild(image);
是的,就是这么简单:)
限制
尽管ATF对于2D内容(比如Starling)是非常有用的,而且它也被广泛应用于3D纹理支持,但我还要强调它的一些限制。为什么呢?
因为对于纹理的有损压缩,是会损失素材的质量的。还有像RGBA8888和RGBA4444的PVR目前是不支持的,这是一个问题。
但是我们非常需要您的反馈和测试,来帮助我们优化和完善ATF,并且未来让它支持更多的格式。有什么建议就告诉我们吧!
必备条件
请注意要使用ATF纹理的话,您需要满足一些必备条件:
- 如果您使用Starling, 请确保使用了Starling 1.2或更高的版本. 从这里 获取最新版本.
- 如果您直接使用Stage3D, 您需要使用最终的 AGALMiniAssembler
- 您需要最新的AIR SDK 3.4. 下载 Flash Builder 4.7 这个已经内置了 AIR 3.4 SDK.
- 您需要最新的 Flash Player 11.4/AIR 3.4
- 您需要在编译参数中添加: ”-swf-version=17”
下载
从这里下载ATF工具: 点击我下载. 它包含了:
- ATF工具包 (适用Linux, Mac, Windows).
- ATF 规范说明
- ATF的用户指南.
祝好运!
译者:郭少瑞