Search Unity

Resolved Custom UI shader looks glitchy when under certain conditions (too long to put in post title)

Discussion in 'UGUI & TextMesh Pro' started by HunterAhlquist, Jun 5, 2023.

  1. HunterAhlquist

    HunterAhlquist

    Joined:
    Oct 6, 2013
    Posts:
    132
    Hi I encountered a strange graphical bug with Screen Space - Overlay for my custom UI Image shader.
    I set my player to become a child of an object it's standing on so that it moves with it when the parent object is moved. Under my player is my UI canvas, which uses screen space - overlay. Whenever my player is on a moving object, I get graphical glitches on custom transparent effects like this. It changes every frame the object is moved.
    upload_2023-6-5_12-39-1.png
    In this example I use a custom UI which essentially is just a grab pass blur. This doesn't appear when using Screen Space - Camera, but I'm too far along in my project to make a big change like that because it relies on overlay coordinates.

    Here's the code:
    Code (CSharp):
    1. Shader "Ahlquist Interactive/SimpleGrabPassBlur" {
    2.     Properties{
    3.         _Color("Main Color", Color) = (1,1,1,1)
    4.         _BumpAmt("Distortion", Range(0,128)) = 10
    5.         _MainTex("Tint Color (RGB)", 2D) = "white" {}
    6.         _BumpMap("Normalmap", 2D) = "bump" {}
    7.         _Size("Size", Range(0, 50)) = 1
    8.     }
    9.  
    10.         Category{
    11.  
    12.             // We must be transparent, so other objects are drawn before this one.
    13.             Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }
    14.             Cull Off
    15.  
    16.             SubShader {
    17.  
    18.             // Horizontal blur
    19.             GrabPass {
    20.                 Tags { "LightMode" = "Always" }
    21.             }
    22.             Pass {
    23.                 Tags { "LightMode" = "Always" }
    24.  
    25.                 CGPROGRAM
    26.                 #pragma vertex vert
    27.                 #pragma fragment frag
    28.                 #pragma fragmentoption ARB_precision_hint_fastest
    29.              
    30.                 #include "UnityCG.cginc"
    31.  
    32.                 struct appdata_t {
    33.                     float4 vertex : POSITION;
    34.                     float2 texcoord: TEXCOORD0;
    35.                 };
    36.  
    37.                 struct v2f {
    38.                     float4 vertex : POSITION;
    39.                     float4 uvgrab : TEXCOORD0;
    40.                  
    41.                 };
    42.  
    43.                 v2f vert(appdata_t v) {
    44.                     v2f o;
    45.                     o.vertex = UnityObjectToClipPos(v.vertex);
    46.                     #if UNITY_UV_STARTS_AT_TOP
    47.                     float scale = -1.0;
    48.                     #else
    49.                     float scale = 1.0;
    50.                     #endif
    51.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    52.                     o.uvgrab.zw = o.vertex.zw;
    53.                  
    54.                     return o;
    55.                 }
    56.  
    57.                 sampler2D _GrabTexture;
    58.                 float4 _GrabTexture_TexelSize;
    59.                 float _Size;
    60.  
    61.                 half4 frag(v2f i) : COLOR {
    62.                     //                  half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    63.                     //                  return col;
    64.  
    65.                                         half4 sum = half4(0,0,0,0);
    66.  
    67.                                         #define GRABPIXEL(weight,kernelx) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx*_Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight
    68.  
    69.                                         sum += GRABPIXEL(0.05, -4.0);
    70.                                         sum += GRABPIXEL(0.09, -3.0);
    71.                                         sum += GRABPIXEL(0.12, -2.0);
    72.                                         sum += GRABPIXEL(0.15, -1.0);
    73.                                         sum += GRABPIXEL(0.18,  0.0);
    74.                                         sum += GRABPIXEL(0.15, +1.0);
    75.                                         sum += GRABPIXEL(0.12, +2.0);
    76.                                         sum += GRABPIXEL(0.09, +3.0);
    77.                                         sum += GRABPIXEL(0.05, +4.0);
    78.  
    79.                                         return sum;
    80.                                     }
    81.                                     ENDCG
    82.                                 }
    83.  
    84.             // Vertical blur
    85.             GrabPass {
    86.                 Tags { "LightMode" = "Always" }
    87.             }
    88.             Pass {
    89.                 Tags { "LightMode" = "Always" }
    90.  
    91.                 CGPROGRAM
    92.                 #pragma vertex vert
    93.                 #pragma fragment frag
    94.                 #pragma fragmentoption ARB_precision_hint_fastest
    95.                 #include "UnityCG.cginc"
    96.              
    97.                 struct appdata_t {
    98.                     float4 vertex : POSITION;
    99.                     float2 texcoord: TEXCOORD0;
    100.                 };
    101.  
    102.                 struct v2f {
    103.                     float4 vertex : POSITION;
    104.                     float4 uvgrab : TEXCOORD0;
    105.                  
    106.                 };
    107.  
    108.                 v2f vert(appdata_t v) {
    109.                     v2f o;
    110.                     o.vertex = UnityObjectToClipPos(v.vertex);
    111.                     #if UNITY_UV_STARTS_AT_TOP
    112.                     float scale = -1.0;
    113.                     #else
    114.                     float scale = 1.0;
    115.                     #endif
    116.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    117.                     o.uvgrab.zw = o.vertex.zw;
    118.                  
    119.                     return o;
    120.                 }
    121.  
    122.                 sampler2D _GrabTexture;
    123.                 float4 _GrabTexture_TexelSize;
    124.                 float _Size;
    125.  
    126.                 half4 frag(v2f i) : COLOR {
    127.                     //                  half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    128.                     //                  return col;
    129.  
    130.                                         half4 sum = half4(0,0,0,0);
    131.  
    132.                                         #define GRABPIXEL(weight,kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely*_Size, i.uvgrab.z, i.uvgrab.w))) * weight
    133.  
    134.                                         //G(X) = (1/(sqrt(2*PI*deviation*deviation))) * exp(-(x*x / (2*deviation*deviation)))
    135.  
    136.                                         sum += GRABPIXEL(0.05, -4.0);
    137.                                         sum += GRABPIXEL(0.09, -3.0);
    138.                                         sum += GRABPIXEL(0.12, -2.0);
    139.                                         sum += GRABPIXEL(0.15, -1.0);
    140.                                         sum += GRABPIXEL(0.18,  0.0);
    141.                                         sum += GRABPIXEL(0.15, +1.0);
    142.                                         sum += GRABPIXEL(0.12, +2.0);
    143.                                         sum += GRABPIXEL(0.09, +3.0);
    144.                                         sum += GRABPIXEL(0.05, +4.0);
    145.  
    146.                                         return sum;
    147.                                     }
    148.                                     ENDCG
    149.                                 }
    150.  
    151.                                         // Distortion
    152.                                         GrabPass {
    153.                                             Tags { "LightMode" = "Always" }
    154.                                         }
    155.                                         Pass {
    156.                                             Tags { "LightMode" = "Always" }
    157.  
    158.                                             CGPROGRAM
    159.                                             #pragma vertex vert
    160.                                             #pragma fragment frag
    161.                                             #pragma fragmentoption ARB_precision_hint_fastest
    162.                                             #pragma debug
    163.                                             #include "UnityCG.cginc"
    164.  
    165.                                             struct appdata_t {
    166.                                                 float4 vertex : POSITION;
    167.                                                 float2 texcoord: TEXCOORD0;
    168.  
    169.                                             };
    170.  
    171.                                             struct v2f {
    172.                                                 float4 vertex : POSITION;
    173.                                                 float4 uvgrab : TEXCOORD0;
    174.                                                 float2 uvbump : TEXCOORD1;
    175.                                                 float2 uvmain : TEXCOORD2;
    176.                                             };
    177.  
    178.                                             float _BumpAmt;
    179.                                             float4 _BumpMap_ST;
    180.                                             float4 _MainTex_ST;
    181.  
    182.                                             v2f vert(appdata_t v) {
    183.                                                 v2f o;
    184.                                              
    185.                                                 o.vertex = UnityObjectToClipPos(v.vertex);
    186.                                                 #if UNITY_UV_STARTS_AT_TOP
    187.                                                 float scale = -1.0;
    188.                                                 #else
    189.                                                 float scale = 1.0;
    190.                                                 #endif
    191.                                                 o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    192.                                                 o.uvgrab.zw = o.vertex.zw;
    193.                                                 o.uvbump = TRANSFORM_TEX(v.texcoord, _BumpMap);
    194.                                                 o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
    195.                                              
    196.                                                 return o;
    197.                                             }
    198.  
    199.                                             fixed4 _Color;
    200.                                             sampler2D _GrabTexture;
    201.                                             float4 _GrabTexture_TexelSize;
    202.                                             sampler2D _BumpMap;
    203.                                             sampler2D _MainTex;
    204.  
    205.                                             half4 frag(v2f i) : COLOR {
    206.                                                 // calculate perturbed coordinates
    207.                                                 half2 bump = UnpackNormal(tex2D(_BumpMap, i.uvbump)).rg; // we could optimize this by just reading the x  y without reconstructing the Z
    208.                                                 float2 offset = bump * _BumpAmt * _GrabTexture_TexelSize.xy;
    209.                                                 i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    210.  
    211.                                                 half4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    212.                                                 half4 tint = tex2D(_MainTex, i.uvmain) * _Color;
    213.  
    214.                                                 return col * tint;
    215.                                             }
    216.                                             ENDCG
    217.                                         }
    218.                                     }
    219.         }
    220. }
    Anyone can identify what might cause a graphical glitch like this? Thank you

    and I'm sorry if this isn't the right board, not sure if it's actually 100% shader or UGui related...
     
  2. HunterAhlquist

    HunterAhlquist

    Joined:
    Oct 6, 2013
    Posts:
    132
    So I implemented some of the UI code seen in the default sprite shader such as stencil support, and I've found my shader is missing a lot of it. After making it compatible, the problem went away. Specifically
     ZTest [unity_GUIZTestMode] 
    near the culling settings is what fixed it.
    Full edited code:
    Code (CSharp):
    1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    2.  
    3. Shader "Ahlquist Interactive/UI/SimpleGrabPassBlur" {
    4.     Properties{
    5.         _Color("Main Color", Color) = (1,1,1,1)
    6.         _BumpAmt("Distortion", Range(0,128)) = 10
    7.         _MainTex("Tint Color (RGB)", 2D) = "white" {}
    8.         _BumpMap("Normalmap", 2D) = "bump" {}
    9.         _Size("Size", Range(0, 50)) = 1
    10.        
    11.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    12.  
    13.         [HideInInspector]_StencilComp ("Stencil Comparison", Float) = 8
    14.         [HideInInspector]_Stencil ("Stencil ID", Float) = 0
    15.         [HideInInspector]_StencilOp ("Stencil Operation", Float) = 0
    16.         [HideInInspector]_StencilWriteMask ("Stencil Write Mask", Float) = 255
    17.         [HideInInspector]_StencilReadMask ("Stencil Read Mask", Float) = 255
    18.  
    19.         [HideInInspector]_ColorMask ("Color Mask", Float) = 15
    20.  
    21.         [HideInInspector][Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    22.     }
    23.  
    24.         Category{
    25.  
    26.             // We must be transparent, so other objects are drawn before this one.
    27.             Tags {
    28.                 "Queue"="Transparent"
    29.                 "IgnoreProjector"="True"
    30.                 "RenderType"="Transparent"
    31.                 "PreviewType"="Plane"
    32.                 "CanUseSpriteAtlas"="True"
    33.             }
    34.             Stencil {
    35.                 Ref [_Stencil]
    36.                 Comp [_StencilComp]
    37.                 Pass [_StencilOp]
    38.                 ReadMask [_StencilReadMask]
    39.                 WriteMask [_StencilWriteMask]
    40.             }
    41.             Cull Off
    42.             Lighting Off
    43.             ZWrite Off
    44.             ZTest [unity_GUIZTestMode]
    45.             Blend SrcAlpha OneMinusSrcAlpha
    46.             ColorMask [_ColorMask]
    47.  
    48.             SubShader {
    49.  
    50.             // Horizontal blur
    51.             GrabPass {
    52.                 Tags { "LightMode" = "Always" }
    53.             }
    54.             Pass {
    55.  
    56.                 CGPROGRAM
    57.                 #pragma vertex vert
    58.                 #pragma fragment frag
    59.                 #pragma fragmentoption ARB_precision_hint_fastest
    60.                
    61.                 #include "UnityCG.cginc"
    62.                 #include "UnityUI.cginc"
    63.  
    64.                 #pragma multi_compile_local _ UNITY_UI_CLIP_RECT
    65.                 #pragma multi_compile_local _ UNITY_UI_ALPHACLIP
    66.  
    67.                 struct appdata_t {
    68.                     float4 vertex : POSITION;
    69.                     float4 color    : COLOR;
    70.                     float2 texcoord: TEXCOORD0;
    71.                     //UNITY_VERTEX_INPUT_INSTANCE_ID
    72.                 };
    73.  
    74.                 struct v2f {
    75.                     float4 vertex   : SV_POSITION;
    76.                     fixed4 color    : COLOR;
    77.                     float2 texcoord  : TEXCOORD0;
    78.                     float4 worldPosition : TEXCOORD1;
    79.                     //UNITY_VERTEX_OUTPUT_STEREO
    80.                     float4 uvgrab : TEXCOORD2;
    81.                 };
    82.  
    83.                 v2f vert(appdata_t v) {
    84.                     v2f o;
    85.                     o.vertex = UnityObjectToClipPos(v.vertex);
    86.                     #if UNITY_UV_STARTS_AT_TOP
    87.                     float scale = -1.0;
    88.                     #else
    89.                     float scale = 1.0;
    90.                     #endif
    91.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    92.                     o.uvgrab.zw = o.vertex.zw;
    93.                    
    94.                     return o;
    95.                 }
    96.  
    97.                 sampler2D _GrabTexture;
    98.                 float4 _GrabTexture_TexelSize;
    99.                 float _Size;
    100.  
    101.                 half4 frag(v2f i) : COLOR {
    102.                     //                  half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    103.                     //                  return col;
    104.  
    105.                                         half4 sum = half4(0,0,0,0);
    106.  
    107.                                         #define GRABPIXEL(weight,kernelx) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx*_Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight
    108.  
    109.                                         sum += GRABPIXEL(0.05, -4.0);
    110.                                         sum += GRABPIXEL(0.09, -3.0);
    111.                                         sum += GRABPIXEL(0.12, -2.0);
    112.                                         sum += GRABPIXEL(0.15, -1.0);
    113.                                         sum += GRABPIXEL(0.18,  0.0);
    114.                                         sum += GRABPIXEL(0.15, +1.0);
    115.                                         sum += GRABPIXEL(0.12, +2.0);
    116.                                         sum += GRABPIXEL(0.09, +3.0);
    117.                                         sum += GRABPIXEL(0.05, +4.0);
    118.  
    119.                                         return sum;
    120.                                     }
    121.                                     ENDCG
    122.                                 }
    123.  
    124.             // Vertical blur
    125.             GrabPass {
    126.                 Tags { "LightMode" = "Always" }
    127.             }
    128.             Pass {
    129.                 Tags { "LightMode" = "Always" }
    130.  
    131.                 CGPROGRAM
    132.                 #pragma vertex vert
    133.                 #pragma fragment frag
    134.                 #pragma fragmentoption ARB_precision_hint_fastest
    135.                 #include "UnityCG.cginc"
    136.                
    137.                 struct appdata_t {
    138.                     float4 vertex : POSITION;
    139.                     float2 texcoord: TEXCOORD0;
    140.                 };
    141.  
    142.                 struct v2f {
    143.                     float4 vertex : POSITION;
    144.                     float4 uvgrab : TEXCOORD0;
    145.                    
    146.                 };
    147.  
    148.                 v2f vert(appdata_t v) {
    149.                     v2f o;
    150.                     o.vertex = UnityObjectToClipPos(v.vertex);
    151.                     #if UNITY_UV_STARTS_AT_TOP
    152.                     float scale = -1.0;
    153.                     #else
    154.                     float scale = 1.0;
    155.                     #endif
    156.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    157.                     o.uvgrab.zw = o.vertex.zw;
    158.                    
    159.                     return o;
    160.                 }
    161.  
    162.                 sampler2D _GrabTexture;
    163.                 float4 _GrabTexture_TexelSize;
    164.                 float _Size;
    165.  
    166.                 half4 frag(v2f i) : COLOR {
    167.                     //                  half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    168.                     //                  return col;
    169.  
    170.                                         half4 sum = half4(0,0,0,0);
    171.  
    172.                                         #define GRABPIXEL(weight,kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely*_Size, i.uvgrab.z, i.uvgrab.w))) * weight
    173.  
    174.                                         //G(X) = (1/(sqrt(2*PI*deviation*deviation))) * exp(-(x*x / (2*deviation*deviation)))
    175.  
    176.                                         sum += GRABPIXEL(0.05, -4.0);
    177.                                         sum += GRABPIXEL(0.09, -3.0);
    178.                                         sum += GRABPIXEL(0.12, -2.0);
    179.                                         sum += GRABPIXEL(0.15, -1.0);
    180.                                         sum += GRABPIXEL(0.18,  0.0);
    181.                                         sum += GRABPIXEL(0.15, +1.0);
    182.                                         sum += GRABPIXEL(0.12, +2.0);
    183.                                         sum += GRABPIXEL(0.09, +3.0);
    184.                                         sum += GRABPIXEL(0.05, +4.0);
    185.  
    186.                                         return sum;
    187.                                     }
    188.                                     ENDCG
    189.                                 }
    190.  
    191.                                         // Distortion
    192.                                         GrabPass {
    193.                                             Tags { "LightMode" = "Always" }
    194.                                         }
    195.                                         Pass {
    196.                                             Tags { "LightMode" = "Always" }
    197.  
    198.                                             CGPROGRAM
    199.                                             #pragma vertex vert
    200.                                             #pragma fragment frag
    201.                                             #pragma fragmentoption ARB_precision_hint_fastest
    202.                                             #pragma debug
    203.                                             #include "UnityCG.cginc"
    204.  
    205.                                             struct appdata_t {
    206.                                                 float4 vertex : POSITION;
    207.                                                 float2 texcoord: TEXCOORD0;
    208.  
    209.                                             };
    210.  
    211.                                             struct v2f {
    212.                                                 float4 vertex : POSITION;
    213.                                                 float4 uvgrab : TEXCOORD0;
    214.                                                 float2 uvbump : TEXCOORD1;
    215.                                                 float2 uvmain : TEXCOORD2;
    216.                                             };
    217.  
    218.                                             float _BumpAmt;
    219.                                             float4 _BumpMap_ST;
    220.                                             float4 _MainTex_ST;
    221.  
    222.                                             v2f vert(appdata_t v) {
    223.                                                 v2f o;
    224.                                                
    225.                                                 o.vertex = UnityObjectToClipPos(v.vertex);
    226.                                                 #if UNITY_UV_STARTS_AT_TOP
    227.                                                 float scale = -1.0;
    228.                                                 #else
    229.                                                 float scale = 1.0;
    230.                                                 #endif
    231.                                                 o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    232.                                                 o.uvgrab.zw = o.vertex.zw;
    233.                                                 o.uvbump = TRANSFORM_TEX(v.texcoord, _BumpMap);
    234.                                                 o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
    235.                                                
    236.                                                 return o;
    237.                                             }
    238.  
    239.                                             fixed4 _Color;
    240.                                             sampler2D _GrabTexture;
    241.                                             float4 _GrabTexture_TexelSize;
    242.                                             sampler2D _BumpMap;
    243.                                             sampler2D _MainTex;
    244.  
    245.                                             half4 frag(v2f i) : COLOR {
    246.                                                 // calculate perturbed coordinates
    247.                                                 half2 bump = UnpackNormal(tex2D(_BumpMap, i.uvbump)).rg; // we could optimize this by just reading the x  y without reconstructing the Z
    248.                                                 float2 offset = bump * _BumpAmt * _GrabTexture_TexelSize.xy;
    249.                                                 i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    250.  
    251.                                                 half4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    252.                                                 half4 tint = tex2D(_MainTex, i.uvmain) * _Color;
    253.  
    254.                                                 return col * tint;
    255.                                             }
    256.                                             ENDCG
    257.                                         }
    258.                                     }
    259.         }
    260. }