当具有相同名称的全局和局部着色器关键字具有不同的状态时,Unity 使用 LocalKeyword 的 isOverridable 属性来确定是否为单个材质或计算着色器启用或禁用该关键字。如果该关键字被声明具有全局范围,则 isOverridable 为 true,如果该关键字被声明具有本地范围,则该属性为 false。
isOverridable 为 true 时:如果存在并启用了同名称的全局关键字,Unity 将使用全局关键字的状态。否则,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.SetKeyword、ComputeShader.EnableKeyword 或 ComputeShader.DisableKeyword。
要使用命令缓冲区 (Command Buffer) 启用或禁用本地或全局关键字,请使用 CommandBuffer.EnableKeyword 或 CommandBuffer.DisableKeyword。
注意:启用或禁用与着色器变体一起使用的关键字时,Unity 会使用不同的着色器变体。在运行时更改着色器变体可能会影响性能。如果关键字的更改需要首次使用变体,可能会导致图形驱动程序在准备着色器程序时出现卡顿。对于大型或复杂的着色器而言,或者当全局关键字状态的改变会影响到多个着色器时,这可能会成为一个特别棘手的问题。为了避免这种情况,如果将关键字与着色器变体一起使用,请确保在着色器加载和预热策略中考虑关键字变体。有关更多信息,请参阅着色器加载。
在 Unity 中,可以将着色器关键字与着色器变体一起使用,也可以将它们与动态分支一起使用。你可以在声明关键字时自行决定。
LocalKeyword 的 isDynamic 属性指示在着色器源文件中关键字是否被声明为能够与动态分支一起使用。如果关键字被声明为能够与动态分支一起使用,则该属性为 true;如果关键字被声明为能够与着色器变体一起使用,则该属性为 false。