文章目录
环境
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;}
版权归原作者 Jave.Lin 所有, 如有侵权,请联系我们删除。