Unity中Shader变体优化


前言

在Shader中,一般有两个方面的优化:一方面是内存优化(即变体优化);一方面是渲染优化(即Shader中计算的优化)。我们这篇文章来了解一下Shader变体的优化。


一、在Unity中查看变体个数,以及有哪些变体

  • 创建一个UnlitShader,里面有一个默认的Shader

#pragma multi_compile_fog

  • 选择Shader后,点击Compile and show code 右边的小箭头可以可见变体数

在这里插入图片描述

  • 变体数后面有一个 Show,可以展示有哪些变体

在这里插入图片描述


二、若使用预定义的变体太多,我们只使用其中的几个变体,我们该怎么做

优化一:可以直接定义需要的那个变体

  • 例如,我们只需要线性雾 FOG_LINEAR 变体,可以单独定义这个变体

#pragma multi_compile _ FOG_LINEAR

  • 空格 _ 空格 是空变体的意思

  • 可以看见我们的变体数变少了

在这里插入图片描述

优化二:使用 skip_variants 剔除不需要的变体

在这里插入图片描述

  • 我们剔除 指数雾1 和 指数雾2

#pragma multi_compile_fog
//优化法二 (使用 skip_variants 剔除变体)
#pragma skip_variants FOG_EXP FOG_EXP2


三、变体的数量增长

1、使用 multi_compile 再定义 3 个变体

#pragma multi_compile_fog
//我们再定义3个变体 A B C 看一下变体数量会增加到多少
#pragma multi_compile A B C

  • 我们会看见,虽然我们只定义了三个变体。但是,最后的变体数,却是相乘的数量

在这里插入图片描述
在这里插入图片描述

由此可见变体数很容易达到成百上千的,所以我们要尽可能地控制变体的数量

2、再用 shader_feature 定义三个变体 D E F

shader_feature定义的变体,只有在使用的时候才会生成

//我们再用 shader_feature 定义三个变体 D E F(shader_feature定义的变体,只有在使用的时候才会生成)
#pragma shader_feature D E F

  • 我们可以看见在剔除没有用到的变体前,我们的变体数由上升了 3 倍

在这里插入图片描述

  • 勾选剔除后,可以把 shader_feature 没有使用的变体剔除

在这里插入图片描述
在这里插入图片描述


四、变体收集器

1、我们在资源管理界面,创建变体收集器

在这里插入图片描述

2、创建了变体收集器后,我们把刚才使用的Shader加入变体收集器

在这里插入图片描述

3、然后点击加号,可以看见变体收集器中收集的变体

变体收集器一般是由程序使用的,在游戏一开始对其进行着色器加载,比如说原神中进入游戏时,卡岩那个游戏加载。

在这里插入图片描述


五、Unity 项目设置 中的 变体收集器

  • Edit->Project Setting->Graphics->Shader Stripping
  • 可以在其中自定义是否使用变体

在这里插入图片描述

  • 还可以把用到的变体,全都打包成一个变体收集器(一般不推荐这样用,变体太多太杂了)

六、测试代码

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

  • 31
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
UnityShader变体是指在编译阶段根据当前渲染平台和材质属性的不同而生成的多个不同的着色器程序。Shader变体会根据平台的不同动态地作出适配,以实现在不同平台下的最佳性能和视觉效果。 在编写Shader时,我们可以使用多种预处理指令和变量来定义Shader变体。预处理指令比如#pragma multi_compile和#pragma shader_feature可以用来指示编译器在编译时根据条件来包含或排除某些代码块。通过这样的方式,我们可以根据不同情况选择不同的代码路径。 Shader变体的生成是基于Shader的特性和特定的材质属性。特性是用来定义一组可选功能的开关,可以在材质进行开关的切换。材质属性是指材质上的一些自定义属性,比如颜色、纹理等。因此,Shader变体的生成是根据这些特性和属性的组合来确定的。 Shader变体的生成会带来一定的开销,因为每个变体都需要编译和存储。为了减少这种开销,Unity使用了渐变的方式生成变体。即在编译过程Unity会根据之前生成的变体生成新的变体,以便在之后的编译过程尽可能重用已经生成的变体,从而减少重复的工作。 对于Shader变体的管理,Unity提供了几种优化的方式。首先,我们可以使用ShaderVariantCollection来存储和管理常用的变体,从而减少编译时间和内存占用。其次,可以使用ShaderKeywords来动态地切换Shader的特性,以实现更精细的控制和优化。 总之,UnityShader变体功能可以根据不同平台和材质属性生成多个不同的着色器程序,以实现最佳的性能和视觉效果。合理的使用Shader变体管理和优化可以大大提升游戏的性能和兼容性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠溪泽岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值