shader | Unity 将要编译的着色器。 |
snippet | 有关正在编译的特定着色器代码的详细信息。 |
data | Unity 将要为着色器编译的变体列表。 |
实现此接口以在编译着色器片段之前接收回调。
在构建应用程序时,Unity 会将每个着色器源文件编译成多个着色器变体。Unity 为着色器源文件中定义的关键字的所有可能组合或部分组合创建变体。
您可以使用 OnProcessShader
迭代 Unity 将要编译的每个着色器和变体,并排除(“剥离”)使用您不需要的关键字或关键字组合的变体。如果您剥离变体,可以大幅减少构建大小、构建时间以及 Unity 使用的运行时内存量。
例如,您可以使用 OnProcessShader
删除使用以下内容的变体
Unity 在 Player 和 AssetBundle 构建中都会调用 OnProcessShader
回调。
您可以检查项目中有哪些着色器变体,以帮助您确定要剥离的关键字和变体。
例如,如果您在着色器代码中声明一个名为 DEBUG
的关键字,使用 #pragma multi_compile _ DEBUG
,则以下编辑器脚本 会找到并剥离使用该关键字的着色器变体。
在构建应用程序时,该脚本会执行以下操作
IPreprocessShaders
接口的类。ShaderKeyword
实例。OnProcessShader
回调函数,并迭代 data
列表,其中包含着色器中的每个变体。data.shaderKeywordSet.IsEnabled()
检查每个变体是否使用该关键字。data.removeAt()
剥离包含该关键字的着色器变体,前提是在 构建设置 中禁用了 **开发版本**。using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; using UnityEditor.Build; using UnityEditor.Rendering;
class ShaderDebugBuildPreprocessor : IPreprocessShaders { ShaderKeyword m_KeywordToStrip;
public ShaderDebugBuildPreprocessor() { m_KeywordToStrip = new ShaderKeyword("DEBUG"); }
// Use callbackOrder to set when Unity calls this shader preprocessor. Unity starts with the preprocessor that has the lowest callbackOrder value. public int callbackOrder { get { return 0; } }
public void OnProcessShader( Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data) {
for (int i = 0; i < data.Count; ++i) { if (data[i].shaderKeywordSet.IsEnabled(m_KeywordToStrip) && !EditorUserBuildSettings.development) { var foundKeywordSet = string.Join(" ", data[i].shaderKeywordSet.GetShaderKeywords()); Debug.Log("Found keyword DEBUG in variant " + i + " of shader " + shader); Debug.Log("Keyword set: " + foundKeywordSet); data.RemoveAt(i); --i; } } } }
您还可以找到本地关键字。您必须在 OnProcessShader
的实现中创建 ShaderKeyword
实例,以便在 ShaderKeyword
构造函数中使用回调的 shader
变量。
例如,如果您在着色器代码中声明一个名为 RED
的本地关键字,使用 #pragma multi_compile_local _ RED
,则以下脚本会找到并剥离使用该关键字的着色器变体。
using System.Collections.Generic; using UnityEditor.Build; using UnityEditor.Rendering; using UnityEngine; using UnityEngine.Rendering;
class MyCustomBuildProcessor : IPreprocessShaders {
public int callbackOrder { get { return 0; } }
public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data) { // Create an instance of ShaderKeyword using the constructor that takes a Shader argument ShaderKeyword localKeywordToStrip = new ShaderKeyword(shader, "RED");
for (int i = 0; i < data.Count; ++i) { if (data[i].shaderKeywordSet.IsEnabled(localKeywordToStrip)) { data.RemoveAt(i); --i; } } } }
如果您剥离了 Material 在运行时需要的变体,Unity 会选择尽可能匹配的可用着色器变体。
了解有关其他剥离着色器变体方法的信息,请查看剥离着色器变体。
其他资源:BuildPipeline.BuildPlayer、BuildPipeline.BuildAssetBundles、IPreprocessComputeShaders。