今やってるお仕事で 特定の Android 端末 (ASUS MeMO Pad 8 とか) で画像が出ない という問題が発生した。
色々調べて解決策を見つけたので、それを書き殴る。
原因
結論から言うと、テクスチャの圧縮形式に問題があった。
全体最適するなら RGB Compressed ETC 4bits か RGBA Compressed DXT5 にしましょうね、ってお話です。
解説
元々ウチでは Android 用の圧縮形式として RGBA Compressed ATC 8bits とか RGB Compressed ATC 4bits とかをメインに使っていたが、一部の Android 端末は、この形式で圧縮された画像を処理できないコトが判明。
大半の Android 端末は Adreno という Qualcomm 社の GPU を積んでおり、ATC を正しく展開できるので問題ない。
が、上述の ASUS MeMO Pad 8 は調べたところ PowerVR G6430 という GPU を積んでおり、漏れなく ATC を展開できない。
※余談ではあるが、PowerVR は iOS な端末に搭載されている GPU のようで、PVRTC で圧縮してあげれば動くんだろうけど、他の Android で動かないから却下な方向ですよねー。
おまけ
毎回手動でこの辺設定するのが面倒な場合は、AssetPostprocessor で自動設定してあげるとオシャレ。
using UnityEngine;
using UnityEditor;
public class CustomAssetPostprocessor : AssetPostprocessor {
public void OnPreprocessTexture() {
TextureImporter importer = (assetImporter as TextureImporter);
// この辺の設定は、お好みで。
importer.textureType = TextureImporterType.Advanced;
importer.npotScale = TextureImporterNPOTScale.ToLarger;
importer.spriteImportMode = SpriteImportMode.None;
importer.mipmapEnabled = false;
importer.generateCubemap = TextureImporterGenerateCubemap.None;
importer.wrapMode = TextureWrapMode.Repeat;
importer.filterMode = FilterMode.Bilinear;
importer.anisoLevel = 0;
importer.alphaIsTransparency = false;
importer.linearTexture = false;
importer.compressionQuality = (int)TextureCompressionQuality.Best;
importer.maxTextureSize = 2048;
importer.textureFormat = TextureImporterFormat.RGBA32;
// ココで Platform 毎の個別設定を行う。
importer.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4, (int)TextureCompressionQuality.Normal);
importer.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC_RGB4, (int)TextureCompressionQuality.Normal);
}
}
}
なお、アルファチャンネルを含む画像の場合は、Line: 25, 26 を以下のようにすると良い。
importer.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGBA4, (int)TextureCompressionQuality.Normal);
importer.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.DXT5, (int)TextureCompressionQuality.Normal);