Article directory
Preface
In Shader, there are generally two aspects of optimization: on the one hand, memory optimization (i.e., variant optimization); on the other hand, rendering optimization (i.e., optimization of calculations in Shader). Let’s take a look at the optimization of Shader variants in this article.
1. Check the number of variants in Unity and what variants there are
- Create an UnlitShader with a default Shader inside
#pragma multi_compile_fog
- After selecting Shader, click the small arrow on the right side of Compile and show code to see the number of variants.
- There is a Show after the variant number to show which variants there are.
2. If there are too many predefined variants and we only use a few of them, what should we do?
Optimization 1: You can directly define the variant you need
- For example, we only need the linear fog FOG_LINEAR variant, which can be defined separately
#pragma multi_compile _ FOG_LINEAR
-
Space _ Space means empty variant
-
You can see that our number of variants has decreased.
Optimization 2: Use skip_variants to eliminate unnecessary variants
- We eliminate exponential fog 1 and exponential fog 2
#pragma multi_compile_fog
//Optimization method two (use skip_variants to eliminate variants)
#pragma skip_variants FOG_EXP FOG_EXP2
3. Growth in the number of variants
1. Use multi_compile to define 3 more variants
#pragma multi_compile_fog
//We define 3 more variants A B C to see how much the number of variants will increase
#pragma multi_compile A B C< /span>
- We'll see, though, that we've only defined three variants. However, the final number of variants is the multiplied number
It can be seen that the number of variants can easily reach hundreds or thousands, so we must control the number of variants as much as possible
2. Use shader_feature to define three variants D E F
shader_feature定义的变体,只有在使用的时候才会生成
//We then use shader_feature to define three variants D E F (the variants defined by shader_feature will only be generated when used)
#pragma shader_feature D E F
- We can see that before eliminating unused variants, our number of variants increased by 3 times
- After checking the check box, you can remove the unused variants of shader_feature.
4. Variant Collector
1. We create a variant collector in the resource management interface
2. After creating the variant collector, we add the Shader we just used to the variant collector.
3. Then click the plus sign to see the variants collected in the variant collector.
Variant collectors are generally used by programs to load shaders at the beginning of the game. For example, when entering the game in Genshin Impact, the game is loaded.
5. Variant collector in Unity project settings
- Edit->Project Setting->Graphics->Shader Stripping
- where you can customize whether to use variants
- You can also package all the used variants into a variant collector (generally not recommended, as there are too many variants)
6. Test code
Shader "MyShader/P2_3_2"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
//优化法一 ( _ 是空变体的意思)
//#pragma multi_compile _ FOG_LINEAR
//优化法二 (使用 skip_variants 剔除变体)
//#pragma skip_variants FOG_EXP FOG_EXP2
//我们再定义3个变体 A B C 看一下变体数量会增加到多少
#pragma multi_compile A B C
//我们再用 shader_feature 定义三个变体 D E F(shader_feature定义的变体,只有在使用的时候才会生成)
#pragma shader_feature D E F
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}