Shader variant optimization in Unity


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.

Insert image description here

  • There is a Show after the variant number to show which variants there are.

Insert image description here


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.

Insert image description here

Optimization 2: Use skip_variants to eliminate unnecessary variants

Insert image description here

  • 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

Insert image description here
Insert image description here

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

Insert image description here

  • After checking the check box, you can remove the unused variants of shader_feature.

Insert image description here
Insert image description here


4. Variant Collector

1. We create a variant collector in the resource management interface

Insert image description here

2. After creating the variant collector, we add the Shader we just used to the variant collector.

Insert image description here

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.

Insert image description here


5. Variant collector in Unity project settings

  • Edit->Project Setting->Graphics->Shader Stripping
  • where you can customize whether to use variants

Insert image description here

  • 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
        }
    }
}

Guess you like

Origin blog.csdn.net/qq_51603875/article/details/134697692