[Unity] 在Unity中纹理图该是什么格式?

一个在Windows下的png格式图,在Unity中存储为什么格式?

Unity下的资源导入问题:

Unity会把我们放进去的外部资源转换成一种Unity内部格式的资源,这个过程就是资源导入。

比如说在Windows下显示为png格式的图片,在Unity内部会根据平台的不同而设置成不同的压缩格式

可以使用AssetPostProcessor来对导入的资源进行规定化。

AssetPostProcessor是一个编辑器类,用来管理资源导入,当资源导入之前和之后都会发送通知,可以根据不同的资源类型,在导入之前和之后做不同的处理,来修改Unity内部资源格式。

由于这是一个编辑器类,在UnityEditor命名空间下,所以在使用C#脚本时,需要在脚本前加上using UnityEditor引用,且放在工程目录下的Asset/Editor文件夹下。
一般我们通过修改这个类中OnPreprocessxxxOnPostprocessxxx函数来修改资源数据和设置。
这两者的区别可以简单理解为:前者用来Inspector视图可见的选项,后者为不可见的。

下面的脚本可以自动设置不同文件夹下贴图的压缩格式以及大小:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using UnityEditor;
using UnityEngine;

public class Script_12_02 : AssetPostprocessor
{
void OnPreprocessTexture()
{
TextureImporter textureImporter = (TextureImporter)assetImporter;

if(textureImporter.assetPath.Contains("UI"))
{
textureImporter.textureType = TextureImporterType.Sprite;
textureImporter.mipmapEnabled = false;

// 设置UI贴图在三个平台下的压缩格式以及大小
textureImporter.SetPlatformTextureSettings("Standalone",2048,TextureImporterFormat.RGBA32);
textureImporter.SetPlatformTextureSettings("iPhone",2048,TextureImporterFormat.RGBA32,100,true);
textureImporter.SetPlatformTextureSettings("Android",2048,TextureImporterFormat.RGBA32,true);
}
else if(textureImporter.assetPath.Contains("Texture"))
{
textureImporter.textureType = TextureImporterType.Default;
textureImporter.mipmapEnabled = true;

// 设置模型贴图在三个平台下的压缩格式以及大小
textureImporter.SetPlatformTextureSettings("Standalone",2048,TextureImporterFormat.DXT5);
textureImporter.SetPlatformTextureSettings("iPhone",2048,TextureImporterFormat.ASTC_RGBA_4x4,100,true);
textureImporter.SetPlatformTextureSettings("Android",2048,TextureImporterFormat.ETC_RGB4,true);

}
}
}

拓展阅读:

为什么要进行纹理压缩:http://www.newhappy.com.cn/?p=907

那么纹理有哪些压缩格式呢?

桌面平台:

  • RGB Compressed DXT1 压缩的RGB纹理。这是最常见的漫反射纹理格式。4位/像素(32 KB 256x256)
  • RGBA Compressed DXT5 压缩的RGBA纹理。这是漫反射和高光控制纹理的主要格式。1 字节/像素(64 KB 256x256)
  • RGB 16 bit 65万颜色不带alpha。压缩的DXT格式使用较少的内存,通常会更好看。(128 KB 256x256)
  • RGB 24 bit 真彩色不带alpha。(192 KB 256x256)
  • Alpha 8 bit 高质量alpha通道,不带颜色。(64 KB 256x256)
  • RGBA 16 bit 低质量真彩色。有16级红,绿,蓝和alpha。压缩的DXT5格式使用较少的内存,通常会更好看。(128 KB 256x256)
  • RGBA 32 bit 高质量真彩色带alpha(256 KB 256x256),这个文件很大。大多数情况下
  • DXT5提供足够的质量,文件大小要小得多。这个主要用于法线贴图,DXT压缩往往带有一个可见的质量损失。

Android:

  • RGB Compressed DXT1 压缩的RGB纹理。支持Nvidia Tegra。4位/像素(32 KB 256x256)
  • RGBA Compressed DXT5 压缩的RGBA纹理。支持Nvidia Tegra。6位/像素(64 KB 256x256)
  • RGB Compressed ETC 4 bits 压缩的RGB纹理。这是Android工程默认的纹理格式。
  • ETC1是OpenGL ES 2.0标准的一部分,并且支持所有的OpenGL ES 2.0 GPU,但它不支持Alpha。4位/像素(32 KB 256x256)
  • RGB Compressed PVRTC 2 bits 压缩的RGB纹理。 支持Imagination PowerVR GPU。2位/像素(16 KB 256x256)
  • RGBA Compressed PVRTC 2 bits 压缩的RGBA纹理。支持Imagination PowerVR GPU。2位/像素(16 KB 256x256)
  • RGB Compressed PVRTC 4 bits 压缩的RGB纹理。 支持Imagination PowerVR GPU。4位/像素(32 KB 256x256)
  • RGBA Compressed PVRTC 4 bits 压缩的RGBA纹理。 支持Imagination PowerVR GPU。4位/像素(32 KB 256x256)
  • RGB Compressed ATC 4 bits 压缩的RGB纹理。 支持Qualcomm Snapdragon。4位/像素(32 KB 256x256)
  • RGBA Compressed ATC 8 bits 压缩的RGB纹理。 支持Qualcomm Snapdragon。6位/像素(64 KB 256x256)
  • RGB 16 bit 65万颜色不带alpha。比压缩的格式使用更多的内存,但更适用于UI或不带渐变的明快的纹理。128 KB 256x256
  • RGB 24 bit 真彩色不带alpha。(192 KB 256x256)
  • Alpha 8 bit 高质量alpha通道,不带颜色。(64 KB 256x256)
  • RGBA 16 bit 低质量真彩色。默认压缩的纹理带有alpha通道(128 KB 256x256)
  • RGBA 32 bit 真彩色带alpha - 这是高质量压缩的纹理带有alpha通道。(256 KB 256x256)

IOS:

  • RGB Compressed PVRTC 4 bits
  • PVRTC 4位,压缩的RGB纹理。这是最常见的漫反射纹理格式。4位/像素(32 KB 256x256)
  • RGBA Compressed PVRTC 4 bits 压缩的RGBA纹理。这是漫反射和高光控制纹理的主要格式。4 位/像素(32 KB 256x256)
  • RGB Compressed PVRTC 2 bits压缩的RGB纹理。 低质量格式,适用于漫反射纹理。2 位/像素(16 KB 256x256)
  • RGBA Compressed PVRTC 2 bits 压缩的RGBA纹理。 低质量格式,适用于漫反射纹理和高光控制纹理。2 位/像素(16 KB 256x256)
  • RGB Compressed DXT1 压缩的RGB纹理。 在iOS不支持此格式,但为桌面项目保持向后兼容性。
  • RGBA Compressed DXT5 压缩的RGBA纹理。在iOS不支持此格式,但为桌面项目保持向后兼容性。
  • RGB 16 bit 65万颜色不带alpha。比PVRTC格式使用更多的内存,但更适用于UI或不带渐变的明快的纹理。128 KB 256x256
  • RGB 24 bit 真彩色不带alpha。(192 KB 256x256)
  • Alpha 8 bit 高质量alpha通道,不带颜色。(64 KB 256x256)
  • RGBA 16 bit 低质量真彩色。具有16级的红、绿、蓝和alpha。比PVRTC格式使用更多的内存,但如果需要精确的alpha通道,会更方便。(128 KB 256x256)
  • RGBA 32 bit 真彩色带alpha - 这是最高质量。256KB 256x256,这个是很消耗性能的。大多数情况下,PVRTC格式提供足够的质量,但有更小的文件大小。

(图片来自:喵小逗@UWA问答社区)

几种主要的压缩格式介绍:

高清晰无压缩 - RGBA32

RGBA32等同于原图了,优点是清晰、与原图一致,缺点是内存占用十分大;对于一些美术要求最好清晰度的图片,是首选。

要注意一些png图片,在硬盘中占用几KB,怎么在Unity中显示却变大?因为Unity显示的是Texture大小,是实际运行时占用内存的大小,而png却是一种压缩显示格式;可以这样理解,png类似于zip格式,是一个压缩文件,只不过在运行时会自动解压解析罢了。

中清晰中压缩 - RGBA16 + Dithering

Unity RGBA16,不抖动处理的渐变图片惨不忍睹

既然叫RGBA16,自然就是RGBA32的阉割版。
对于一些采用渐变的图片,从RGBA32转换成RGBA16,能明显的看出颜色的层叠变化。

采用Floyd Steinberg抖动处理后,除非放大,否则肉眼基本看不出区别

RGBA16的优点,内存占用是RGBA32的1/2;搭配上Dithering抖动,在原尺寸下看清晰度一模一样;

缺点,Unity原生不支持Dithering抖动,需要自己做工具对图片做处理;对于需要放大、拉伸的图片,Dithering抖动的支持不好,会有非常明显的颗粒感。

RGB16

而RGB16,是主要针对一些,不带透明通道,同时长宽又不是2的次方的图片;对于这些图片,使用RGB16可以降低一半的内存,但是效果会略逊于RGB32。

当然了,RGB16其实也是可以搭配抖动,也能提升显示效果;但同样的Dithering抖动对拉伸放大是不友好的。

低清晰高压缩 - ETC1+Alpha/PVRTC4

很多初学者都会疑惑,为什么游戏开发中经常看到一些图片,需要设置成2的次方?因为像ETC1、PVRTC4等这类在内存中无需解压、直接被GPU支持的格式,占用内存极低,而且性能效率也是最好的

但是,相对RGBA32,还是能肉眼看出质量有所下降的。

  1. ETC1

    ETC1+Alpha一般应用在Android版的UI图集中,ETC1不带透明通道,所以需要外挂一张同样是ETC1格式的Alpha通道图。方法是,在原RGBA32的原图中,提取RGB生成第一张ETC1,再提取A通道,填充另一张ETC1的R通道;游戏运行时,Shader将两张ETC1图片进行混合。

  2. PVRTC4

    PVRTC4在Unity中是直接支持的,不过要注意的细节是,它必须是二次方正方形;也就是说,长宽在二次方的同时,还必须要相等。

    在项目中,尽可能是使用ETC1和PVRTV4等GPU直接支持的图片格式,不仅内存占用低、性能也更好;当出现质量不及格时,再逐步的提升压缩格式,来满足需要。


参考:

  1. Unity运用导入器规范资源格式和设置
  2. Unity3D 图片纹理格式(作者:JumboWu)
  3. 干货:Unity游戏开发图片纹理压缩方案