こんにちは!情熱開発部プログラマの倉平です!
暑い日が続くので毎日アイスを食べるのが止まりません。
食感が好きなのでガリガリ君を良く食べるのですが、暑すぎて持ち帰っている間に溶けてしまいます…。
溶けにくいあずきバーに乗り換えるべきかとコンビニで悩むんですが結局ガリガリ君を買う、そして溶ける。学習力が無い私です。
そんな夏の悩みはさておき今回はUnity6で使えるShaderWarmupについて紹介します。
※本記事ではUnityバージョン 6000.0.53f1を使用しています。
UnityのShaderWarmupについて
ShaderVariantColectionを使用したWarmupが一般的だと思います。
※過去記事にて紹介しています。
【Unity】ShaderのWarmupについて
ShaderVariantColectionでのWarmupは以下の問題もあります。
・Warmup処理が非同期処理なので終了するまで画面が固まる
・DX11とOpenGLはサポートされているが、DX12、Vulkan、Metalではサポートされていない。
Unity6では上記の問題を解決できる別のShaderWarmupがあります。
GraphicsStateCollectionについて
GraphicsStateCollectionはUnity6で追加されたAPIです。
ShaderWarmupに必要な情報の記録、それらを用いて非同期でのShaderWarmupを実行が行えます。
本件ではこのAPIを使用してShaderWarmupを実装する方法を紹介します。
※このAPIは実験的に追加された機能です(2025/07/23時点)。
将来的に変更が掛かるか削除される可能性があるのでご注意ください。
また、こちらのAPIはDX12、Vulkan、Metalのみサポートされています。
DX11とOpenGLでは使用しても動作が行われません。
事前情報を準備
GraphicsStateCollectionはShaderWarmupを行うのにShaderVariantと関連する描画情報を記録しておく必要があります。
また、DX12、Vulkan、Metalと環境ごとに記録される情報が異なります。
開発中のゲームが動作する環境に合わせて使用する情報を用意してください。
GraphicsStateCollectionの以下の関数を使用して記録と保存が行えます。
保存するファイルの拡張子は「.graphicsstate」を使用してください。
記録終了
bool EndTrace()
記録した情報を保存
bool SaveToFile(string filePath)
実装例
using UnityEngine;
using UnityEngine.Experimental.Rendering;
public class SampleTraceGraphicsStateCollection : MonoBehaviour
{
pritvate const string FileExtensionName = ".graphicsstate";
[SerializeField]
private string savePath;
[SerializeField]
private string saveFileName;
private GraphicsStateCollection graphicsStateCollection = null;;
/// <summary>
/// 記録開始
/// </summary>
public void BeginTrace()
{
if (graphicsStateCollection == null) graphicsStateCollection = new GraphicsStateCollection();
graphicsStateCollection.BeginTrace();
}
/// <summary>
/// 記録終了
/// </summary>
public void EndTrace()
{
if (graphicsStateCollection == null) return;
graphicsStateCollection.EndTrace();
}
/// <summary>
/// 記録情報を保存
/// </summary>
public void SaveToFile()
{
if (graphicsStateCollection == null) return;
graphicsStateCollection.SaveToFile(savePath + saveFileName + FileExtensionName);
}
}
記録を取る端末でゲームを起動して任意のタイミングでBeginTrace()を実行。
終了時にEndTrace()、SaveToFile()を実行してデータが取れます。
BeginTrace()実行中に描画された情報が収集されるので
実装されているあらゆるシチュエーションをカバーするのが望ましいです。
★注意★
DevelopmentBuildで作成したアプリじゃないと情報収集されないので注意してください。
作成したWindowアプリで保存したファイルをUnityEditorで見てみる

赤線で引いた箇所を見るとShaderVarinatも描画状態も保存されてますね。
カウント数しか表示していないのは少し不便です。
テキストエディタで直接中身は見れます。

GraphicsStateCollectionの以下の関数を使用すると各情報が取れるので
こちらを使用した確認用表示処理を用意するのも良いかもしれません。
ShaderVariantリストを取得
public void GetVariants(List results);
ShaderVariantに紐づいた描画状態リストを取得
public void GetGraphicsStatesForVariant(Experimental.Rendering.GraphicsStateCollection.ShaderVariant variant, List results);
ShaderWarmupを実装
GraphicsStateCollectionの以下の関数でWarmupが実行できます。
ShaderVariantCollectionでのWarmupと違いJobHandleを使用した非同期処理になっています。
Warmupを実行
Unity.Jobs.JobHandle WarmUp(Unity.Jobs.JobHandle dependency)
Varant数を指定してWarmupを実行
Unity.Jobs.JobHandle WarmUpProgressively(int count, Unity.Jobs.JobHandle dependency)
WarmUpProgressivelyはWarmupを分割する必要があまりないと思うので
基本的にはWarmUp()だけ使えば良いと思います。
終了判定は返ってきたJobHandleを使用してください。
実装例
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using Unity.Jobs;
public class SampleShaderWarmup : MonoBehaviour
{
[SerializeField]
private GraphicsStateCollection graphicsStateCollection = null;
private JobHandle jobHandleWarmup = default;
/// <summary>
/// Warmup実行
/// </summary>
public void Warmup()
{
if (graphicsStateCollection == null) return;
jobHandleWarmup = graphicsStateCollection.WarmUp();
jobHandleWarmup.Complete();
}
/// <summary>
/// Warmupが終了したか
/// </summary>
public bool IsEndWarmup()
{
return jobHandleWarmup.IsCompleted;
}
}
graphicsStateCollectionで設定するファイルは「事前情報を準備」で作成した「.graphicsstate」ファイルを設定したください。
今回の実装例だとInspector上で直接設定しています。

マルチ環境で動作するゲームの場合は環境ごとに「.graphicsstate」ファイルを変える必要があるので注意してください。
まとめ
GraphicsStateCollectionを使用したShaderWarmupを紹介しました。
以下のデメリットもあるので実際に組み込むかは要検討です。
・環境ごとに「.graphicsstate」ファイルを分けないといけない
・「.graphicsstate」ファイルの作成をUnityEditor上で完結出来ない
・BeginTrace()を実行中に計測した情報しか保存しないので漏れが出る可能性がある
・現状のサポート環境がDX12、Vulkan、Metalのみ
・実験的に追加された機能なので仕様が変わるか削除される可能性がある
ご自身の制作環境に合わせて最適なShaderWarmupを実装してみてください。
参考サイト
今回の記事を書くにあたり、以下のサイトを参考にさせていただきました。
Prevent shader compilation stutters with PSO Tracing in Unity 6 – Unity Engine – Unity Discussions
GraphicsStateCollectionについて
Unity 6シェーダーWarmupガイド
【免責事項】
本サイトでの情報を利用することによる損害等に対し、
株式会社ロジカルビートは一切の責任を負いません。