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

文章目录

一、前言

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

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

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

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

如果你将一张图片导入到Unity中,你会发现默认被转成了2的N次方大小。
比如下面这张图原图尺寸是640x1138
《Unity导入图片尺寸大小和压缩格式的问题》
导入到Unity中,看到尺寸变成了512x1024
《Unity导入图片尺寸大小和压缩格式的问题》
这是因为图片的纹理像素在Unity中需要遵循2的N次方,由图形学决定。

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

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

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

四、常用的压缩格式

纹理压缩格式描述大小(256×256 像素纹理)平台支持
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);
        }
    }
 
}
    原文作者:林新发
    原文地址: https://blog.csdn.net/linxinfa/article/details/108827197
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞