版本: Unity 6 (6000.0)
语言英语
  • C#

IPreprocessShaders.OnProcessShader

建议修改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们不能接受所有提交的内容,但我们会阅读用户提出的每个建议,并在适用时进行更新。

关闭

提交失败

由于某种原因,您的建议修改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

声明

public void OnProcessShader(Shader shader, Rendering.ShaderSnippetData snippet, IList<ShaderCompilerData> data);

参数

shader Unity 将要编译的着色器。
snippet 有关正在编译的特定着色器代码的详细信息。
data Unity 将要为着色器编译的变体列表。

描述

实现此接口以在编译着色器片段之前接收回调。

在构建应用程序时,Unity 会将每个着色器源文件编译成多个着色器变体。Unity 为着色器源文件中定义的关键字的所有可能组合或部分组合创建变体。

您可以使用 OnProcessShader 迭代 Unity 将要编译的每个着色器和变体,并排除(“剥离”)使用您不需要的关键字或关键字组合的变体。如果您剥离变体,可以大幅减少构建大小、构建时间以及 Unity 使用的运行时内存量。

例如,您可以使用 OnProcessShader 删除使用以下内容的变体

  • 当前目标平台不需要的关键字。
  • 从未使用的关键字组合。
  • 仅在调试版本中使用的关键字。

Unity 在 Player 和 AssetBundle 构建中都会调用 OnProcessShader 回调。

您可以检查项目中有哪些着色器变体,以帮助您确定要剥离的关键字和变体。

例如,如果您在着色器代码中声明一个名为 DEBUG 的关键字,使用 #pragma multi_compile _ DEBUG,则以下编辑器脚本 会找到并剥离使用该关键字的着色器变体。

在构建应用程序时,该脚本会执行以下操作

  1. 创建一个实现 IPreprocessShaders 接口的类。
  2. 创建一个带有关键字名称的 ShaderKeyword 实例。
  3. 实现 OnProcessShader 回调函数,并迭代 data 列表,其中包含着色器中的每个变体。
  4. 使用 data.shaderKeywordSet.IsEnabled() 检查每个变体是否使用该关键字。
  5. 使用 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.BuildPlayerBuildPipeline.BuildAssetBundlesIPreprocessComputeShaders