Version: 2020.1
言語: 日本語
シェーダーのコンパイル
Optimizing shader variants

Asynchronous shader compilation in the Unity Editor

Asynchronous shader compilation is an Editor-only feature that can speed up your workflow when you have complex Unity shaders with lots of shader variants.

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

概要

Unity shaders can contain of hundreds or thousands of shader variants. If the Editor compiled all variants when loading a Unity shader, the import process would be very slow. Instead, the Editor compiles shader variants on-demand, the first time it encounters them.

Compiling these shader variants can cause the Editor to stall for milliseconds or even seconds, depending on the graphics API and the complexity of the Unity shader. To avoid these stalls, you can use Asynchronous Shader Compilation to compile the shader variants in the background, and use placeholder Unity shaders in the meantime.

非同期シェーダーコンパイルのしくみ

非同期のシェーダーコンパイルは以下のように行われます。

  1. エディターがコンパイルされていないシェーダーバリアントに初めて遭遇すると、そのシェーダーバリアントをジョブスレッド上のコンパイルキューに追加します。エディターの右下にあるプログレスバーはコンパイルキューの状態を示しています。
  2. While the shader variant is loading, Editor renders the geometry with a placeholder Unity shader, which appears as a plain cyan color.
  3. エディターがシェーダーバリアントのコンパイルを終了すると、シェーダーバリアントを使ってジオメトリを描画します。

The feature does not have any effect on the standalone Player, because the Editor compiles all the Shader Variants needed by the Player during the build process.

Unity は、コンパイルが終了するまで、シアンのダミーシェーダーでコンパイルしているシェーダーバリアントをレンダリングします。右下のプログレスバーは、コンパイルキューの進行状況を示します。
Unity は、コンパイルが終了するまで、シアンのダミーシェーダーでコンパイルしているシェーダーバリアントをレンダリングします。右下のプログレスバーは、コンパイルキューの進行状況を示します。

例外

以下の例外があります。

  • If you draw geometry using DrawProcedural or CommandBuffer.DrawProcedural, the Editor doesn’t use a placeholder Unity shader. Instead, the Editor just skips rendering this geometry until it has compiled the shader variant.
  • Unity エディターは、Blit 操作による非同期シェーダーコンパイルを使用しません。これは、最も一般的な使用例で正しい出力を保証するためです。

プロジェクトの非同期シェーダーコンパイルを有効/無効にする

シェーダーの非同期コンパイルは、デフォルトで有効になっています。

To enbale or disable asynchronous shader compilation:

  1. Go to Edit > Project Settings.. > Editor.
  2. エディター設定の下の方の Shader Compilation で、Asynchronous Shader Compilation のチェックを入れます/外します。
Asynchronous Shader Compilation のチェックボックスは、Project Settings > Editor > Shader Compilation 以下にあります。
Asynchronous Shader Compilation のチェックボックスは、Project Settings > Editor > Shader Compilation 以下にあります。

Note: Enabling and disabling asynchronous shader compilation in this way affects only the Scene and Game views by default. If you want to use it in other scenarios, you can control this via scripts. See [Using asynchronous Shader compilation in custom Editor tools.

特定のレンダリング呼び出しのための非同期シェーダーコンパイルを有効/無効にする

You can enable or disable asynchronous shader compilation for specific rendering commands in your C# scripts. You might use this

The following instructions show you how to enable or disable the feature in an immediate scope, and a CommandBuffer scope.

即時スコープ

In an immediate scope, you can use ShaderUtil.allowAsyncCompilation;.

これは以下の手順で行えます。

  1. ShaderUtil.allowAsyncCompilation の現在の状態を変数に格納します。
  2. レンダリングコマンドを呼び出す前に、ShaderUtil.allowAsyncCompilationfalse に設定します。
  3. レンダリングコマンドを呼び出します。
  4. レンダリングコマンドを呼び出した後、ShaderUtil.allowAsyncCompilation を以前の状態に戻します。

以下は擬似コードの例です。

// Store the current state
bool oldState = ShaderUtil.allowAsyncCompilation;

// Disable async compilation
ShaderUtil.allowAsyncCompilation = false;

// Enter your rendering code that should never use the placeholder Unity shader
Graphics.DrawMesh(...);

// Restore the old state
ShaderUtil.allowAsyncCompilation = oldState;

CommandBuffer スコープ

In a CommandBuffer scope, you can use ShaderUtil.SetAsyncCompilation and ShaderUtil.RestoreAsyncCompilation.

  1. レンダリングコマンドを呼び出す直前に、ShaderUtil.SetAsyncCompilation を呼び出して false に設定します。CommandBuffer の後続のコマンドでは非同期コンパイルはできません。
  2. レンダリングコマンドを CommandBuffer に加えます。
  3. レンダリングコマンドの後、Shader.Util.RestoreAsyncCompilation を呼び出して、非同期シェーダーコンパイルの状態を復元します。

以下はその例です。


// Disable async compilation for subsequent commands
ShaderUtil.SetAsyncCompilation(cmd, false);

/// Enter your rendering commands that should never use the placeholder Unity shader
cmd.DrawMesh(...);

// Restore the old state
ShaderUtil.RestoreAsyncCompilation(cmd);

Disabling asynchronous compilation for specific Unity shaders

You can disable asynchronous shader compilation for specific Unity shaders by forcing the Editor to always compile them synchronously. This is a good option for data generating Unity shaders that are always present at the start of your rendering, and which are relatively quick to compile. You would most likely need this if you are performing advanced rendering.

To force synchronous compilation for a Unity shader, add the #pragma editor_sync_compilation directive to your Unity shader source code.

Note: If you force synchronous compilation for complex Unity shaders that encounter new shader variants in the middle of your rendering, this can stall rendering in the Editor.

非同期のシェーダーコンパイルの検出

C# の API を使って、非同期のシェーダコンパイルの状態を監視し、その状態が変化したときに操作を行うことができます。

This is most likely useful in advanced rendering; if the placeholder Unity shader pollutes your generated data, you can discard the polluted data and regenerate a new set with the correct shader variants.

調べたいマテリアルがすでにわかっている場合は、ShaderUtil.IsPassCompiled を使って、シェーダーバリアントのコンパイル状況を確認することができます。ステータスが Uncompiled から Compiled に変わると、コンパイルが完了です。

どのマテリアルを調べたいのかわからない場合や、複数のマテリアルを調べたい場合は、 ShaderUtil.anythingCompiling を使って、Unity がシェーダーバリアントを非同期にコンパイルしているかどうかを検出することができます。これが true から false に変わると、現在のすべてのコンパイルは完了です。

エディターの高度なレンダリング

Advanced rendering solutions rely on generating data once and reusing it in later frames. If the Editor uses a placeholder Unity shader during this process, it might pollute the generated data. If this happens, you can see the cyan color or other rendering artifacts in your scene, even after the shader variants have finished compiling.

これを回避するには、以下を行います。

カスタムエディターツールと非同期シェーダーコンパイル

デフォルトでは、 非同期シェーダーコンパイルはゲームビューとシーンビューで動作します。カスタム製のエディターツールで使用したい場合は、カスタムツールの C# を使って有効にできます。

そのために、特定のレンダリングコールに対して非同期シェーダーコンパイルを有効 にします。

コンパイル時のレンダリングのカスタマイズ

You can make your custom tools draw something other than the placeholder Unity shader for each material. This way, you can avoid rendering in plain cyan, and instead draw something else while the shader variant compiles.

特定のシェーダーバリアントがコンパイルされたかどうかを確認するには、非同期シェーダーコンパイルの検出 を参照してください。

手動でコンパイルを開始するには、ShaderUtil.CompilePass を使います。このようにして、シアンのプレースホルダーでのレンダリングを避け、代わりにシェーダバリアントのコンパイル中に他のものを描画することができます。

シェーダーのコンパイル
Optimizing shader variants