Search Unity

How to use our shader after slicing an UI image

Discussion in 'Shaders' started by ddadkhah, Mar 20, 2022.

  1. ddadkhah

    ddadkhah

    Joined:
    Nov 6, 2017
    Posts:
    59
    I am a beginner to shader programming in Unity.
    I wrote a shader to create gradient color on ui images. But when I set image type on sliced and set "Pixels per unit multiplier" to a different number, I don't get the result I expected.
    It seems my shader comes to work before image slicing happens. And it makes all the pixels at the center to have the same color (I want to all the pixels to be gradient. in other word I want all of them to participate in gradient process). Is there any way to render the image using my shader after slicing is happened?
    I hope I was able to transfer my meaning well (My English is not good enough).


    And this is my fragment shader code:
    Code (CSharp):
    1.  fixed4 frag (v2f i) : SV_Target
    2.             {
    3.                 // sample the texture
    4.                 fixed4 tcol = tex2D(_MainTex, i.uv);
    5.                 float4 res =float4(0,0,0,0);
    6.                 //distance from each of 4 points
    7.                 float d1 = clamp(distance(i.uv,_Point1.xy),0,1);
    8.                 float d2 = clamp(distance(i.uv,_Point1.zw),0,1);
    9.                 float d3 = clamp(distance(i.uv,_Point2.xy),0,1);
    10.                 float d4 = clamp(distance(i.uv,_Point2.zw),0,1);
    11.                
    12.                 res += (1- d1) * _Color1;
    13.                 res += (1- d2) * _Color2;
    14.                 res += (1- d3) * _Color3;
    15.                 res += (1- d4) * _Color4;
    16.  
    17.                 res.w =tcol.w;
    18.                
    19.                 // apply fog
    20.                 //UNITY_APPLY_FOG(i.fogCoord, res);
    21.                 return res;
    22.             }
     
    Epsilon_Delta likes this.
  2. ddadkhah

    ddadkhah

    Joined:
    Nov 6, 2017
    Posts:
    59
    Nobody has any idea about how I can create gradient using shaders for slices images?
     
  3. ddadkhah

    ddadkhah

    Joined:
    Nov 6, 2017
    Posts:
    59
    Nobody has any idea? please,
     
  4. Crokett

    Crokett

    Joined:
    May 14, 2021
    Posts:
    48
    Did you find any solution? I have a similar problem
     
  5. ddadkhah

    ddadkhah

    Joined:
    Nov 6, 2017
    Posts:
    59
    No, not yet
     
  6. ddadkhah

    ddadkhah

    Joined:
    Nov 6, 2017
    Posts:
    59
    No body has any idea about this?
     
  7. ddadkhah

    ddadkhah

    Joined:
    Nov 6, 2017
    Posts:
    59
    Hi,
    I want to bring this up if anyone have any ideas about it.
     
  8. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    Your shader *is* running after slicing happens, but the problem is you're relying on UV positions to do the gradient. To support slicing without shaders needing to have custom code for it, Unity is simply manipulating the UV points of the mesh used to render the graphic, to create the effect. And the center of that sliced mesh takes up just a point in the UV space, causing it to be filled with the graphic color at that point.

    Instead of using the UV in your distance calculation, just use the object-space vertex position. And Point1 and Point2 should then be the corners of your graphic in object space. (technically you only need 1 float4. Store top-left corner XY, bottom-right ZW, and that's all the information you need to derive the top-right and bottom-left values.)
     
    irenjie likes this.
  9. ddadkhah

    ddadkhah

    Joined:
    Nov 6, 2017
    Posts:
    59
    Could please give me a tip on how I can achieve that?
    This is my whole shader code:
    Code (CSharp):
    1. Shader "Hokm/Gradient"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.  
    7.         _Point1 ("Point 1",vector) = (1,1,1,1)
    8.         _Point2 ("Point 2",vector) = (1,1,1,1)
    9.  
    10.         _Color1 ("Color 1",Color) = (1,1,1,1)
    11.         _Color2 ("Color 2",Color) = (1,1,1,1)
    12.         _Color3 ("Color 3",Color) = (1,1,1,1)
    13.         _Color4 ("Color 4",Color) = (1,1,1,1)
    14.     }
    15.     SubShader
    16.     {
    17.         Tags {"Queue" = "Transparent" "RenderType" = "Transparent" "IGNOREPROJECTOR"="true"}
    18.         LOD 100
    19.  
    20.         Pass
    21.         {
    22.             Blend SrcAlpha OneMinusSrcAlpha
    23.  
    24.             CGPROGRAM
    25.             #pragma vertex vert
    26.             #pragma fragment frag
    27.             // make fog work
    28.             #pragma multi_compile_fog
    29.  
    30.             #include "UnityCG.cginc"
    31.  
    32.             struct appdata
    33.             {
    34.                 float4 vertex : POSITION;
    35.                 float2 uv : TEXCOORD0;
    36.                 float4 color    : COLOR;
    37.             };
    38.  
    39.             struct v2f
    40.             {
    41.                 float2 uv : TEXCOORD0;
    42.                 UNITY_FOG_COORDS(1)
    43.                 float4 vertex : SV_POSITION;
    44.             };
    45.  
    46.             sampler2D _MainTex;
    47.             float4 _MainTex_ST;
    48.             float4 _Point1;
    49.             float4 _Point2;
    50.             float4 _Color1;
    51.             float4 _Color2;
    52.             float4 _Color3;
    53.             float4 _Color4;
    54.  
    55.             v2f vert (appdata v)
    56.             {
    57.                 v2f o;
    58.                 o.vertex = UnityObjectToClipPos(v.vertex);
    59.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);    
    60.                 UNITY_TRANSFER_FOG(o,o.vertex);
    61.                 return o;
    62.             }
    63.  
    64.             fixed4 frag (v2f i) : SV_Target
    65.             {
    66.                 // sample the texture
    67.                 fixed4 tcol = tex2D(_MainTex, i.uv);
    68.                 float4 res =float4(0,0,0,0);
    69.                 float d1 = clamp(distance(i.uv,_Point1.xy),0,1);
    70.                 float d2 = clamp(distance(i.uv,_Point1.zw),0,1);
    71.                 float d3 = clamp(distance(i.uv,_Point2.xy),0,1);
    72.                 float d4 = clamp(distance(i.uv,_Point2.zw),0,1);
    73.              
    74.                 res += (1- d1) * _Color1;
    75.                 res += (1- d2) * _Color2;
    76.                 res += (1- d3) * _Color3;
    77.                 res += (1- d4) * _Color4;
    78.              
    79.                
    80.  
    81.                 res.w =tcol.w;
    82.              
    83.                 // apply fog
    84.                 //UNITY_APPLY_FOG(i.fogCoord, res);
    85.                 return res;
    86.             }
    87.             ENDCG
    88.         }
    89.     }
    90.      Fallback "UI/Default"
    91. }
    92.  
     
  10. mauriciofelippe

    mauriciofelippe

    Joined:
    Aug 9, 2017
    Posts:
    28
    I found a solution today, put my shader(add the stencil things on yours and can be good to go too) on a image object without sprite, make it child sliced image without shader but with mask, disable show mask graph.

    upload_2022-12-24_12-37-13.png

    Code (CSharp):
    1. Shader "0MF/Ui4"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.        
    7.         _TopLeft ("Top Left", Color) = (1,1,1,1)
    8.         _TopRight ("Top Right", Color) = (1,1,1,1)
    9.         _BottonLeft ("Botton Left", Color) = (1,1,1,1)
    10.         _BottonRight ("Botton Right", Color) = (1,1,1,1)
    11.         _Stencil ("Stencil ID", Float) = 0
    12.         _StencilOp ("Stencil Operation", Float) = 0
    13.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    14.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    15.         _StencilComp ("Stencil Comparison", Float) = 8
    16.         _ColorMask ("Color Mask", Float) = 15
    17.        
    18.        
    19.     }
    20.     SubShader
    21.     {
    22.         // No culling or depth
    23.         Cull Off ZWrite Off ZTest Always
    24.        
    25.         Blend SrcAlpha OneMinusSrcAlpha
    26.  
    27.          Tags {"Queue" = "Transparent" "RenderType" = "Transparent"}
    28.        
    29.         Stencil
    30.         {
    31.             Ref [_Stencil]
    32.             Comp [_StencilComp]
    33.             Pass [_StencilOp]
    34.             ReadMask [_StencilReadMask]
    35.             WriteMask [_StencilWriteMask]
    36.         }
    37.        
    38.         Pass
    39.         {
    40.             CGPROGRAM
    41.             #pragma vertex vert
    42.             #pragma fragment frag
    43.  
    44.             #include "UnityCG.cginc"
    45.  
    46.             struct appdata
    47.             {
    48.                 float4 vertex : POSITION;
    49.                 float2 uv : TEXCOORD0;
    50.             };
    51.  
    52.             struct v2f
    53.             {
    54.                 float2 uv : TEXCOORD0;
    55.                 float4 vertex : SV_POSITION;
    56.             };
    57.  
    58.             v2f vert (appdata v)
    59.             {
    60.                 v2f o;
    61.                 o.vertex = UnityObjectToClipPos(v.vertex);
    62.                 o.uv = v.uv;
    63.                 return o;
    64.             }
    65.  
    66.             uniform float4 _TopLeft;
    67.             uniform float4 _TopRight;
    68.             uniform float4 _BottonLeft;
    69.             uniform float4 _BottonRight;
    70.             sampler2D _MainTex;
    71.  
    72.             fixed4 frag (v2f i) : COLOR
    73.             {
    74.                 fixed4 col = tex2D(_MainTex, i.uv);
    75.                
    76.                 fixed4 topLeft = smoothstep(0,1,i.uv.x);
    77.                 fixed4 topRight = smoothstep(0,1,i.uv.x-1);
    78.  
    79.                 fixed4 bottonLeft = smoothstep(0,1,i.uv.x);
    80.                 fixed4 bottonRight = smoothstep(0,1,i.uv.x-1);
    81.  
    82.                 fixed4 top = smoothstep(0,1,i.uv.y);
    83.                 fixed4 botton = smoothstep(0,1,i.uv.y-1);
    84.  
    85.                 fixed4 topper = lerp(_TopLeft,_TopRight, topLeft+topRight);
    86.  
    87.                 fixed4 botter = lerp(_BottonLeft,_BottonRight, bottonLeft+bottonRight);
    88.  
    89.                 fixed4 screen = lerp(botter,topper,botton+top);
    90.                
    91.                 return  screen*col;
    92.             }
    93.             ENDCG
    94.         }
    95.     }
    96. }
    97.