You can enable or disable shader keywords. When you enable or disable a shader keyword, Unity renders the appropriate shader variant.
このページには以下の情報が含まれています。
Unity は、C# でシェーダーキーワードを表すにあたって、ローカルシェーダーキーワード および グローバルシェーダーキーワード という概念を使用します。
ローカルシェーダーキーワードは、シェーダーソースファイル内で宣言する全てのキーワードによって構成されます。ローカルシェーダーキーワードは、個々のシェーダーまたはコンピュートシェーダーに影響を与えます。ローカルキーワードは、ローカルスコープかグローバルスコープを持つことができ、これによって、グローバルシェーダーキーワードでオーバーライド可能かどうかが変わります。
グローバルシェーダーキーワードは、ローカルシェーダーキーワードのオーバーライドとして機能します。これらはシェーダーソースファイルでは宣言されず、C# コードにのみ存在します。グローバルシェーダーキーワードは、同時に複数のシェーダーおよびコンピュートシェーダーに影響を与えることができます。
シェーダーソースファイル内でシェーダーキーワードを宣言する場合、Unity はこれを C# で LocalKeyword 構造体で表現します。これを ローカルシェーダーキーワード と呼びます。
LocalKeyword
の isOverridable プロパティは、そのキーワードがソースファイル内でグローバルスコープとローカルスコープのどちらで宣言されたかを示します。キーワードがグローバルスコープで宣言され、したがって同名のグローバルシェーダーキーワードでオーバーライド可能な場合、これは true になります。キーワードがローカルスコープで宣言され、したがって同名のグローバルシェーダーキーワードでオーバーライドできない場合は、false になります。
Unity は、シェーダーやコンピュートシェーダーに影響を与える全てのローカルシェーダーキーワードを LocalKeywordSpace 構造体に保存します。グラフィックスシェーダーの場合は、Shader.keywordSpace でこれにアクセスできます。コンピュートシェーダーの場合は、ComputeShader-keywordSpace でこれにアクセスできます。
Unity は、ソースファイル内で宣言したローカルシェーダーキーワードに加え、それとは別の グローバルシェーダーキーワード のリストを管理します。グローバルシェーダーキーワードはシェーダーソースファイル内で宣言するものではなく、C# で扱うローカルシェーダーキーワードのランタイムオーバーライドです。グローバルシェーダーキーワードは、同時に複数のシェーダーおよびコンピュートシェーダーに影響を与えることができます。
Unity はグローバルシェーダーキーワードを GlobalKeyword 構造体で表します。
グローバルシェーダーキーワードを設定すると、同じシェーダーキーワードを多数のマテリアルやコンピュートシェーダーに対して有効化または無効化する必要がある場合に便利なことがあります。しかしこれは、以下のような不都合をもたらす可能性があります。
GlobalKeyword
を作成すると、Unity は、この時点でロードされている全てのシェーダーおよびコンピュートシェーダーに関して、グローバルキーワード空間とローカルキーワード空間の間の内部マッピングを更新します。この操作は CPU に高い負荷をかける場合があります。この操作の影響を軽減するには、できるだけ、アプリケーションの開始後すぐに (アプリケーションのロード中に) 全てのグローバルキーワードを作成してください。同じ名前を持つグローバルキーワードとローカルシェーダーキーワードの状態が異なる場合、Unity は、LocalKeyword
の isOverridable
プロパティを使用して、個々のマテリアルまたはコンピュートシェーダーに対してそのキーワードが有効であるか無効であるか判断します。isOverridable
は、キーワードがグローバルスコープで宣言されていれば true、 ローカルスコープで宣言されていれば false となります。
isOverridable
が true
の場合: 同じ名前のグローバルキーワードが存在し、それが有効になっている場合、Unity は、グローバルキーワードの状態を使用します。それ以外の場合は、ローカルキーワードの状態を使用します。isOverridable
が false
の場合: Unity は常にローカルキーワードの状態を使用します。したがって、個々のマテリアルやコンピュートシェーダーに関してシェーダーキーワードが有効か無効か把握するには、isOverridable
プロパティの状態と、グローバルキーワードやローカルキーワードの状態を調査する必要があります。
以下の例は、特定のマテリアルについて、Unity がキーワードを有効と見なすか無効と見なすか確認する方法を示しています。
using UnityEngine;
using UnityEngine.Rendering;
public class KeywordExample : MonoBehaviour
{
public Material material;
void Start()
{
CheckShaderKeywordState();
}
void CheckShaderKeywordState()
{
// Get the instance of the Shader class that the material uses
var shader = material.shader;
// Get all the local keywords that affect the Shader
var keywordSpace = shader.keywordSpace;
// Iterate over the local keywords
foreach (var localKeyword in keywordSpace.keywords)
{
// If the local keyword is overridable (i.e., it was declared with a global scope),
// and a global keyword with the same name exists and is enabled,
// then Unity uses the global keyword state
if (localKeyword.isOverridable && Shader.IsKeywordEnabled(localKeyword.name))
{
Debug.Log("Local keyword with name of " + localKeyword.name + " is overridden by a global keyword, and is enabled");
}
// Otherwise, Unity uses the local keyword state
else
{
var state = material.IsKeywordEnabled(localKeyword) ? "enabled" : "disabled";
Debug.Log("Local keyword with name of " + localKeyword.name + " is " + state);
}
}
}
}
グラフィックスシェーダーのローカルパスワードが有効になっているかどうか確認するには、Material.IsKeywordEnabled か Material.EnableKeyword を使用してください。コンピュートシェーダーには、ComputeShader.IsKeywordEnabled か ComputeShader.EnableKeyword を使用してください。
グローバルキーワードが有効になっているか確認するには、Shader.IsKeywordEnabled、Shader.EnableKeyword、または ComputeShader.enabledKeywords を使用してください。
グラフィックスシェーダーのローカルシェーダーキーワードを有効化または無効化するには、Material.SetKeyword、Material.EnableKeyword、または Material.DisableKeyword を使用してください。コンピュートシェーダーには、ComputeShader.SetKeyword、ComputeShader.EnableKeyword、または ComputeShader.DisableKeyword を使用してください。
グローバルシェーダーキーワードを有効化または無効化するには、Shader.EnableKeyword か Shader.DisableKeyword を使用してください。
コマンドバッファでグローバルキーワードを有効化または無効化するには、CommandBuffer.EnableKeyword か CommandBuffer.DisableKeyword を使用してください。
ノート: シェーダーバリアントを扱うキーワードを有効化または無効化すると、Unity は別のシェーダーバリアントを使用します。ランタイムにシェーダーバリアントを変更すると、パフォーマンスに影響を与える可能性があります。キーワードを変更するために特定のバリアントを初めて使用する必要が生じる場合、グラフィックスドライバーがシェーダープログラムの準備をする間に、がたつきが発生する可能性があります。これは、大きなシェーダーや複雑なシェーダーで、あるいはグローバルキーワードの状態の変化が複数のシェーダーに影響する場合に、特に問題となる場合があります。これを回避するため、シェーダーバリアントでキーワードを使用する場合には、シェーダーのローディングと事前準備のアプローチを決定する際にキーワードバリアントのことを考慮してください。詳細は、Unity がシェーダーをロードして使用する方法 を参照してください。
シェーダーをオーサリングする際は、キーワードをセットで宣言します。セットには、互いに排他的なキーワードが含まれます。
ランタイムでは、Unity はこうしたセットの概念を持ちません。任意のキーワードを個別に有効化または無効化することが可能になっており、キーワードを有効化または無効化しても、他のどのキーワードの状態にも影響しません。つまり、同じセットに含まれる複数のキーワードを有効にしたり、セット内の全てのキーワードを無効にしたりすることができます。
When more than one keyword in a set is enabled or no keywords in a set are enabled, Unity chooses a variant that it considers a “good enough” match. There is no guarantee about what exactly happens, and it can lead to unintended results. It is best to avoid this situation by managing keyword state carefully.