介绍
突然好奇如果在Shader里对同一纹理多次采样是否会影响性能,所以简单进行了测试
结论
先说下结论在Shader里对同一纹理多次采样不会影响性能,前提是只要是uv相同的贴图采样,surface和vertex frag编译之后都会优化掉多余的采样次数。
流程
无实际意义,只是为了测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| fixed4 frag (v2f i) : SV_Target { fixed col = tex2D(_MainTex, i.uv).r; fixed col2 = tex2D(_MainTex, i.uv).g; fixed col3 = tex2D(_MainTex, i.uv).b; fixed col4 = tex2D(_MainTex, i.uv).a; fixed2 col5 = tex2D(_MainTex, i.uv).rg; fixed2 col6 = tex2D(_MainTex, i.uv).rb;
fixed4 final_color = col.rrrr + col2.rrrr + col3.rrrr + col4.rrrr + col5.rgrg + col6.rgrg; return final_color; }
|
选择为OpenGLES 然后Compile

局部编译后代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #ifdef FRAGMENT #version 300 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 _MainTex; in highp vec2 vs_TEXCOORD0; layout(location = 0) out mediump vec4 SV_Target0; mediump vec4 u_xlat16_0; mediump vec4 u_xlat16_1; void main() { u_xlat16_0 = texture(_MainTex, vs_TEXCOORD0.xy); u_xlat16_1.x = u_xlat16_0.y + u_xlat16_0.x; u_xlat16_1.x = u_xlat16_0.z + u_xlat16_1.x; u_xlat16_1.x = u_xlat16_0.w + u_xlat16_1.x; u_xlat16_1 = u_xlat16_0.xyxy + u_xlat16_1.xxxx; SV_Target0 = u_xlat16_0.xzxz + u_xlat16_1; return; }
#endif
|
可以看到编译后的代码只有一次采样,其他的采样都被优化掉了
如果任意修改其中的一个采样UV
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| fixed4 frag (v2f i) : SV_Target { fixed col = tex2D(_MainTex, i.uv + _Time.x * 10).r; fixed col2 = tex2D(_MainTex, i.uv).g; fixed col3 = tex2D(_MainTex, i.uv).b; fixed col4 = tex2D(_MainTex, i.uv).a; fixed2 col5 = tex2D(_MainTex, i.uv).rg; fixed2 col6 = tex2D(_MainTex, i.uv).rb;
fixed4 final_color = col.rrrr + col2.rrrr + col3.rrrr + col4.rrrr + col5.rgrg + col6.rgrg; return final_color; }
|
编译后的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #ifdef FRAGMENT #version 300 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 vec4 _Time; UNITY_LOCATION(0) uniform mediump sampler2D _MainTex; in highp vec2 vs_TEXCOORD0; layout(location = 0) out mediump vec4 SV_Target0; vec2 u_xlat0; mediump vec4 u_xlat16_0; mediump vec4 u_xlat16_1; mediump float u_xlat16_2; void main() { u_xlat0.xy = _Time.xx * vec2(10.0, 10.0) + vs_TEXCOORD0.xy; u_xlat16_0.x = texture(_MainTex, u_xlat0.xy).x; u_xlat16_1 = texture(_MainTex, vs_TEXCOORD0.xy); u_xlat16_2 = u_xlat16_0.x + u_xlat16_1.y; u_xlat16_2 = u_xlat16_1.z + u_xlat16_2; u_xlat16_2 = u_xlat16_1.w + u_xlat16_2; u_xlat16_0 = u_xlat16_1.xyxy + vec4(u_xlat16_2); SV_Target0 = u_xlat16_1.xzxz + u_xlat16_0; return; }
#endif
|
可以看到编译后的代码有两次采样,其中一次采样的UV是修改后的,另一次采样的UV是原来的UV,这样就会导致两次采样的结果不一样,所以编译器就不会优化掉其中的一次采样。