文章目录
- 环境
- TestingIf4Sample
- unity shaderlab 中的 TestingIf4Sample.shader
- graphics analyzer 中的 TestingIf4Sample.glsl
- TestingKW4Sample
- unity shaderlab 中的 TestingKW4Sample.shader
- graphics analyzer 中的 TestingKW4Sample.glsl
- 比较
环境
Unity : 2020.3.37f1
Pipeline : BRP
TestingIf4Sample
下面是 shaderlab 和 arm mobile studio 中的 graphics analyzer 的 glsl 代码
unity shaderlab 中的 TestingIf4Sample.shader
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "TestingIf4Sample"
{
Properties
{
_A_Tex ("A Texture", 2D) = "white" {}
_B_Tex ("B Texture", 2D) = "white" {}
_USE_TEX_A ("Using Tex A", Float) = 1.0
}
SubShader
{
Tags
{
"Queue"="Geometry"
"RenderType"="Opaque"
}
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
sampler2D _A_Tex;
sampler2D _B_Tex;
fixed _USE_TEX_A;
v2f vert(appdata_t v)
{
v2f OUT;
float4 vPosition = UnityObjectToClipPos(v.vertex);
OUT.vertex = vPosition;
OUT.texcoord = v.texcoord.xy;
return OUT;
}
fixed4 frag(v2f IN) : SV_Target
{
return _USE_TEX_A == 1.0 ? tex2D(_A_Tex, IN.texcoord) : tex2D(_B_Tex, IN.texcoord);
}
ENDCG
}
}
}
graphics analyzer 中的 TestingIf4Sample.glsl
VS
#version 320 es
precision highp float;
precision highp int;
#define HLSLCC_ENABLE_UNIFORM_BUFFERS 1
#if HLSLCC_ENABLE_UNIFORM_BUFFERS
#define UNITY_UNIFORM
#else
#define UNITY_UNIFORM uniform
#endif
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
uniform mediump float _USE_TEX_A;
UNITY_LOCATION(0) uniform mediump sampler2D _A_Tex;
UNITY_LOCATION(1) uniform mediump sampler2D _B_Tex;
in highp vec2 vs_TEXCOORD0;
layout(location = 0) out mediump vec4 SV_Target0;
vec4 u_xlat0;
bool u_xlatb0;
vec4 u_xlat1;
vec4 u_xlat2;
void main()
{
#ifdef UNITY_ADRENO_ES3
u_xlatb0 = !!(_USE_TEX_A==1.0);
#else
u_xlatb0 = _USE_TEX_A==1.0;
#endif
u_xlat1 = texture(_A_Tex, vs_TEXCOORD0.xy);
u_xlat2 = texture(_B_Tex, vs_TEXCOORD0.xy);
u_xlat0 = (bool(u_xlatb0)) ? u_xlat1 : u_xlat2;
SV_Target0 = u_xlat0;
return;
}
FS
#version 320 es
precision highp float;
precision highp int;
#define HLSLCC_ENABLE_UNIFORM_BUFFERS 1
#if HLSLCC_ENABLE_UNIFORM_BUFFERS
#define UNITY_UNIFORM
#else
#define UNITY_UNIFORM uniform
#endif
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
uniform mediump float _USE_TEX_A;
UNITY_LOCATION(0) uniform mediump sampler2D _A_Tex;
UNITY_LOCATION(1) uniform mediump sampler2D _B_Tex;
in highp vec2 vs_TEXCOORD0;
layout(location = 0) out mediump vec4 SV_Target0;
vec4 u_xlat0;
bool u_xlatb0;
vec4 u_xlat1;
vec4 u_xlat2;
void main()
{
#ifdef UNITY_ADRENO_ES3
u_xlatb0 = !!(_USE_TEX_A==1.0);
#else
u_xlatb0 = _USE_TEX_A==1.0;
#endif
u_xlat1 = texture(_A_Tex, vs_TEXCOORD0.xy);
u_xlat2 = texture(_B_Tex, vs_TEXCOORD0.xy);
u_xlat0 = (bool(u_xlatb0)) ? u_xlat1 : u_xlat2;
SV_Target0 = u_xlat0;
return;
}
TestingKW4Sample
下面是 shaderlab 和 glsl
unity shaderlab 中的 TestingKW4Sample.shader
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "TestingKW4Sample"
{
Properties
{
_A_Tex ("A Texture", 2D) = "white" {}
_B_Tex ("B Texture", 2D) = "white" {}
[Toggle(_USE_TEX_A)]_USE_TEX_A ("Using Tex A", Float) = 1.0
}
SubShader
{
Tags
{
"Queue"="Geometry"
"RenderType"="Opaque"
}
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ _USE_TEX_A
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
sampler2D _A_Tex;
sampler2D _B_Tex;
v2f vert(appdata_t v)
{
v2f OUT;
float4 vPosition = UnityObjectToClipPos(v.vertex);
OUT.vertex = vPosition;
OUT.texcoord = v.texcoord.xy;
return OUT;
}
fixed4 frag(v2f IN) : SV_Target
{
#ifdef _USE_TEX_A
return tex2D(_A_Tex, IN.texcoord);
#else
return tex2D(_B_Tex, IN.texcoord);
#endif
}
ENDCG
}
}
}
graphics analyzer 中的 TestingKW4Sample.glsl
VS: 和上面的一样,就不复制上来的
主要看 FS:
#version 320 es
precision highp float;
precision highp int;
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
UNITY_LOCATION(0) uniform mediump sampler2D _A_Tex;
in highp vec2 vs_TEXCOORD0;
layout(location = 0) out mediump vec4 SV_Target0;
mediump vec4 u_xlat16_0;
void main()
{
u_xlat16_0 = texture(_A_Tex, vs_TEXCOORD0.xy);
SV_Target0 = u_xlat16_0;
return;
}
比较
if 是指令实打实存在的
kw 原理是 macro 的 define,是在预编辑级别的分支,因此指令少一些也很正常
if 的推荐使用 记得是 if … else … 中 cycles 在 < 4 cycles 的,可以使用 if
否则还是使用 kw 的写法
下面的示例是 texture 的 sample,也就是 T unit 的采样
我印象中记得: (到时我再补回来,或是看到的大佬可以指导一下、分享一下资料)
- register op: 1 cycles
- sfu : 4~6 (忘记了)
- texture sample : 300+ cyles
因此 T unit 优化是非常有必要的