Version: 2023.1
言語: 日本語
ミップマップの基本
ミップマップストリーミングシステム API

ミップマップストリーミングシステム

ミップマップストリーミング (ミップマップストリーミング) システムを使うと、Unity による ミップマップ のロードの方法を制御できます。

このページには以下の情報が含まれています。

このシステムの機能を拡張するための API の使用については、ミップマップストリーミングシステム API を参照してください。

概要

このシステムは、デフォルトですべてのミップレベルをロードする代わりに、現在のカメラ位置のレンダリングに必要なミップレベルのみをロードするように強制します。これは、大量の GPU メモリを節約するために、少量の CPU リソースを犠牲にするものです。

アプリケーション内のすべてのテクスチャに対してメモリの総量制限を設定することができ、システムはミップレベルを自動的に削減して、この制限内に収まるようにします。

Unity の Viking Village デモプロジェクトでは、ミップマップストリーミングシステムはカメラの場所に応じて、テクスチャメモリの 25 - 30% を節約します。

はじめに

ミップマップストリーミングの有効化

ミップマップストリーミングを有効にするには、Unity の Quality Settings (Edit > Project Settings > Quality) を開き、Texture Streaming チェックボックスを有効にします。

この設定を有効にすると、Quality Settings ウィンドウにミップマップストリーミングシステム固有の設定項目が表示されます。各設定の詳細については、Quality Settings のドキュメントを参照してください。

デフォルトでは、これにより、プロジェクト内のすべてのカメラでミップマップストリーミングが有効になります。

ミップマップストリーミングシステムでテクスチャを動作させる

これで、個々のテクスチャにミップマップストリーミングを設定することができます。テクスチャアセットを選択し、Inspector ウィンドウに移動して、テクスチャインポートの設定を表示します。Advanced 設定を開き、Mip Streaming チェックボックスをオンにします。

Android 用に開発する場合は、Build Settings (ビルド設定) を開き、Compression MethodLZ4LZ4HC に設定する必要があります。 Unity では、ミップマップストリーミングシステムが依存する 非同期テクスチャのロード にそれらの圧縮方法の 1 つが必要です。

Unity は、メモリバジェットを守りつつ、可能な限り高い解像度でミップをロードします。テクスチャの優先順位は、テクスチャインポート設定の Mip Streaming__ > Priority の設定で設定することができます。

Unity は、この設定を使用して以下を決定します。

  • リソースを割り当てる際に、どのテクスチャを優先するか。
  • メモリバジェットに収まるミップレベルを選択する際のミップバイアス値。例えば、優先度 2 の場合、ミップマップストリーミングシステムは、優先度 0 のテクスチャより 2 ミップレベル高いミップマップを使用しようとします。

正の数は優先度を高くします。有効な値は –128 から 127 までです。

ストリーミングライトマップ

ミップマップストリーミングシステムを使用して、ライトマップのミップレベルをストリーミングすることができます。

ライトマップアセットのミップマップストリーミング設定は、他のテクスチャと同じように編集できますが、Unity がライトマップを再生成するときにデフォルト値にリセットされます。これを解決するには、ライトマップを生成するときにこれらの値を適用するように Unity に指示します。Player Settings (Edit > Project Settings > Player) には、生成されたライトマップのストリーミングと優先度を設定する 2 つのコントロール Lightmap Streaming EnabledStreaming Priority があります。

ミップマップストリーミングを有効にし優先順位を設定することは、ライトマップに対して 通常のテクスチャ と同じように動作します。

ミップマップストリーミングの設定

Unity エディターでデフォルトの設定を行い、必要に応じて ミップマップストリーミング API を使用してこれらの設定をオーバーライドすることができます。

メモリバジェットの設定

Memory Budget プロパティは、Unity がシーンのテクスチャに使用するメモリの最大量を決定します。メモリバジェットが小さすぎると、Unityはシーン内のテクスチャの解像度を下げてしまいます。これにより、テクスチャがポップしたり、ロードが遅くなったりします。しかし、他のリソースのためのメモリを確保するために、メモリバジェットはできるだけ小さくすべきです。

Quality Settings ウィンドウの Texture Streaming > Memory Budget プロパティで、メモリバジェットを設定します。

メモリバジェットがいっぱいになると、Unity は使用していないミップマップを破棄して、使用する必要があるミップマップのためのスペースを確保します。未使用のミップマップをどれだけ捨てるかは、Max Level Reduction で制御することができます。

この値は、ミップマップストリーミング システムが起動時に最初にロードするミップマップレベルでもあります。例えば、この値を 2 に設定すると、Unity は最初のロード時に最も高い 2 つのミップマップをスキップします。

この値は、Quality Settings ウィンドウの Texture Streaming > Max Level Reduction プロパティで設定します。

ノート: Unity はメモリバジェットよりも Max Level Reduction の値を優先します。例え、テクスチャのメモリがバジェットを超えることになっても、Max Level Reduction の値を超えるミップマップを破棄することはありません。

メモリバジェットには、ミップマップストリーミングを使用しないテクスチャが含まれます。例えば、予算が100MB で、ミップマップストリーミングを使用しないテクスチャが 90MB ある場合、Unity は残りの10 MB にすべてのストリーミングミップマップを収めようとします。それができない場合、低い解像度でロードます。Unity は、例え、メモリバジェットをオーバーしても、ミップマップストリーミングを使用しないテクスチャを常に完全な解像度でロードします。

適切なメモリバジェットは、以下の方法で求められます。

  1. プロジェクトの実行中に Texture.destatedTextureMemory の値を確認します。
  2. Memory Budget の値を Texture.destablishedTextureMemory の値よりもわずかに高く設定します。

これにより、シーンの中で最もリソースを必要とする領域に利用できる十分なテクスチャメモリが確保され、テクスチャが低解像度に落ちるのを防ぐことができます。メモリに余裕がある場合は、メモリバジェットを大きく設定することで、シーンで表示されていないテクスチャデータをストリーミングキャッシュに残すことができます。

カメラの設定

デフォルトで、ミップマップストリーミングシステムを有効にすると、Unity はすべてのカメラに対してこれを有効にします。必要に応じてこの設定を無効にすることができます。

Unity がすべてのカメラのミップマップストリーミングを有効にするかどうかは、Quality Settings ウィンドウの Texture Streaming > Add All Cameras プロパティで設定します。

特定のカメラを除外したい場合は、そのカメラに Streaming Controller コンポーネントを加えてから、無効にします。

Add All Cameras を無効にすると、カメラ毎のミップマップストリーミングを有効にする必要があります。これを行うには、Camera コンポーネント同様に、ゲームオブジェクトに Streaming Controller コンポーネントを加えます。

また、このコンポーネントでは、カメラごとにミップバイアスの設定を調整することができます。

Streaming Controller コンポーネント
Streaming Controller コンポーネント

エディターストリーミングの設定

Edit > Project Settings > Editor にあるストリーミング設定
Edit > Project Settings > Editor にあるストリーミング設定

エディターの Mipmap Streaming (テクスチャストリーミングとも呼ばれます) はデフォルトで有効ですが、品質設定Texture Streaming を有効にし、テクスチャアセットのインポート設定 の 1 つ以上で Mipmap Streaming を有効にした場合にのみ有効になります。

Unity がエディターで再生モードと編集モードの両方で Mipmap Streaming を使用するかどうかは、独立してコントロールできます。これを行うには、Project Settings > Editor > Streaming Settings に移動します。

エディターで片方のモードで Mipmap Streaming を有効にし、もう片方のモードで Mipmap Streaming を有効にしない場合は、プレイモードへの切り替えと終了に若干時間がかかります。両方のモードで Mipmap Streaming を有効にすると、Unity がミップマップデータをアンロードしてリロードすることがなくなり、Play モードへの切り替えと終了のスピードが上がります。

“Load texture data on demand (テクスチャデータをオンデマンドでロードする)” 設定は、ミップマップストリーミングが有効になっているテクスチャに対して、エディターでさらなる最適化を可能にします。これにより、

  • テクスチャデータをディスクからメモリに非同期にロードします
  • 現在のカメラビューで必要なミップマップレベルのみをロードします
  • 現在の品質設定のテクスチャストリーミングメモリバジェットの範囲内で動作しようとします

これらの最適化により、いくつかのストールが回避され、ローディングがわずかに速くなり、CPU メモリの使用量が削減されます。ただし、この設定により、高解像度のバージョンがロードされる間、ミップマップされたテクスチャが一時的に本来の解像度よりも低い解像度で表示される場合があります。この機能は CPU にいくらかのオーバーヘッドを発生させます。そのため、テクスチャがすべて一度にメモリに収まるか、ストリームするように設定したテクスチャがない場合は、この設定を無効のままにしておくとよいでしょう。

ミップマップストリーミングのデバッグ

Unity にはビルトインのミップマップストリーミングデバッグビューモードがあります。それにアクセスするには、シーンビューの描画モードのドロップダウン をクリックし、Texture Streaming を選択します。このビューモードでは、ミップマップストリーミングシステム内でのゲームオブジェクトの状態に応じて、ゲームオブジェクトに以下の色を設定します。

  • Green - ミップマップストリーミングシステムによってミップマップが減少したテクスチャ。
  • Red - ミップマップストリーミングシステムにすべてのミップマップをロードするのに十分なリソースがないため、ミップマップがほどんどないテクスチャ。
  • Blue - ストリーミングに設定されていないテクスチャ、またはミップレベルを計算するレンダラーがない場合。

また、デバッグ API を使って、独自のカスタムデバッグツールやビジュアライゼーションを作成することもできます。

重要: メインテクスチャが MainTexture 属性を使用して設定されている場合は、テクスチャストリーミング デバッグビューモード またはカスタムデバッグツールを使用すると、ゲームビューに表示されません。

必要なミップレベルの算出方法

ミップマップストリーミングを使用するテクスチャの場合、Unity は以下のいずれかの方法で正しいミップレベルを計算します。

  • Unity のレンダラーコンポーネントが使用するマテリアルにテクスチャを割り当てる場合、Unity は自動的にミップレベルを計算します。
  • Texture2D.requestMipmapLevel を使って手動でミップレベルをリクエストします。

これを行わないと、Unity は正しいミップレベルを計算できず、低品質のミップを使用してテクスチャをロードします。このため、ぼやけた印象になることがあります。

ノート: 以下のシステムは標準の Renderer コンポーネントを使用しません。つまり、これらのシステムで要求されるミップを手動で設定する必要があります。

  • デカールプロジェクターテクスチャ
  • リフレクションプローブテクスチャ。解像度の低いミップは、粗さ (roughness) のルックアップテーブルになります。そのため、Unity が低いミップマップレベルを使用すると誤った粗さでマテリアルをレンダリングしてしまいます。
  • Mesh.uv (UV0 とも呼ばれる) 以外のチャンネルで UV テクスチャ座標を使用するシェーダー、またはシェーダーでテクスチャ座標を変更するシェーダー。唯一の例外は、スケールとトランスレーションの変更 (下記参照)。

制限

  • Unity はTerrain (地形) テクスチャ のミップマップストリーミングをサポートしていません。これは、Unity がテクスチャをタイル化してブレンドするために、Terrain (地形) テクスチャが常にフル解像度で利用可能である必要があるためです。
  • Renderer コンポーネントがアクティブな場合、そのメッシュは、望ましいミップレベルを計算するために有効な UV 分布メトリクスを必要とします。Unity はメッシュのインポート処理の一部として、自動的に分布メトリクスを計算します。

    コードからメッシュを作成する場合、Unity は分配メトリクスを自動的に計算しないため、間違ったミップレベルがロードされます。UV 配分メトリクスの計算を手動でトリガーするには、Mesh.RecalculateUVDistributionMetrics を使用します。
  • Unity がストリーム化されたテクスチャを API (Graphics.DrawMeshNow など) で直接レンダリングする場合、システムにはミップレベルを計算するためのレンダラー境界や他の情報がありません。つまり、テクスチャのミップレベルを手動で設定するか、このテクスチャのミップマップストリーミングを無効にする必要があります。Unity がロードするミップレベルを手動で設定する方法について詳細は、Texture2D.requestedMipmapLevel を参照してください。
  • Unity がテクスチャのミップレベルを計算する場合、シェーダーでフラグが立てられたテクスチャと同じ名前の _ST 値でそのテクスチャの scale と translation を探します。例えば、テクスチャを _ MainTex を使用してシェーダーで参照する場合、Unity は _ MainTex_ST を探します。
ミップマップの基本
ミップマップストリーミングシステム API