本文主要是介绍剥离脚本化着色器变体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Massively reduce Player build time and data size by allowing developers to control which Shader variants are handled by the Unity Shader compiler and included in the Player data.
通过允许开发人员控制Unity Shader编译器处理哪些Shader变体并将其包含在Player数据中,来大大减少Player的构建时间和数据大小。
Player build time and data size increase along with the complexity of your project because of the rising number of shader variants.
由于着色器变体的数量不断增加,播放器的构建时间和数据大小会随着项目的复杂性而增加。
With scriptable shader variants stripping, introduced in 2018.2 beta, you can manage the number of shader variants generated and therefore drastically reduce Player build time and data size.
通过2018.2 beta中引入的可脚本化的着色器变体剥离功能,您可以管理生成的着色器变体的数量,从而大大减少Player的构建时间和数据大小。
This feature allows you to strip all the shader variants with invalid code paths, strip shader variants for unused features or create shader build configurations such as “debug” and “release” without affecting iteration time or maintenance complexity.
此功能使您可以剥离带有无效代码路径的所有着色器变体,为未使用的功能剥离着色器变体或创建着色器构建配置(例如“调试”和“发布”),而不会影响迭代时间或维护复杂性。
In this blog post, we first define some of the terms we use. Then we focus on the definition of shader variants to explain why we can generate so many. This is followed by a description of automatic shader variants stripping and how scriptable shader variants stripping is implemented in the Unity shader pipeline architecture. Then, we look at the scriptable shader variants stripping API before discussing results on the Fountainbleau demo and concluding with some tips on writing stripping scripts.
在此博客文章中,我们首先定义一些我们使用的术语。 然后,我们着重介绍着色器变体的定义,以解释为什么我们可以生成这么多变体。 接下来是对自动着色器变体剥离的描述,以及如何在Unity着色器管道体系结构中实现可脚本化的着色器变体剥离。 然后,在讨论Fountainbleau演示的结果并总结一些编写剥离脚本的技巧之前,我们先看一下可脚本化的着色器变体剥离API。
Learning scriptable shader variants stripping is not a trivial undertaking, but it can lead to a massive increase in team efficiency!
学习可脚本化的着色器变体剥离并不是一件容易的事,但是它可以大大提高团队效率!
概念 (Concepts)
To understand the scriptable shader variants stripping feature it is important to have a precise understanding of the different concepts involved.
要了解可编写脚本的着色器变体剥离功能,重要的是要对所涉及的不同概念有一个精确的了解。
Shader asset: The full file source code with properties, sub-shader, passes, and HLSL.
着色器资产 :包含属性,子着色器,过程和HLSL的完整文件源代码。
In Unity, uber shaders are managed by ShaderLab sub shaders, passes, and shader types as well as the #pragma multi_compile and #pragma shader_feature preprocessor directives.
在Unity中,超级着色器由ShaderLab子着色器,过程和着色器类型以及#pragma multi_compile和#pragma shader_feature 预处理器指令管理 。
计算生成的着色器变体的数量 (Counting the number of shader variants generated)
To use scriptable shader variant stripping, you need a clear understanding of what a shader variant is, and how shader variants are generated by the shader build pipeline. The number of shader variants generated is directly proportional to the build time and the Player shader variant data size. A shader variant is one output of the shader build pipeline.
要使用可脚本化的着色器变体剥离,您需要清楚地了解什么是着色器变体,以及着色器构建管道如何生成着色器变体。 生成的着色器变量的数量与构建时间和Player着色器变量的数据大小成正比。 着色器变体是着色器构建管道的一个输出。
Shader keywords are one of the elements that cause the generation of shader variants. An unconsidered use of shader keywords can quickly lead to a shader variants count explosion and therefore extremely long build time.
着色器关键字是导致生成着色器变体的元素之一。 不考虑使用着色器关键字会Swift导致着色器变体数量激增,因此构建时间非常长。
To see how shader variants are generated, the following simple shader couns how many shader variants it produces:
若要查看着色器变体的生成方式,以下简单的着色器会计算出它会生成多少个着色器变体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | Shader "ShaderVariantsStripping" { SubShader { Pass { Name "ShaderVariantsStripping/Pass" CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile COLOR_ORANGE COLOR_VIOLET COLOR_GREEN COLOR_GRAY #pragma multi_compile OP_ADD OP_MUL OP_SUB struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 get_color() { #if defined(COLOR_ORANGE) return fixed4(1.0, 0.5, 0.0, 1.0); #elif defined(COLOR_VIOLET) return fixed4(0.8, 0.2, 0.8, 1.0); #elif defined(COLOR_GREEN) return fixed4(0.5, 0.9, 0.3, 1.0); #elif defined(COLOR_GRAY) return fixed4(0.5, 0.9, 0.3, 1.0); #else #error "Unknown 'color' keyword" #endif } fixed4 frag (v2f i) : SV_Target { fixed4 diffuse = tex2D(_MainTex, i.uv); fixed4 color = get_color(); #if defined(OP_ADD) return diffuse + color; #elif defined(OP_MUL) return diffuse * color; #elif defined(OP_SUB) return diffuse - color; #else #error "Unknown 'op' keyword" #endif } ENDCG } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | Shader "ShaderVariantsStripping" { SubShader { Pass { Name "ShaderVariantsStripping/Pass" CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile COLOR_ORANGE COLOR_VIOLET COLOR_GREEN COLOR_GRAY #pragma multi_compile OP_ADD OP_MUL OP_SUB struct appdata { float4 vertex : POSITION ; float2 uv : TEXCOORD0 ; } ; struct v2f { float2 uv : TEXCOORD0 ; float4 vertex : SV_POSITION ; } ; sampler2D _MainTex ; float4 _MainTex_ST ; v2f vert ( appdata v ) { v2f o ; o . vertex = UnityObjectToClipPos ( v . vertex ) ; o . uv = v . uv ; return o ; } fixed4 get_color ( ) { #if defined(COLOR_ORANGE) return fixed4 ( 1.0 , 0.5 , 0.0 , 1.0 ) ; #elif defined(COLOR_VIOLET) return fixed4 ( 0.8 , 0.2 , 0.8 , 1.0 ) ; #elif defined(COLOR_GREEN) return fixed4 ( 0.5 , 0.9 , 0.3 , 1.0 ) ; #elif defined(COLOR_GRAY) return fixed4 ( 0.5 , 0.9 , 0.3 , 1.0 ) ; #else #error "Unknown 'color' keyword" #endif } fixed4 frag ( v2f i ) : SV_Target { fixed4 diffuse = tex2D ( _MainTex , i . uv ) ; fixed4 color = get_color ( ) ; #if defined(OP_ADD) return diffuse + color ; #elif defined(OP_MUL) return diffuse * color ; #elif defined(OP_SUB) return diffuse - color ; #else #error "Unknown 'op' keyword" #endif } ENDCG } } } |
The total number of shader variants in a project is deterministic and given by the following equation:
项目中着色器变体的总数是确定性的,并由以下公式给出:



Keywords in the equation refers to both platform and shader keywords. A graphics tier is a specific platform keyword set combination.
公式中的关键字指的是平台和Shader关键字。 图形层是特定的平台关键字集组合。
The ShaderVariantStripping/Pass has two multi compile directives. The first directive defines 4 keywords (COLOR_ORANGE, COLOR_VIOLET, COLOR_GREEN, COLOR_GRAY) and the second directive defines 3 keywords (OP_ADD, OP_MUL, OP_SUB). Finally, the pass defines 2 shader stages: a vertex shader stage and a fragment shader stage.
ShaderVariantStripping / Pass具有两个多重编译指令。 第一个指令定义4个关键字(COLOR_ORANGE,COLOR_VIOLET,COLOR_GREEN,COLOR_GRAY),第二个指令定义3个关键字(OP_ADD,OP_MUL,OP_SUB)。 最后,该遍定义了两个着色器阶段:一个顶点着色器阶段和一个片段着色器阶段。

This shader variant total is given for a single supported graphics API. However, for each supported graphics API in the project, we need a dedicated set of shader variants. For example, if we build an Android Player that supports both OpenGL ES 3 and Vulkan, we need two sets of shader variants. As a result, the Player build time and shader data size are directly proportional to the number of supported graphics APIs.
此着色器变体总数是针对单个受支持的图形API给出的。 但是,对于项目中每个受支持的图形API ,我们需要一组专用的着色器变体。 例如,如果我们构建一个同时支持OpenGL ES 3和Vulkan的Android Player,则需要两组着色器变体。 因此,Player的构建时间和着色器数据大小与支持的图形API的数量成正比。
着色器构建管道 (Shader build pipeline)
The shader compilation pipeline in Unity is a black box where each shader in the project is parsed to extract shader snippets before collecting the variant preprocessing instructions, such as multi_compile and shader_feature. This produces a list of compilation parameters, one per shader variant.
Unity中的着色器编译管道是一个黑匣子,在此项目中每个着色器都经过解析,以在收集变体预处理指令(例如multi_compile和shader_feature)之前提取着色器片段。 这将生成一个编译参数列表,每个着色器变体一个。
These compilation parameters include the shader snippet, the graphics tier, the shader type, the shader keyword set, the pass type and name. Each of the set compilation parameters are used to produce a single shader variant.
这些编译参数包括着色器代码段,图形层,着色器类型,着色器关键字集,通过类型和名称。 每个设置的编译参数都用于生成单个着色器变体。
Consequently, Unity executes an automatic shader variant stripping pass based on two heuristics. Firstly, stripping is based on the Project Settings, for example, if Virtual Reality Supported is disabled then VR shader variants are systematically stripped. Second, the automatic stripping is based on the configuration of Shader Stripping section of the Graphics Settings.
因此,Unity基于两种启发式算法执行自动着色器变体剥离过程。 首先,剥离是基于项目设置的,例如,如果禁用“支持虚拟现实”,则系统地剥离VR着色器变体。 其次,自动剥离基于“ 图形设置”的“着色器剥离”部分的配置。

Automatic shader variants stripping options in the GraphicsSettings.
GraphicsSettings中的自动着色器变体剥离选项。
Automatic shader variants stripping is based on build time restrictions. Unity can’t automatically select only the necessary shader variants at build time because those shader variants depend on runtime C# execution. For example, if a C# script adds a point light but there were no point lights at build time, then there is no way for the shader build pipeline to figure out that the Player would need a shader variant that does point light shading.
自动着色器变体剥离是基于构建时间限制的。 Unity无法在构建时自动选择必要的着色器变体,因为这些着色器变体取决于运行时C#执行。 例如,如果C#脚本添加了一个点光源,但在构建时没有点光源,则着色器构建管道无法确定Player是否需要进行点光源着色的着色器变体。
Here’s a list of shader variants with enabled keywords that get stripped automatically:
这是带有启用的关键字的着色器变体的列表,这些自动被剥离:
Lightmap modes: LIGHTMAP_ON, DIRLIGHTMAP_COMBINED, DYNAMICLIGHTMAP_ON, LIGHTMAP_SHADOW_MIXING, SHADOWS_SHADOWMASK
光照贴图模式:LIGHTMAP_ON,DIRLIGHTMAP_COMBINED,DYNAMICLIGHTMAP_ON,LIGHTMAP_SHADOW_MIXING,SHADOWS_SHADOWMASK
Fog modes: FOG_LINEAR, FOG_EXP, FOG_EXP2
雾模式:FOG_LINEAR,FOG_EXP,FOG_EXP2
Instancing Variants: INSTANCING_ON
实例变体:INSTANCING_ON
Furthermore, when Virtual Reality support is disabled, the shader variants with the following built-in enabled keywords are stripped:
此外,禁用虚拟现实支持后,将剥离具有以下内置启用的关键字的着色器变体:
STEREO_INSTANCING_ON, STEREO_MULTIVIEW_ON, STEREO_CUBEMAP_RENDER_ON, UNITY_SINGLE_PASS_STEREO
STEREO_INSTANCING_ON,STEREO_MULTIVIEW_ON,STEREO_CUBEMAP_RENDER_ON,UNITY_SINGLE_PASS_STEREO
When automatic stripping is done, the shader build pipeline uses the remaining compilation parameter sets to schedule shader variant compilation in parallel, launching as many simultaneous compilations as the platform has CPU core threads.
自动剥离完成后,着色器构建管道会使用其余的编译参数集来并行调度着色器变体编译,并启动与平台具有CPU核心线程的数目相同的同时编译。
Here’s a visual representation of that process:
这是该过程的直观表示:

Shader pipeline architecture with scriptable shader variant stripping integration in orange.
具有橙色的可编写脚本的着色器变量剥离集成的着色器管道体系结构。
In Unity 2018.2 beta, the shader pipeline architecture introduces a new stage right before the shader variant compilation scheduling, allowing users to control the shader variant compilation. This new stage is exposed via C# callbacks to user code, and each callback is executed per shader snippet.
在Unity 2018.2 beta中 ,着色器管道架构在着色器变体编译日程安排之前引入了一个新阶段,允许用户控制着色器变体编译。 这个新阶段通过C#回调公开给用户代码,并且每个回调均按着色器代码段执行。
可编写脚本的着色器变体剥离API (Scriptable shader variant stripping API)
As an example, the following script enables stripping of all the shader variants that would be associated with a “DEBUG” configuration, identified by a “DEBUG” keyword used in development Player build.
例如,以下脚本可剥离所有与“ DEBUG”配置相关联的着色器变体,“ DEBUG”配置由开发Player构建中使用的“ DEBUG”关键字标识。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | using System.Collections.Generic; using UnityEditor; using UnityEditor.Build; using UnityEditor.Rendering; using UnityEngine; using UnityEngine.Rendering; // Simple example of stripping of a debug build configuration class ShaderDebugBuildProcessor : IPreprocessShaders { ShaderKeyword m_KeywordDebug; public ShaderDebugBuildProcessor() { m_KeywordDebug = new ShaderKeyword("DEBUG"); } // Multiple callback may be implemented. // The first one executed is the one where callbackOrder is returning the smallest number. public int callbackOrder { get { return 0; } } public void OnProcessShader( Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> shaderCompilerData) { // In development, don't strip debug variants if (EditorUserBuildSettings.development) return; for (int i = 0; i < shaderCompilerData.Count; ++i) { if (shaderCompilerData[i].shaderKeywordSet.IsEnabled(m_KeywordDebug)) { shaderCompilerData.RemoveAt(i); --i; } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | using System . Collections . Generic ; using UnityEditor ; using UnityEditor . Build ; using UnityEditor . Rendering ; using UnityEngine ; using UnityEngine . Rendering ; // Simple example of stripping of a debug build configuration class ShaderDebugBuildProcessor : IPreprocessShaders { ShaderKeyword m_KeywordDebug ; public ShaderDebugBuildProcessor ( ) { m_KeywordDebug = new ShaderKeyword ( "DEBUG" ) ; } // Multiple callback may be implemented. // The first one executed is the one where callbackOrder is returning the smallest number. public int callbackOrder { get { return 0 ; } } public void OnProcessShader ( Shader shader , ShaderSnippetData snippet , IList < ShaderCompilerData > shaderCompilerData ) { // In development, don't strip debug variants if ( EditorUserBuildSettings . development ) return ; for ( int i = 0 ; i < shaderCompilerData . Count ; ++ i ) { if ( shaderCompilerData [ i ] . shaderKeywordSet . IsEnabled ( m_KeywordDebug ) ) { shaderCompilerData . RemoveAt ( i ) ; -- i ; } } } } |
OnProcessShader is called right before the scheduling of the shader variant compilation.
在计划着色器变体编译之前,将调用OnProcessShader。
Each combination of a Shader, a ShaderSnippetData and ShaderCompilerData instances is an identifier for a single shader variant that the shader compiler will produce. To strip that shader variant, we only need to remove it from the ShaderCompilerData list.
Shader,ShaderSnippetData和ShaderCompilerData实例的每种组合都是着色器编译器将生成的单个着色器变体的标识符。 要剥离该着色器变体,我们只需要将其从ShaderCompilerData列表中删除即可。
Every single shader variant that the shader compiler should generate will appear in this callback. When working on scripting the shader variants stripping, you need to first figure out which variants need removing, because they’re not useful for the project.
着色器编译器应生成的每个着色器变体都将出现在此回调中。 在编写着色器变体剥离脚本时,您首先需要弄清楚哪些变体需要删除,因为它们对项目没有用。
结果 (Results)
渲染管线的着色器变体剥离 (Shader variants stripping for a render pipeline)
One use case for the scriptable shader variants stripping is to systematically strip invalid shader variants of a render pipeline due to the various combinations of shader keywords.
可脚本化的着色器变体剥离的一个用例是,由于着色器关键字的各种组合,系统地剥离渲染管道的无效着色器变体。
A shader variants stripping script included in the HD render pipeline allows you to systematically reduce the build time and size of a project using the HD render pipeline. This script applies to the following shaders:
HD渲染管道中包含的着色器变体剥离脚本允许您使用HD渲染管道来系统地减少项目的构建时间和大小。 该脚本适用于以下着色器:
HDRenderPipeline/Lit HDRenderPipeline/LitTessellation HDRenderPipeline/LayeredLit HDRenderPipeline/LayeredLitTessellation
HDRenderPipeline / Lit HDRenderPipeline / LitTessellation HDRenderPipeline / LayeredLit HDRenderPipeline / LayeredLitTessellation
The script produces the following results:
该脚本产生以下结果:
Unstripped | Stripped | |
Player Data Shader Variant Count | 24350 (100%) | 12122 (49.8%) |
Player Data Size on disk | 511 MB | 151 MB |
Player Build Time | 4864 seconds | 1356 seconds |
不剥离 | 剥离 | |
播放器数据着色器变体计数 | 24350(100%) | 12122(49.8%) |
磁盘上的播放器数据大小 | 511兆字节 | 151兆字节 |
玩家建立时间 | 4864秒 | 1356秒 |

Screenshot of the Fontainebleau Photogrammetry demo using the HD Render Pipeline from the standard PlayStation 4 1920×1080 resolution.
枫丹白露摄影测量演示的屏幕快照,使用的是标准PlayStation 4 1920×1080分辨率的HD渲染管线。
Furthermore, the Lightweight render pipeline for Unity 2018.2 has a UI to automatically feed a stripping script that can automatically strip up to 98% of the shader variants which we expect to be particularly valuable for mobile projects.
此外,Unity 2018.2的轻量级渲染管道具有一个UI,可以自动提供一个剥离脚本 ,该脚本可以自动剥离多达98%的着色器变体,我们希望这对于移动项目特别有价值。
为项目剥离着色器变体 (Shader variants stripping for a project)
Another use case is a script to strip all the rendering features of a render pipeline that are not used for a specific project. Using an internal test demo for the Lightweight rendering pipeline, we got the following results for the entire project:
另一个用例是一个脚本,用于剥离渲染管道中所有未用于特定项目的渲染功能。 使用针对Lightweight渲染管道的内部测试演示,我们获得了整个项目的以下结果:
Unstripped | Stripped | |
Player Data Shader Variant Count | 31080 | 7056 |
Player Data Size on disk | 121 | 116 |
Player Build Time | 839 seconds | 286 seconds |
不剥离 | 剥离 | |
播放器数据着色器变体计数 | 31080 | 7056 |
磁盘上的播放器数据大小 | 121 | 116 |
玩家建立时间 | 839秒 | 286秒 |
As we can see, using scriptable shader variant stripping can lead to significant results and with more work on the stripping script we could go even further.
如我们所见,使用可脚本化的着色器变体剥离可以带来显着的结果,并且通过对剥离脚本进行更多的工作,我们可以走得更远。

Screenshot of a Lightweight pipeline demo.
轻量级管道演示的屏幕截图。
编写着色器变体剥离代码的技巧 (Tips on writing shader variants stripping code)
改进着色器代码设计 (Improving shader code design)
A project may quickly run into a shader variants count explosion, leading to unsustainable compilation time and Player data size. Scriptable shader stripping helps deal with this issue, but you should reevaluate how you are using shader keywords to generate more relevant shader variants. We can rely on the #pragma skip_variants to test unused keywords in the editor.
一个项目可能很快会遇到一个着色器变体,数量激增,从而导致不可持续的编译时间和Player数据大小。 可脚本化的着色器剥离可帮助解决此问题,但您应该重新评估如何使用着色器关键字生成更相关的着色器变体。 我们可以依靠#pragma skip_variants在编辑器中测试未使用的关键字。
For example, in ShaderStripping/Color Shader the preprocessing directives are declared with the following code:
例如,在ShaderStripping / Color Shader中,预处理指令使用以下代码声明:
1 2 | #pragma multi_compile COLOR_ORANGE COLOR_VIOLET COLOR_GREEN COLOR_GRAY // color keywords #pragma multi_compile OP_ADD OP_MUL OP_SUB // operator keywords |
1 2 | #pragma multi_compile COLOR_ORANGE COLOR_VIOLET COLOR_GREEN COLOR_GRAY // color keywords #pragma multi_compile OP_ADD OP_MUL OP_SUB // operator keywords |
This approach implies that all the combinations of color keywords and operator keywords will be generated.
这种方法意味着将生成颜色关键字和操作员关键字的所有组合。
Let’s say we want to render the following scene:
假设我们要渲染以下场景:

COLOR_ORANGE + OP_ADD, COLOR_VIOLET + OP_MUL, COLOR_GREEN + OP_MUL.
COLOR_ORANGE + OP_ADD,COLOR_VIOLET + OP_MUL,COLOR_GREEN + OP_MUL。
First, we should make sure that every keyword is actually useful. In this scene COLOR_GRAY and OP_SUB are never used. If we can guarantee these keywords are never used, then we should remove them.
首先,我们应该确保每个关键字实际上都是有用的。 在此场景中,从不使用COLOR_GRAY和OP_SUB。 如果我们可以保证不使用这些关键字,则应将其删除。
Second, we should combine keywords that effectively produce a single code path. In this example, the ‘add’ operation is always used with the ‘orange’ color exclusively. So we can combine them in a single keyword and refactor the code as shown below.
其次,我们应该结合有效产生单个代码路径的关键字。 在此示例中,“添加”操作始终与“橙色”颜色一起使用。 因此,我们可以将它们组合为一个关键字,然后重构代码,如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 | #pragma multi_compile ADD_COLOR_ORANGE MUL_COLOR_VIOLET MUL_COLOR_GREEN #if defined(ADD_COLOR_ORANGE) #define COLOR_ORANGE #define OP_ADD #elif defined(MUL_COLOR_VIOLET) #define COLOR_VIOLET #define OP_MUL #elif defined(MUL_COLOR_GREEN) #define COLOR_GREEN #define OP_MUL #endif |
1 2 3 4 5 6 7 8 9 10 11 12 | #pragma multi_compile ADD_COLOR_ORANGE MUL_COLOR_VIOLET MUL_COLOR_GREEN #if defined(ADD_COLOR_ORANGE) #define COLOR_ORANGE #define OP_ADD #elif defined(MUL_COLOR_VIOLET) #define COLOR_VIOLET #define OP_MUL #elif defined(MUL_COLOR_GREEN) #define COLOR_GREEN #define OP_MUL #endif |
Of course, it’s not always possible to refactor keywords. In these cases, scriptable shader variants stripping is a valuable tool!
当然,并非总是可以重构关键字。 在这些情况下,可脚本化的着色器变体剥离是一个有价值的工具!
使用callbackOrder在多个步骤中剥离着色器变体 (Using callbackOrder to strip shader variants in multiple steps)
For each snippet, all the shader variant stripping scripts are executed. We can order the scripts’ execution by ordering the value returned by the callbackOrder member function. The shader build pipeline will execute the callbacks in order of increasing callbackOrder, so lowest first and highest last.
对于每个片段,将执行所有着色器变体剥离脚本。 我们可以通过对callbackOrder成员函数返回的值进行排序来对脚本的执行进行排序。 着色器构建管道将按递增的callbackOrder顺序执行回调,因此,最低的优先和最高的最后。
A use case for using multiple shader stripping scripts is to separate the scripting per purpose. For example:
使用多个着色器剥离脚本的用例是按用途分隔脚本。 例如:
Script 2: Strips all the debug shader variants.
脚本2:剥离所有调试着色器变体。
编写着色器变体剥离脚本的过程 (Process for writing a shader variants stripping script)
Shader variants stripping is extremely powerful but requires a lot of work to achieve good results.
着色器变体剥离功能非常强大,但需要大量工作才能达到良好的效果。
下载示例项目 (Download the sample project)
The example project used to illustrate this blog post can be downloaded here. It requires Unity 2018.2.0b1.
可以在此处下载用于说明此博客文章的示例项目。 它需要Unity 2018.2.0b1 。
在Unite Berlin上了解有关优化二进制部署大小的更多信息 (Learn more about optimizing binary deployment size at Unite Berlin)
Come to Jonas Echterhoff’s June 21 talk and learn about all the new tools that give you more control over what ends up in your build!
快来参加Jonas Echterhoff于6月21日发表的演讲,了解所有可以使您对构建最终结果有更多控制权的新工具!
翻译自: https://blogs.unity3d.com/2018/05/14/stripping-scriptable-shader-variants/
这篇关于剥离脚本化着色器变体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!