【Unity6】Mipmap Streamingを使ったメモリ節約
概要
Mipmap Streaming(ミップマップテクスチャストリーミング)を使用することで、テクスチャのメモリ使用量を節約することができます。
今回の記事では、Mipmap Streamingを触ってみます。
環境
Unityバージョン : Unity6000.0.31f1
端末 : iPhoneX
実験1. テクスチャ1000枚をメモリにのせる
Mipmap Streamingの効果を見るため、Mipmap Streamingを使用しない場合のメモリを計測してみます。
- 球体を1000個シーンに配置する
- それぞれの球体に解像度1024x1024のテクスチャをアサインする (1000枚のテクスチャがメモリに乗る)
使用したテクスチャ
Hoge_1からHoge_1000までの解像度1024x1024のテクスチャ1000枚を用意しています。
使用したC#スクリプト
using UnityEngine;
public class Benchmark : MonoBehaviour
{
private const int N_X = 17; // 横に並べる個数
private const int N = 1000; // トータルの個数
void Start()
{
var spherePrefab = Resources.Load<GameObject>("Prefabs/Sphere");
for (int i = 0; i < N; i++)
{
var sphere = GameObject.Instantiate(spherePrefab);
int x = i % N_X - (N_X / 2);
int z = i / N_X;
sphere.transform.position = new Vector3(x, 0, z);
var renderer = sphere.GetComponent<MeshRenderer>();
var material = renderer.material;
var texture = Resources.Load<Texture2D>($"Textures/Hoge_{i+1}"); // テクスチャ読み込み
material.mainTexture = texture;
}
}
}
結果 : 0.58 GB
テクスチャサイズの合計値は 0.58GB となりました。 (iPhoneXにて計測しています)
テクスチャ1枚あたり0.6MBほどのメモリ消費です
実験2. Mipmap Streaming を有効化する
Mipmap Streamingを有効化すると、
メモリ上にロードするMipmapを削減し、テクスチャサイズの合計値がMemory Budgetで指定したサイズに収まるようになります。
Memory Budgetのサイズが小さすぎると、収まらなくなることがあります (記事の後半で触れます)
今回の実験では、Memory Budget はデフォルト値 512 MB としました。
結果 : 508.3MB
テクスチャサイズの合計値は 508.3MBとなりました。
メモリ上のテクスチャサイズが Memory Budget を超えていないことが確認できます。
テクスチャは基本的にMip0でロードしてますが、
遠景オブジェクトのテクスチャは Mip2がロードされています。
実験3. Memory Budgetを下げる
次に、Memory Budget をさらに減らした時のメモリを見てみます。
Memory Budget : 128MB
Memory Budgetを128 MBに設定してみます。
結果 : 88.0 MB
メモリ上のテクスチャサイズは88.0 MBとなりました。
Memory Budget : 16 MB
Memory Budgetを16 MBに設定してみます。
Max Level Reduciton はデフォルト値 2 です
結果 : 38.7 MB
メモリ上のテクスチャサイズは 38.7MBとなりました。
Memory Budget を超えるサイズになっていますが、これは Max Level Reduciton = 2 であることが理由です。
Max Level Reductionについて
Mipmap Streamingでは、ロードするMipのレベルを上げてメモリを減らしますが、
Max Level Reductionを超えるレベルのMipをメモリから破棄できません。
Max Level Reduction = 2 の場合、 Mip 1まで破棄できる(Mip 2までロードできる)ため、
テクスチャサイズは 1/16 まで減らすことができます。
Max Level Reduction = 3 の場合、 Mip 2まで破棄できる(Mip 3までロードできる)ため、
テクスチャサイズは 1/64 まで減らすことができます。
今回、Max Level Reduciton = 2 と設定しているため、Mip2までロードできます。
すべてのテクスチャがMipmap2がロードされている
実験4 : Max Level Reduction を増やす
Max Level Reductionを増やすと、より高いレベルのMipを破棄できるため、メモリサイズをさらに減らせるようになります。
以下のようにストリーミングを設定した時のメモリを見てみます。
- Memory Budget : 16 MB
- Max Level Reduction : 3
結果 : 12.3 MB
メモリを計測してみると 12.3MB となりました
遠景のテクスチャは Mip3がロードされていることが確認できます。 (近景のテクスチャはMip0,1,2が使用されます)
まとめ
今回はMipmap Streamingのふるまいを確認できました。
- Memory Budgetに収まるレベルまで、Mipを削減してくれる
- Max Level Reductionを増やすと、より高いレベルのMipを削減できる (メモリサイズをより減らせるようになる)
その他 : QualitySettings.globalTextureMipmapLimit
QualitySettings.globalTextureMipmapLimitは、Max Level Reductionより優先されます。
QualitySettings.globalTextureMipmapLimitで設定したMipより低いレベルのMipは読み込まれなくなります。
例えば、QualitySettings.globalTextureMipmapLimit = 4 で Max Level Reduction = 2の場合はMip4がロードされます
Discussion