0


Unity Shader - UI/Default shader 优化示例

文章目录


环境

Unity : 2020.3.37f1
Pipeline : BRP


优化

做性能优化都是慢慢都扣出来的

当然,优先处理 top 热点的

但是一些就算不是 top,但是像素面积有多,overdraw 也多不可小觑

当然,如果你能找到性能热点,那还是优先分析一下哪些 shader 占的 cycles 最高,和 A, L/S, T, 最高

还有 register 的数量尽可能的少


示例

比如:

UI/Default

的 shader
下面优化的是一些小部分的内容,不是 top 热点,优化原理是一样的

优化选项:

  • 浮点精度
  • 避免类型转换
  • 避免 laster z (一般是 alpha test 导致,或是 sv_depth 的深度操作)
  • 删除无用的效果代码
  • 删除不明显的效果代码
  • 优化写法(这个一般需要了解一些 编译器 无法识别的 编译优化时,需要特殊处理)

Texture Format : Alpha 8 和 shaderlab : _TextureSampleAdd

如果确保项目中没有使用到 texture 的格式为

Alpha 8

的 UI 纹理,那么可以将

_TextureSampleAdd

删除

但是

_TextureSampleAdd

文档根本没有说明
cginc 或是 shader 文件也没有表述,这就很 Unity

因此之前压根不敢删除

谷歌 搜索了一下,找到:
What does _TextureSampleAdd do?

然后确定我们项目中没使用到

Alpha 8

格式的 UI 纹理,那么就可以直接删除了
项目中实践发现,使用到

Alpha 8

的一般有:

  • UGUI 的 Text 组件,里面的 Font 资源会自动生成一张 Alpha 8 的 font atlas (推荐使用 TMP 替代 Text)
  • 还有主动使用到 alpha 8 来做为数据的并用于 Shader "UI/Default" shader 的 (这个很少,就看项目组有无这么使用)

看到了回答:
在这里插入图片描述


shaderlab : _UIMaskSoftnessX 和 _UIMaskSoftnessY

如果项目中的

RectMask2D

也没有使用到 软裁剪,也可以将

UI/Default

中的

_UIMaskSoftnessX

_UIMaskSoftnessY

删除

Softness 开启
在这里插入图片描述

Softness 关闭
在这里插入图片描述


shaderlab _Color

这块比较容易忽略,虽然只是 vs 的计算,而且 UI 的顶点数量不多,一般不是什么问题
但还是那句话,性能如果要做到极致,除了优化 top 热点,其余小的也是肉,能优化就优化

所以,如果项目中

UI/Default

使用了

_Color

,但是项目中没去使用,那就可以删除
一般都是使用unity 自带的按钮状态来控制(这些是通过 vertex buffer 来控制的,因为这样可以 vertex buffer 合批)


shader

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "UI/Default"{
    Properties
    {[PerRendererData]_MainTex("Sprite Texture",2D)="white"{}_Color("Tint", Color)=(1,1,1,1)_StencilComp("Stencil Comparison", Float)=8_Stencil("Stencil ID", Float)=0_StencilOp("Stencil Operation", Float)=0_StencilWriteMask("Stencil Write Mask", Float)=255_StencilReadMask("Stencil Read Mask", Float)=255_ColorMask("Color Mask", Float)=15[Toggle(UNITY_UI_ALPHACLIP)]_UseUIAlphaClip("Use Alpha Clip", Float)=0}

    SubShader
    {
        Tags
        {"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent""PreviewType"="Plane""CanUseSpriteAtlas"="True"}

        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp]
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]}

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend One OneMinusSrcAlpha
        ColorMask [_ColorMask]

        Pass
        {
            Name "Default"
        CGPROGRAM
            #pragmavertex vert#pragmafragment frag#pragmatarget 2.0#include"UnityCG.cginc"#include"UnityUI.cginc"#pragmamulti_compile_local _ UNITY_UI_CLIP_RECT#pragmamulti_compile_local _ UNITY_UI_ALPHACLIPstructappdata_t{
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };structv2f{
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord  : TEXCOORD0;
                float4 worldPosition : TEXCOORD1;
                float4  mask : TEXCOORD2;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            sampler2D _MainTex;
            fixed4 _Color;
            fixed4 _TextureSampleAdd;
            float4 _ClipRect;
            float4 _MainTex_ST;float _UIMaskSoftnessX;float _UIMaskSoftnessY;

            v2f vert(appdata_t v){
                v2f OUT;UNITY_SETUP_INSTANCE_ID(v);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
                float4 vPosition =UnityObjectToClipPos(v.vertex);
                OUT.worldPosition = v.vertex;
                OUT.vertex = vPosition;

                float2 pixelSize = vPosition.w;
                pixelSize /=float2(1,1)*abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));

                float4 clampedRect =clamp(_ClipRect,-2e10,2e10);
                float2 maskUV =(v.vertex.xy - clampedRect.xy)/(clampedRect.zw - clampedRect.xy);
                OUT.texcoord =TRANSFORM_TEX(v.texcoord.xy, _MainTex);
                OUT.mask =float4(v.vertex.xy *2- clampedRect.xy - clampedRect.zw,0.25/(0.25*half2(_UIMaskSoftnessX, _UIMaskSoftnessY)+abs(pixelSize.xy)));

                OUT.color = v.color * _Color;return OUT;}

            fixed4 frag(v2f IN): SV_Target
            {
                half4 color = IN.color *(tex2D(_MainTex, IN.texcoord)+ _TextureSampleAdd);#ifdefUNITY_UI_CLIP_RECT
                half2 m =saturate((_ClipRect.zw - _ClipRect.xy -abs(IN.mask.xy))* IN.mask.zw);
                color.a *= m.x * m.y;#endif#ifdefUNITY_UI_ALPHACLIPclip(color.a -0.001);#endif

                color.rgb *= color.a;return color;}
        ENDCG
        }}}

优化后

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "UI/Default_EXT"{
    Properties
    {[PerRendererData]_MainTex("Sprite Texture",2D)="white"{}_StencilComp("Stencil Comparison", Float)=8_Stencil("Stencil ID", Float)=0_StencilOp("Stencil Operation", Float)=0_StencilWriteMask("Stencil Write Mask", Float)=255_StencilReadMask("Stencil Read Mask", Float)=255_ColorMask("Color Mask", Float)=15[Toggle(UNITY_UI_ALPHACLIP)]_UseUIAlphaClip("Use Alpha Clip", Float)=0}

    SubShader
    {
        Tags
        {"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent""PreviewType"="Plane""CanUseSpriteAtlas"="True"}

        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp]
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]}

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend One OneMinusSrcAlpha
        ColorMask [_ColorMask]

        Pass
        {
            Name "Default"
        CGPROGRAM
            #pragmavertex vert#pragmafragment frag#pragmatarget 2.0#include"UnityCG.cginc"#include"UnityUI.cginc"#pragmamulti_compile_local _ UNITY_UI_CLIP_RECT#pragmamulti_compile_local _ UNITY_UI_ALPHACLIPstructappdata_t{
                float4 vertex   : POSITION;
                fixed4 color    : COLOR;
                half2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };structv2f{
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                half2 texcoord  : TEXCOORD0;//float4 worldPosition : TEXCOORD1;
                half2  mask : TEXCOORD2;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            sampler2D _MainTex;
            float4 _ClipRect;
            half4 _MainTex_ST;
            half _UIMaskSoftnessX;
            half _UIMaskSoftnessY;

            v2f vert(appdata_t v){
                v2f OUT;UNITY_SETUP_INSTANCE_ID(v);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
                float4 vPosition =UnityObjectToClipPos(v.vertex);//OUT.worldPosition = v.vertex;
                OUT.vertex = vPosition;

                half2 pixelSize = vPosition.w;
                pixelSize /=half2(1,1)*abs(mul((half2x2)UNITY_MATRIX_P, _ScreenParams.xy));

                float4 clampedRect =clamp(_ClipRect,-2e10,2e10);//float2 maskUV = (v.vertex.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
                OUT.texcoord =TRANSFORM_TEX(v.texcoord.xy, _MainTex);
                OUT.mask =half2(v.vertex.xy *2- clampedRect.xy - clampedRect.zw);

                OUT.color = v.color;return OUT;}

            fixed4 frag(v2f IN): SV_Target
            {
                half4 color = IN.color *tex2D(_MainTex, IN.texcoord);//color.rgb *= half3(1.0, 0.1, 0.1);#ifdefUNITY_UI_CLIP_RECT
                half2 m =saturate(_ClipRect.zw - _ClipRect.xy -abs(IN.mask.xy));
                color.a *= m.x * m.y;#endif#ifdefUNITY_UI_ALPHACLIPclip(color.a -0.001);#endif

                color.rgb *= color.a;return color;}
        ENDCG
        }}}

ARM Mobile Studio - Graphics Analyzer

vivo 手机 mali gpu 的来测试
AGA 分析一波

优化前

vs:
在这里插入图片描述

#version320 es#defineHLSLCC_ENABLE_UNIFORM_BUFFERS1#ifHLSLCC_ENABLE_UNIFORM_BUFFERS#defineUNITY_UNIFORM#else#defineUNITY_UNIFORMuniform#endif#defineUNITY_SUPPORTS_UNIFORM_LOCATION1#ifUNITY_SUPPORTS_UNIFORM_LOCATION#defineUNITY_LOCATION(x)layout(location = x)#defineUNITY_BINDING(x)layout(binding = x, std140)#else#defineUNITY_LOCATION(x)#defineUNITY_BINDING(x)layout(std140)#endif
uniform     vec4 _ScreenParams;
uniform     vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
uniform     vec4 hlslcc_mtx4x4glstate_matrix_projection[4];
uniform     vec4 hlslcc_mtx4x4unity_MatrixVP[4];
uniform     mediump vec4 _Color;
uniform     vec4 _ClipRect;
uniform     vec4 _MainTex_ST;
uniform     float _UIMaskSoftnessX;
uniform     float _UIMaskSoftnessY;
in highp vec4 in_POSITION0;
in highp vec4 in_COLOR0;
in highp vec2 in_TEXCOORD0;
out mediump vec4 vs_COLOR0;
out highp vec2 vs_TEXCOORD0;
out highp vec4 vs_TEXCOORD1;
out highp vec4 vs_TEXCOORD2;
vec4 u_xlat0;
vec4 u_xlat1;voidmain(){
    u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0]* in_POSITION0.xxxx + u_xlat0;
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2]* in_POSITION0.zzzz + u_xlat0;
    u_xlat0 = u_xlat0 + hlslcc_mtx4x4unity_ObjectToWorld[3];
    u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0]* u_xlat0.xxxx + u_xlat1;
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[2]* u_xlat0.zzzz + u_xlat1;
    u_xlat0 = hlslcc_mtx4x4unity_MatrixVP[3]* u_xlat0.wwww + u_xlat1;
    gl_Position = u_xlat0;
    u_xlat1 = in_COLOR0 * _Color;
    vs_COLOR0 = u_xlat1;
    vs_TEXCOORD0.xy = in_TEXCOORD0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    vs_TEXCOORD1 = in_POSITION0;
    u_xlat0.xy = _ScreenParams.yy * hlslcc_mtx4x4glstate_matrix_projection[1].xy;
    u_xlat0.xy = hlslcc_mtx4x4glstate_matrix_projection[0].xy * _ScreenParams.xx + u_xlat0.xy;
    u_xlat0.xy = u_xlat0.ww /abs(u_xlat0.xy);
    u_xlat0.xy =vec2(_UIMaskSoftnessX, _UIMaskSoftnessY)*vec2(0.25,0.25)+abs(u_xlat0.xy);
    vs_TEXCOORD2.zw =vec2(0.25,0.25)/ u_xlat0.xy;
    u_xlat0 =max(_ClipRect,vec4(-2e+10,-2e+10,-2e+10,-2e+10));
    u_xlat0 =min(u_xlat0,vec4(2e+10,2e+10,2e+10,2e+10));
    u_xlat0.xy = in_POSITION0.xy *vec2(2.0,2.0)+(-u_xlat0.xy);
    vs_TEXCOORD2.xy =(-u_xlat0.zw)+ u_xlat0.xy;return;}

FS:

在这里插入图片描述

#version320 es

precision highp float;
precision highp int;#defineHLSLCC_ENABLE_UNIFORM_BUFFERS1#ifHLSLCC_ENABLE_UNIFORM_BUFFERS#defineUNITY_UNIFORM#else#defineUNITY_UNIFORMuniform#endif#defineUNITY_SUPPORTS_UNIFORM_LOCATION1#ifUNITY_SUPPORTS_UNIFORM_LOCATION#defineUNITY_LOCATION(x)layout(location = x)#defineUNITY_BINDING(x)layout(binding = x, std140)#else#defineUNITY_LOCATION(x)#defineUNITY_BINDING(x)layout(std140)#endif
uniform     mediump vec4 _TextureSampleAdd;
uniform     vec4 _ClipRect;UNITY_LOCATION(0) uniform mediump sampler2D _MainTex;
in mediump vec4 vs_COLOR0;
in highp vec2 vs_TEXCOORD0;
in highp vec4 vs_TEXCOORD2;layout(location =0) out mediump vec4 SV_Target0;
vec4 u_xlat0;
mediump vec4 u_xlat16_0;
mediump float u_xlat16_1;voidmain(){
    u_xlat0.xy =(-_ClipRect.xy)+ _ClipRect.zw;
    u_xlat0.xy = u_xlat0.xy +-abs(vs_TEXCOORD2.xy);
    u_xlat0.xy = u_xlat0.xy * vs_TEXCOORD2.zw;#ifdefUNITY_ADRENO_ES3
    u_xlat0.xy =min(max(u_xlat0.xy,0.0),1.0);#else
    u_xlat0.xy =clamp(u_xlat0.xy,0.0,1.0);#endif
    u_xlat16_1 = u_xlat0.y * u_xlat0.x;
    u_xlat16_0 =texture(_MainTex, vs_TEXCOORD0.xy);
    u_xlat0 = u_xlat16_0 + _TextureSampleAdd;
    u_xlat0 = u_xlat0 * vs_COLOR0;
    u_xlat16_1 = u_xlat16_1 * u_xlat0.w;
    SV_Target0.xyz = u_xlat0.xyz *vec3(u_xlat16_1);
    SV_Target0.w = u_xlat16_1;return;}

优化后

VS:
在这里插入图片描述

Working Reigster 反而增加1就有点迷

#version320 es#defineHLSLCC_ENABLE_UNIFORM_BUFFERS1#ifHLSLCC_ENABLE_UNIFORM_BUFFERS#defineUNITY_UNIFORM#else#defineUNITY_UNIFORMuniform#endif#defineUNITY_SUPPORTS_UNIFORM_LOCATION1#ifUNITY_SUPPORTS_UNIFORM_LOCATION#defineUNITY_LOCATION(x)layout(location = x)#defineUNITY_BINDING(x)layout(binding = x, std140)#else#defineUNITY_LOCATION(x)#defineUNITY_BINDING(x)layout(std140)#endif
uniform     vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
uniform     vec4 hlslcc_mtx4x4unity_MatrixVP[4];
uniform     vec4 _ClipRect;
uniform     mediump vec4 _MainTex_ST;
in highp vec4 in_POSITION0;
in mediump vec4 in_COLOR0;
in mediump vec2 in_TEXCOORD0;
out mediump vec4 vs_COLOR0;
out mediump vec2 vs_TEXCOORD0;
out mediump vec2 vs_TEXCOORD2;
vec4 u_xlat0;
vec4 u_xlat1;voidmain(){
    u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0]* in_POSITION0.xxxx + u_xlat0;
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2]* in_POSITION0.zzzz + u_xlat0;
    u_xlat0 = u_xlat0 + hlslcc_mtx4x4unity_ObjectToWorld[3];
    u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0]* u_xlat0.xxxx + u_xlat1;
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[2]* u_xlat0.zzzz + u_xlat1;
    gl_Position = hlslcc_mtx4x4unity_MatrixVP[3]* u_xlat0.wwww + u_xlat1;
    vs_COLOR0 = in_COLOR0;
    u_xlat0 =max(_ClipRect,vec4(-2e+10,-2e+10,-2e+10,-2e+10));
    u_xlat0 =min(u_xlat0,vec4(2e+10,2e+10,2e+10,2e+10));
    u_xlat0.xy = in_POSITION0.xy *vec2(2.0,2.0)+(-u_xlat0.xy);
    u_xlat0.xy =(-u_xlat0.zw)+ u_xlat0.xy;
    vs_TEXCOORD2.xy = u_xlat0.xy;
    vs_TEXCOORD0.xy = in_TEXCOORD0.xy * _MainTex_ST.xy + _MainTex_ST.zw;return;}

FS:
在这里插入图片描述

#version320 es

precision highp float;
precision highp int;#defineHLSLCC_ENABLE_UNIFORM_BUFFERS1#ifHLSLCC_ENABLE_UNIFORM_BUFFERS#defineUNITY_UNIFORM#else#defineUNITY_UNIFORMuniform#endif#defineUNITY_SUPPORTS_UNIFORM_LOCATION1#ifUNITY_SUPPORTS_UNIFORM_LOCATION#defineUNITY_LOCATION(x)layout(location = x)#defineUNITY_BINDING(x)layout(binding = x, std140)#else#defineUNITY_LOCATION(x)#defineUNITY_BINDING(x)layout(std140)#endif
uniform     vec4 _ClipRect;UNITY_LOCATION(0) uniform mediump sampler2D _MainTex;
in mediump vec4 vs_COLOR0;
in mediump vec2 vs_TEXCOORD0;
in mediump vec2 vs_TEXCOORD2;layout(location =0) out mediump vec4 SV_Target0;
vec4 u_xlat0;
mediump vec4 u_xlat16_0;
mediump float u_xlat16_1;voidmain(){
    u_xlat0.xy =(-_ClipRect.xy)+ _ClipRect.zw;
    u_xlat0.xy = u_xlat0.xy +-abs(vs_TEXCOORD2.xy);#ifdefUNITY_ADRENO_ES3
    u_xlat0.xy =min(max(u_xlat0.xy,0.0),1.0);#else
    u_xlat0.xy =clamp(u_xlat0.xy,0.0,1.0);#endif
    u_xlat16_1 = u_xlat0.y * u_xlat0.x;
    u_xlat16_0 =texture(_MainTex, vs_TEXCOORD0.xy);
    u_xlat0 = u_xlat16_0 * vs_COLOR0;
    u_xlat16_1 = u_xlat16_1 * u_xlat0.w;
    SV_Target0.xyz = u_xlat0.xyz *vec3(u_xlat16_1);
    SV_Target0.w = u_xlat16_1;return;}
标签: unity shader优化

本文转载自: https://blog.csdn.net/linjf520/article/details/131831016
版权归原作者 Jave.Lin 所有, 如有侵权,请联系我们删除。

“Unity Shader - UI/Default shader 优化示例”的评论:

还没有评论