Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

When do _UseClipRect and _UseAlphaClip work in UI-Default.shader of newGUI?

Discussion in 'UGUI & TextMesh Pro' started by dhkd1157-dalcom, Oct 27, 2015.

  1. dhkd1157-dalcom

    dhkd1157-dalcom

    Joined:
    Apr 16, 2014
    Posts:
    12
    This is the code for "DefaultResourcesExtra/UI/UI-Default.shader" which is part of the Unity built-in shader that is most frequently used in our project.
    Code (CSharp):
    1. Shader "UI/Default"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.      
    8.         _StencilComp ("Stencil Comparison", Float) = 8
    9.         _Stencil ("Stencil ID", Float) = 0
    10.         _StencilOp ("Stencil Operation", Float) = 0
    11.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    12.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    13.  
    14.         _ColorMask ("Color Mask", Float) = 15
    15.     }
    16.  
    17.     SubShader
    18.     {
    19.         Tags
    20.         {
    21.             "Queue"="Transparent"
    22.             "IgnoreProjector"="True"
    23.             "RenderType"="Transparent"
    24.             "PreviewType"="Plane"
    25.             "CanUseSpriteAtlas"="True"
    26.         }
    27.      
    28.         Stencil
    29.         {
    30.             Ref [_Stencil]
    31.             Comp [_StencilComp]
    32.             Pass [_StencilOp]
    33.             ReadMask [_StencilReadMask]
    34.             WriteMask [_StencilWriteMask]
    35.         }
    36.  
    37.         Cull Off
    38.         Lighting Off
    39.         ZWrite Off
    40.         ZTest [unity_GUIZTestMode]
    41.         Blend SrcAlpha OneMinusSrcAlpha
    42.         ColorMask [_ColorMask]
    43.  
    44.         Pass
    45.         {
    46.         CGPROGRAM
    47.             #pragma vertex vert
    48.             #pragma fragment frag
    49.  
    50.             #include "UnityCG.cginc"
    51.             #include "UnityUI.cginc"
    52.          
    53.             struct appdata_t
    54.             {
    55.                 float4 vertex   : POSITION;
    56.                 float4 color    : COLOR;
    57.                 float2 texcoord : TEXCOORD0;
    58.             };
    59.  
    60.             struct v2f
    61.             {
    62.                 float4 vertex   : SV_POSITION;
    63.                 fixed4 color    : COLOR;
    64.                 half2 texcoord  : TEXCOORD0;
    65.                 float4 worldPosition : TEXCOORD1;
    66.             };
    67.          
    68.             fixed4 _Color;
    69.             fixed4 _TextureSampleAdd;
    70.  
    71.             bool _UseClipRect;
    72.             float4 _ClipRect;
    73.  
    74.             bool _UseAlphaClip;
    75.  
    76.             v2f vert(appdata_t IN)
    77.             {
    78.                 v2f OUT;
    79.                 OUT.worldPosition = IN.vertex;
    80.                 OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
    81.  
    82.                 OUT.texcoord = IN.texcoord;
    83.              
    84.                 #ifdef UNITY_HALF_TEXEL_OFFSET
    85.                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
    86.                 #endif
    87.              
    88.                 OUT.color = IN.color * _Color;
    89.                 return OUT;
    90.             }
    91.  
    92.             sampler2D _MainTex;
    93.  
    94.             fixed4 frag(v2f IN) : SV_Target
    95.             {
    96.                 half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
    97.  
    98.                 if (_UseClipRect)
    99.                     color *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
    100.              
    101.                 if (_UseAlphaClip)
    102.                     clip (color.a - 0.001);
    103.  
    104.                 return color;
    105.             }
    106.         ENDCG
    107.         }
    108.     }
    109. }
    110.  

    We've changed the "frag" part of the code, and applied it to objects' Mask and ScrollRect.
    Since shader seems to worked the same in UnityEdior, we believe that UI/Mask uses a stencil feature.
    Code (CSharp):
    1.             fixed4 frag(v2f IN) : SV_Target
    2.             {
    3.                 half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
    4.                 return color;
    5.             }

    If so, we want to know when _UseClipRect and _UseAlphaClip properties work in shader code.
    Also, we believe that if "if statement" is used in pixel shader there might be a performance reduction with low-end mobile devices.
    Would using materials with custom build shader be the only solution to solve this problem?
     
  2. Stephan-B

    Stephan-B

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    _UseClipRect is used by the 2D Rect Mask and set to one when the 2D Rect Mask is enabled. The UI.Mask does in fact use the Stencil and does not use those two material properties.
     
    dhkd1157-dalcom likes this.
  3. dhkd1157-dalcom

    dhkd1157-dalcom

    Joined:
    Apr 16, 2014
    Posts:
    12
    Thank you for helping me out, Stephan B!
    I didn't know they added the 2DRectMask in Unity 5.2 until now. Thank you!
    If you don't mind, I've got a few more questions.
    Do you know how much it will affect the overall performance when fragment shader (pixel shader) is used in an "if statement" that does not work?
    I checked this just now, and it seems that Unity 5.1 does not have if statement with frag shader.
    Code (CSharp):
    1. Shader "UI/Default"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.      
    8.         _StencilComp ("Stencil Comparison", Float) = 8
    9.         _Stencil ("Stencil ID", Float) = 0
    10.         _StencilOp ("Stencil Operation", Float) = 0
    11.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    12.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    13.  
    14.         _ColorMask ("Color Mask", Float) = 15
    15.     }
    16.  
    17.     SubShader
    18.     {
    19.         Tags
    20.         {
    21.             "Queue"="Transparent"
    22.             "IgnoreProjector"="True"
    23.             "RenderType"="Transparent"
    24.             "PreviewType"="Plane"
    25.             "CanUseSpriteAtlas"="True"
    26.         }
    27.      
    28.         Stencil
    29.         {
    30.             Ref [_Stencil]
    31.             Comp [_StencilComp]
    32.             Pass [_StencilOp]
    33.             ReadMask [_StencilReadMask]
    34.             WriteMask [_StencilWriteMask]
    35.         }
    36.  
    37.         Cull Off
    38.         Lighting Off
    39.         ZWrite Off
    40.         ZTest [unity_GUIZTestMode]
    41.         Blend SrcAlpha OneMinusSrcAlpha
    42.         ColorMask [_ColorMask]
    43.  
    44.         Pass
    45.         {
    46.         CGPROGRAM
    47.             #pragma vertex vert
    48.             #pragma fragment frag
    49.             #include "UnityCG.cginc"
    50.          
    51.             struct appdata_t
    52.             {
    53.                 float4 vertex   : POSITION;
    54.                 float4 color    : COLOR;
    55.                 float2 texcoord : TEXCOORD0;
    56.             };
    57.  
    58.             struct v2f
    59.             {
    60.                 float4 vertex   : SV_POSITION;
    61.                 fixed4 color    : COLOR;
    62.                 half2 texcoord  : TEXCOORD0;
    63.             };
    64.          
    65.             fixed4 _Color;
    66.  
    67.             v2f vert(appdata_t IN)
    68.             {
    69.                 v2f OUT;
    70.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    71.                 OUT.texcoord = IN.texcoord;
    72. #ifdef UNITY_HALF_TEXEL_OFFSET
    73.                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
    74. #endif
    75.                 OUT.color = IN.color * _Color;
    76.                 return OUT;
    77.             }
    78.  
    79.             sampler2D _MainTex;
    80.  
    81.             fixed4 frag(v2f IN) : SV_Target
    82.             {
    83.                 half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
    84.                 clip (color.a - 0.01);
    85.                 return color;
    86.             }
    87.         ENDCG
    88.         }
    89.     }
    90. }
    91.  
    Does it have something to do with the Unity 5.2 performance upgrade that's discussed here?
    http://forum.unity3d.com/threads/ve...roid-after-upgrading-to-unity-5.306572/page-9
     
  4. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The linked thread is a huge collection of issues, ranging from user mistakes and misunderstandings to actual performance bugs. It is very likely that at least one of those many issues is the one you mentioned.
     
  5. dhkd1157-dalcom

    dhkd1157-dalcom

    Joined:
    Apr 16, 2014
    Posts:
    12
    Thanks you Dantus.
     
  6. dhkd1157-dalcom

    dhkd1157-dalcom

    Joined:
    Apr 16, 2014
    Posts:
    12
    Does anyone know how much it would affect the overall performance when "if statement" is used in a pixel shader?
    I am currently avoiding performance reduction by using custom materials.

    Is there any other way to avoid performance reduction?


    Modified shader code:
    Code (CSharp):
    1. Shader "Custom/UI/Default"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         _ColorMask ("Color Mask", Float) = 15
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue"="Transparent"
    15.             "IgnoreProjector"="True"
    16.             "RenderType"="Transparent"
    17.             "PreviewType"="Plane"
    18.             "CanUseSpriteAtlas"="True"
    19.         }
    20.         Cull Off
    21.         Lighting Off
    22.         ZWrite Off
    23.         ZTest [unity_GUIZTestMode]
    24.         Blend SrcAlpha OneMinusSrcAlpha
    25.         ColorMask [_ColorMask]
    26.  
    27.         Pass
    28.         {
    29.         CGPROGRAM
    30.             #pragma vertex vert
    31.             #pragma fragment frag
    32.  
    33.             #include "UnityCG.cginc"
    34.             #include "UnityUI.cginc"
    35.            
    36.             struct appdata_t
    37.             {
    38.                 float4 vertex   : POSITION;
    39.                 float4 color    : COLOR;
    40.                 float2 texcoord : TEXCOORD0;
    41.             };
    42.  
    43.             struct v2f
    44.             {
    45.                 float4 vertex   : SV_POSITION;
    46.                 fixed4 color    : COLOR;
    47.                 half2 texcoord  : TEXCOORD0;
    48.                 float4 worldPosition : TEXCOORD1;
    49.             };
    50.            
    51.             fixed4 _Color;
    52.             fixed4 _TextureSampleAdd;
    53.  
    54.             v2f vert(appdata_t IN)
    55.             {
    56.                 v2f OUT;
    57.                 OUT.worldPosition = IN.vertex;
    58.                 OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
    59.  
    60.                 OUT.texcoord = IN.texcoord;
    61.                
    62.                 #ifdef UNITY_HALF_TEXEL_OFFSET
    63.                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
    64.                 #endif
    65.                
    66.                 OUT.color = IN.color * _Color;
    67.                 return OUT;
    68.             }
    69.  
    70.             sampler2D _MainTex;
    71.  
    72.             fixed4 frag(v2f IN) : SV_Target
    73.             {
    74.                 return (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
    75.             }
    76.         ENDCG
    77.         }
    78.     }
    79. }
    80.  

    Shader for UI/Mask's objects:
    Code (CSharp):
    1. Shader "Custom/UI/Default-Stencil"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.        
    8.         _StencilComp ("Stencil Comparison", Float) = 8
    9.         _Stencil ("Stencil ID", Float) = 0
    10.         _StencilOp ("Stencil Operation", Float) = 0
    11.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    12.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    13.  
    14.         _ColorMask ("Color Mask", Float) = 15
    15.     }
    16.  
    17.     SubShader
    18.     {
    19.         Tags
    20.         {
    21.             "Queue"="Transparent"
    22.             "IgnoreProjector"="True"
    23.             "RenderType"="Transparent"
    24.             "PreviewType"="Plane"
    25.             "CanUseSpriteAtlas"="True"
    26.         }
    27.        
    28.         Stencil
    29.         {
    30.             Ref [_Stencil]
    31.             Comp [_StencilComp]
    32.             Pass [_StencilOp]
    33.             ReadMask [_StencilReadMask]
    34.             WriteMask [_StencilWriteMask]
    35.         }
    36.  
    37.         Cull Off
    38.         Lighting Off
    39.         ZWrite Off
    40.         ZTest [unity_GUIZTestMode]
    41.         Blend SrcAlpha OneMinusSrcAlpha
    42.         ColorMask [_ColorMask]
    43.  
    44.         Pass
    45.         {
    46.         CGPROGRAM
    47.             #pragma vertex vert
    48.             #pragma fragment frag
    49.  
    50.             #include "UnityCG.cginc"
    51.             #include "UnityUI.cginc"
    52.            
    53.             struct appdata_t
    54.             {
    55.                 float4 vertex   : POSITION;
    56.                 float4 color    : COLOR;
    57.                 float2 texcoord : TEXCOORD0;
    58.             };
    59.  
    60.             struct v2f
    61.             {
    62.                 float4 vertex   : SV_POSITION;
    63.                 fixed4 color    : COLOR;
    64.                 half2 texcoord  : TEXCOORD0;
    65.                 float4 worldPosition : TEXCOORD1;
    66.             };
    67.            
    68.             fixed4 _Color;
    69.             fixed4 _TextureSampleAdd;
    70.  
    71.             v2f vert(appdata_t IN)
    72.             {
    73.                 v2f OUT;
    74.                 OUT.worldPosition = IN.vertex;
    75.                 OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
    76.  
    77.                 OUT.texcoord = IN.texcoord;
    78.                
    79.                 #ifdef UNITY_HALF_TEXEL_OFFSET
    80.                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
    81.                 #endif
    82.                
    83.                 OUT.color = IN.color * _Color;
    84.                 return OUT;
    85.             }
    86.  
    87.             sampler2D _MainTex;
    88.  
    89.             fixed4 frag(v2f IN) : SV_Target
    90.             {
    91.                 return (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
    92.             }
    93.         ENDCG
    94.         }
    95.     }
    96. }
    97.  

    Shader for UI/2DRectMask's objects:
    Code (CSharp):
    1. Shader "Custom/UI/Default-2DRectClip"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         _ColorMask ("Color Mask", Float) = 15
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue"="Transparent"
    15.             "IgnoreProjector"="True"
    16.             "RenderType"="Transparent"
    17.             "PreviewType"="Plane"
    18.             "CanUseSpriteAtlas"="True"
    19.         }
    20.  
    21.         Cull Off
    22.         Lighting Off
    23.         ZWrite Off
    24.         ZTest [unity_GUIZTestMode]
    25.         Blend SrcAlpha OneMinusSrcAlpha
    26.         ColorMask [_ColorMask]
    27.  
    28.         Pass
    29.         {
    30.         CGPROGRAM
    31.             #pragma vertex vert
    32.             #pragma fragment frag
    33.  
    34.             #include "UnityCG.cginc"
    35.             #include "UnityUI.cginc"
    36.            
    37.             struct appdata_t
    38.             {
    39.                 float4 vertex   : POSITION;
    40.                 float4 color    : COLOR;
    41.                 float2 texcoord : TEXCOORD0;
    42.             };
    43.  
    44.             struct v2f
    45.             {
    46.                 float4 vertex   : SV_POSITION;
    47.                 fixed4 color    : COLOR;
    48.                 half2 texcoord  : TEXCOORD0;
    49.                 float4 worldPosition : TEXCOORD1;
    50.             };
    51.            
    52.             fixed4 _Color;
    53.             fixed4 _TextureSampleAdd;
    54.  
    55.             float4 _ClipRect;
    56.  
    57.             v2f vert(appdata_t IN)
    58.             {
    59.                 v2f OUT;
    60.                 OUT.worldPosition = IN.vertex;
    61.                 OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
    62.  
    63.                 OUT.texcoord = IN.texcoord;
    64.                
    65.                 #ifdef UNITY_HALF_TEXEL_OFFSET
    66.                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
    67.                 #endif
    68.                
    69.                 OUT.color = IN.color * _Color;
    70.                 return OUT;
    71.             }
    72.  
    73.             sampler2D _MainTex;
    74.  
    75.             half4 frag(v2f IN) : SV_Target
    76.             {
    77.                 return (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color * UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
    78.             }
    79.         ENDCG
    80.         }
    81.     }
    82. }

    Is defining each shader like the above the only way to optimize, and avoid performance reduction?
     
    lassade likes this.
  7. lassade

    lassade

    Joined:
    Jan 27, 2013
    Posts:
    127
    i dont think the "if statement" is the problem, maybe the code inside of it is the problem.

    In my game main menu i get 30 fps using the default ui shader, after using a custom shader much more simple i get up to 60fps. Even if there is any other way to improve peformance i think the custom shaders is the way to go.

    This Shader for UI/2DRectMask's objects that you wrote, improves the peformance? You tested it?
     
    ChiuanWei likes this.
  8. dhkd1157-dalcom

    dhkd1157-dalcom

    Joined:
    Apr 16, 2014
    Posts:
    12
    @lassade, thanks for the reply.
    I've used "Custom/UI/Default" shader and "Custom/UI/Default-Stencil" shader which I've posted above, and it has significantly improved the performance.
    (Though it has not been properly tested.) Also, I have not tested "Custom/UI/Default-2DRectClip". If you look at the UI Shader for the Unity 5.3 Beta release, you will find that they had stopped using the "if statement"