Search Unity

Sprite Shader: Cutoff to transparency

Discussion in 'Shaders' started by jelgh, Aug 26, 2018.

  1. jelgh

    jelgh

    Joined:
    Feb 15, 2014
    Posts:
    8
    Hello!

    I wanted to create the effect you can achieve with Unity UI's Image Type "Filled", but with a 2D Sprite. I found this video:
    and that helped me a great deal, but the creator there did not handle transparency. So I found Unity's Standard Sprite Shader (or at least what i believe is: https://github.com/nubick/unity-uti...Assets/Scripts/Shaders/Sprites-Default.shader), and tried to apply the cutoff technique there.

    I managed to get it half-working, but not fully. It works if the color of my Sprite is black, but not for other colors:

    Screen Shot 2018-08-26 at 22.41.38.png Screen Shot 2018-08-26 at 22.41.30.png

    Screen Shot 2018-08-26 at 22.40.17.png Screen Shot 2018-08-26 at 22.40.34.png


    I want the full transparency as with the black hex, but with any color. The base image is just a white hex. I don't understand where that half-transparent thing comes from!


    Here is the Shader i Created:

    Code (CSharp):
    1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    2.  
    3. Shader "Sprites/DefaultCutoff"
    4. {
    5.     Properties
    6.     {
    7.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    8.         _Color ("Tint", Color) = (1,1,1,1)
    9.         _TransitionTex("Transition Texture", 2D) = "white" {}
    10.         _Cutoff("Cutoff", Range(0, 1)) = 0
    11.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    12.     }
    13.  
    14.     SubShader
    15.     {
    16.         Tags
    17.         {
    18.             "Queue"="Transparent"
    19.             "IgnoreProjector"="True"
    20.             "RenderType"="Transparent"
    21.             "PreviewType"="Plane"
    22.             "CanUseSpriteAtlas"="True"
    23.         }
    24.  
    25.         Cull Off
    26.         Lighting Off
    27.         ZWrite Off
    28.         Blend One OneMinusSrcAlpha
    29.  
    30.         Pass
    31.         {
    32.         CGPROGRAM
    33.             #pragma vertex vert
    34.             #pragma fragment frag
    35.             #pragma multi_compile _ PIXELSNAP_ON
    36.             #include "UnityCG.cginc"
    37.          
    38.             struct appdata_t
    39.             {
    40.                 float4 vertex   : POSITION;
    41.                 float4 color    : COLOR;
    42.                 float2 texcoord : TEXCOORD0;
    43.             };
    44.  
    45.             struct v2f
    46.             {
    47.                 float4 vertex   : SV_POSITION;
    48.                 fixed4 color    : COLOR;
    49.                 float2 texcoord  : TEXCOORD0;
    50.             };
    51.          
    52.             fixed4 _Color;
    53.             float _Cutoff;
    54.             sampler2D _TransitionTex;
    55.  
    56.             v2f vert(appdata_t IN)
    57.             {
    58.                 v2f OUT;
    59.                 OUT.vertex = UnityObjectToClipPos(IN.vertex);
    60.                 OUT.texcoord = IN.texcoord;
    61.                 OUT.color = IN.color * _Color;
    62.                 #ifdef PIXELSNAP_ON
    63.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    64.                 #endif
    65.  
    66.                 return OUT;
    67.             }
    68.  
    69.             sampler2D _MainTex;
    70.             sampler2D _AlphaTex;
    71.             float _AlphaSplitEnabled;
    72.  
    73.             fixed4 SampleSpriteTexture (float2 uv)
    74.             {
    75.                 fixed4 color = tex2D (_MainTex, uv);
    76.  
    77. #if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
    78.                 if (_AlphaSplitEnabled)
    79.                     color.a = tex2D (_AlphaTex, uv).r;
    80. #endif //UNITY_TEXTURE_ALPHASPLIT_ALLOWED
    81.  
    82.                 return color;
    83.             }
    84.  
    85.             fixed4 frag(v2f IN) : SV_Target
    86.             {
    87.                 fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
    88.                 c.rgb *= c.a;
    89.  
    90.                 fixed4 transit = tex2D(_TransitionTex, IN.texcoord);
    91.                 if (transit.b > _Cutoff)
    92.                     c.a = 0;
    93.                  
    94.                 return c;
    95.             }
    96.         ENDCG
    97.         }
    98.     }
    99. }

    I'm also very new to Shaders so I might be doing some very basic mistake here...

    Thanks for your help!
    Best,
    Johannes
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    Right now your object will never be transparent because of this:
    Blend One OneMinusSrcAlpha


    If you want transparency, use this instead:
    Blend SrcAlpha OneMinusSrcAlpha



    In your fragment function, you are darkening your pixels based on how transparent they should be.
    c.rgb *= c.a;


    This is not a bad idea, but I don't like to do this until I'm done adjusting alpha. I think the above code should come after this code:
    if (transit.b > _Cutoff) c.a = 0;



    Good luck!
     
    Voodoomedia and jelgh like this.
  3. jelgh

    jelgh

    Joined:
    Feb 15, 2014
    Posts:
    8
    Thanks a lot mate!

    The
    Blend SrcAlpha OneMinusSrcAlpha
    solved it!