微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Unity导入图片尺寸大小和压缩格式的问题

一、前言

虽然 Unity支持许多常见的图像格式作为导入纹理的源文件(例如 JPG、PNG、PSD 和 TGA),但在3D图形硬件(如显卡或移动设备)的实时渲染过程中不会使用这些格式。3D图形硬件要求纹理以专门格式进行压缩,这些格式针对快速纹理采样进行了优化。各种不同的平台和设备都有自己不同的专有格式。

认情况下,Unity Editor自动将纹理转换为最合适的格式,以匹配我们选择的构建目标(如Android、iOS)。只有转换后的纹理才会包含在我们的构建中;源资源文件保留为原始格式,位于项目的Assets文件夹中。

我们可以对纹理选择不同的压缩格式(例如,如果使用纹理作为遮罩,只有一个通道,则可以选择使用 BC4格式来节省空间,同时保持质量)。

二、图片导入到Unity中尺寸会变成2的N次方

如果你将一张图片导入到Unity中,你会发现认被转成了2的N次方大小。
比如下面这张图原图尺寸是640x1138

在这里插入图片描述


导入到Unity中,看到尺寸变成了512x1024

在这里插入图片描述


这是因为图片的纹理像素在Unity中需要遵循2的N次方,由图形学决定。

我们也可以设置不转换,设置Non-Power of 2None,此时图片就会保持原尺寸了。
不过不推荐这样做,因为最终图片加载到显存中,也会进行转换为2的N次方,而这个转换比较耗时,所以可能会导致卡顿。

在这里插入图片描述

三、为什么非要是2的N次方呢

那么,为什么非要是2的N次方呢?
打个不是很恰当的比方,现在我们建了一所小学,每间教室最多安排32个座位。
现在学校招生,如果招的学生数量不是32的整数倍,那么就会浪费教室。比如招了33个学生,那么多出来的1个学生只能安排到另外的一间教室,导致老师上完课还得再跑另外这间教室单独给这个学生再上一次课,这也对资源和时间的一种浪费。
如果学生数量32的整数倍,那就不会浪费资源和时间了。

四、常用的压缩格式

纹理压缩格式 描述 大小(256x256 像素纹理) 平台支持
RGBA 32 位 真实色彩,有 Alpha。这是具有 Alpha 通道的纹理的最高质量压缩格式。 256KB(32 位/像素) 所有平台。
RGBA 16 位 低质量真实色彩。这是具有 Alpha 通道的纹理的认压缩格式。 128KB(16 位/像素) 所有平台。
Alpha 8 高质量 Alpha 通道,但没有任何颜色。 64KB(8 位/像素) 所有平台。
RGB 16 位 65,000 种颜色,没有 Alpha。使用比压缩格式更多的内存,但可能更适合没有渐变的 UI 或清晰纹理。 128KB(16 位/像素) 所有平台。
RGBA Compressed PVRTC 4 位 压缩 RGB 纹理。高质量纹理,尤其是颜色数据,但可能需要很长时间压缩。 32KB(4 位/像素) Android (PowerVR)、iOS、tvOS。
RGB Compressed PVRTC 4 位 压缩 RGB 纹理。高质量纹理,尤其是颜色数据,但可能需要很长时间压缩。 32KB(4 位/像素) Android (PowerVR)、iOS、tvOS。
RGBA Compressed PVRTC 2 位 高压缩 RGBA 纹理。质量低,但较小,因此提高了性能 16KB(2 位/像素) Android (PowerVR)、iOS、tvOS。
RGB Compressed PVRTC 2 位 高压缩 RGB 纹理。质量低,但较小,因此提高了性能 16KB(2 位/像素) Android (PowerVR)、iOS、tvOS。
RGB Compressed ETC 压缩 RGB 纹理。这是适用于 Android 项目的不带 Alpha 通道的纹理的认纹理压缩格式。 32KB(4 位/像素) Android、iOS、tvOS。注意:ETC1 受到所有 OpenGL ES 2.0 GPU 的支持。它不支持 Alpha。
RGB Compressed ETC2 压缩 RGB 纹理。 32KB(4 位/像素) Android (OpenGL ES 3.0) 。注意:在不支持 ETC2 的 Android 平台上,纹理在运行时解压缩为 Build Settings 中的 ETC2 fallback 指定的格式。

五、监听资源导入事件,自动化处理压缩格式

我们有时候需要在导入资源的时候做一些自动化处理,比如导入图片自动设置压缩格式等,此时我们就需要使用AssetPostprocessor这个类了。
示例代码如下:代码放入Editor文件夹下

using UnityEngine;
using System.Collections;
using UnityEditor;
public class MyEditor : AssetPostprocessor {
 
    //模型导入之前调用
    public void OnPreprocessModel()
    {
        Debug.Log ("OnPreprocessModel="+this.assetPath);
    }
 
    //模型导入之前调用
    public void OnPostprocessModel(GameObject go)
    {
        Debug.Log ("OnPostprocessModel="+go.name);
    }
 
    //纹理导入之前调用,针对导入的纹理进行设置
    public void OnPreprocesstexture()
    {
        Debug.Log ("OnPreProcesstexture="+this.assetPath);
        TextureImporter impor = this.assetImporter as TextureImporter;
        impor.textureFormat = TextureImporterFormat.ARGB32;
        impor.maxTextureSize = 512;
        impor.textureType = TextureImporterType.Advanced;
        impor.mipmapEnabled = false;
 
    }
 
    public void OnPostprocesstexture(Texture2D tex)
    {
        Debug.Log ("OnPostProcesstexture="+this.assetPath);
    }
 
 
    public void OnPostprocessAudio(AudioClip clip)
    {
    
    }
 
    public void OnPreprocessAudio()
    {
        AudioImporter audio = this.assetImporter as AudioImporter;
        audio.format = AudioImporterFormat.Compressed;
    }
 
    //所有的资源的导入,删除,移动,都会调用方法,注意,这个方法是static的
    public static void OnPostprocessAllAssets(string[]importedAsset,string[] deletedAssets,string[] movedAssets,string[]movedFromAssetPaths)
    {
        Debug.Log ("OnPostprocessAllAssets");
        foreach (string str in importedAsset) {
            Debug.Log("importedAsset = "+str);
        }
        foreach (string str in deletedAssets) {
            Debug.Log("deletedAssets = "+str);
        }
        foreach (string str in movedAssets) {
            Debug.Log("movedAssets = "+str);
        }
        foreach (string str in movedFromAssetPaths) {
            Debug.Log("movedFromAssetPaths = "+str);
        }
    }
 
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐