IPreprocessShaders.OnProcessShader
Declaration
public void OnProcessShader(Shader shader, Rendering.ShaderSnippetData snippet, IList<ShaderCompilerData> data);Параметры
| Параметр | Описание |
|---|---|
| шейдер | Шейдер, который Unity собирается компилировать. |
| фрагмент | Подробности о конкретном коде шейдера, который компилируется. |
| данные | Список вариантов, которые Unity собирается компилировать для шейдера. |
Описание
Реализуйте этот интерфейс, чтобы получать обратный вызов перед компиляцией фрагмента шейдера.
Когда вы создаете приложение, Unity компилирует каждый исходный файл шейдера в несколько файлов варианты шейдеров. Unity создает варианты для некоторых или всех возможных комбинаций ключевых слов, определенных в исходном файле шейдера.
Вы можете использовать OnProcessShader чтобы итерировать через каждый шейдер и вариант Unity готовится к компиляции и исключает ('strip') варианты, которые используют ключевые слова или комбинации ключевых слов, которые вам не нужны. Если вы исключаете варианты, вы можете уменьшить размер сборки, время сборки и количество памяти выполнения Unity использования.
Например, вы можете использовать OnProcessShader для удаления вариантов, которые используют следующее:
- Ключевые слова, которые не нужны для текущей целевой платформы.
- Комбинации ключевых слов, которые никогда не используются.
- Ключевые слова, которые вы используете только в отладочных сборках.
Unity ссылается на OnProcessShader обратный вызов в Player и AssetBundle Если в кэше уже есть какие-либо шейдеры, то этот метод не вызывается для этих шейдеров. Чтобы убедиться, что обратный вызов запускается для всех шейдеров, выполните чистая сборка. Чтобы запустить его для конкретного шейдера, измените этот шейдер или один из его зависимых ассетов.
Чтобы помочь вам определить ключевые слова и варианты для удаления, вы можете проверить, какие варианты шейдеров есть в вашем проектеНапример, если вы объявить ключевое слово вызванный DEBUG в коде шейдера, используя #pragma multi_compile _ DEBUG, следующим образом: Скрипт редактора находит и удаляет варианты шейдера, использующие ключевое слово.
При сборке приложения скрипт выполняет следующие действия:
- Создаёт класс, реализующий
IPreprocessShadersinterface. - Создает экземпляр
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; } } } }
Вы также можете найти местные ключевые слова. ShaderKeyword в рамках осуществления OnProcessShader, так что вы можете использовать обратный вызов shader переменная в ShaderKeyword изготовитель.
Например, если вы объявляете локальное ключевое слово, называемое 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; } } } }
Если вы удаляете вариант, который Материалу нужен во время выполнения, Unity выбирает доступный вариант шейдера, который соответствует ему как можно ближе.
Узнайте о других способах варианты ленточного шейдера.
Дополнительные ресурсы: BuildPipeline.BuildPlayer, BuildPipeline.BuildAssetBundles, IPreprocessComputeShaders.