Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.
CloseFor some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.
Closeshader | The shader that Unity is about to compile. |
snippet | Details about the specific shader code being compiled. |
data | List of variants that Unity is about to compile for the shader. |
Implement this interface to receive a callback before a shader snippet is compiled.
When you build your application, Unity compiles each shader source file into multiple shader variants. Unity creates variants for some or all of the possible combinations of keywords you define in the shader source file.
You can use OnProcessShader
to iterate through each shader and variant Unity is about to compile, and exclude ('strip') variants that use keywords or keyword combinations you don't need. If you strip variants, you can greatly reduce build size, build times, and how much runtime memory Unity uses.
For example you can use OnProcessShader
to remove variants that use the following:
Unity invokes the OnProcessShader
callback in both Player and AssetBundle builds.
You can check what shader variants you have in your project to help you identify keywords and variants to strip.
For example if you declare a keyword called DEBUG
in your shader code using #pragma multi_compile _ DEBUG
, the following Editor script finds and strips shader variants that use the keyword.
The script does the following when you build your application:
IPreprocessShaders
interface.ShaderKeyword
with the name of the keyword.OnProcessShader
callback function and iterates over the data
list, which contains every variant in the shader.data.shaderKeywordSet.IsEnabled()
to check if each variant uses the keyword.data.removeAt()
to strip a shader variant if it contains the keyword and you've disabled Development build in Build Settings.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; } } } }
You can also find local keywords. You must create the ShaderKeyword
instance inside the implementation of OnProcessShader
, so you can use the callback's shader
variable in the ShaderKeyword
constructor.
For example if you declare a local keyword called RED
in your shader code using #pragma multi_compile_local _ RED
, the following script finds and strips shader variants that use the keyword.
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; } } } }
If you strip a variant that a Material needs at runtime, Unity chooses an available shader variant that matches as closely as possible.
Find out about other ways you can strip shader variants.
Additional resources: BuildPipeline.BuildPlayer, BuildPipeline.BuildAssetBundles, IPreprocessComputeShaders.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.