Search Unity

Problem With Cutout Shader - Unwanted Transparency

Discussion in 'Shaders' started by FGPArthurVII, Aug 11, 2017.

  1. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    Note that I am a total newbie in shader programmin, so I've been trying to study it.
    My intention on this script was to do, at least for now, a Shader that Accepts Tint Color and accepts an Albedo, for each 0 alpha areas on the Albedo, these would cut out from the rendering, this was supposed to be used on a character's cloathes. There goes the code:

    Code (CSharp):
    1. Shader "Custom/PBR Shader"
    2. {
    3.     Properties
    4.     {
    5.         _TintColor ("Colour Tint", color) = (1,1,1,1)
    6.         _MainTex ("Albedo", 2D) = "white" {}
    7.         _CutOff ("CutOff", Range(0,1)) = 0.5
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags {"Queue" = "Transparent" "RenderType" = "Opaque"}
    13.         cull off
    14.  
    15.         CGPROGRAM
    16.  
    17.         #pragma surface surf Lambert finalcolor:mycolor alpha
    18.  
    19.         struct Input
    20.         {
    21.             float2 uv_MainTex;
    22.         };
    23.  
    24.         fixed4 _TintColor;
    25.         void mycolor (Input IN, SurfaceOutput o,inout fixed4 color)
    26.         {
    27.             color *= _TintColor;
    28.         }
    29.  
    30.         sampler2D _MainTex;
    31.         float _CutOff;
    32.         void surf (Input IN, inout SurfaceOutput o)
    33.         {
    34.             float ca = tex2D(_MainTex, IN.uv_MainTex).a;
    35.             o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
    36.  
    37.             if (ca > _CutOff)
    38.                 o.Alpha = ca;
    39.             else
    40.                 o.Alpha = 0;
    41.         }
    42.  
    43.         ENDCG
    44.  
    45.     }
    46.     FallBack "Transparent/Diffuse"
    47. }
    48. Shader "Custom/PBR Shader"
    49. {
    50.     Properties
    51.     {
    52.         _TintColor ("Colour Tint", color) = (1,1,1,1)
    53.         _MainTex ("Albedo", 2D) = "white" {}
    54.         _CutOff ("CutOff", Range(0,1)) = 0.5
    55.     }
    56.  
    57.     SubShader
    58.     {
    59.         Tags {"Queue" = "Transparent" "RenderType" = "Opaque"}
    60.         cull off
    61.  
    62.         CGPROGRAM
    63.  
    64.         #pragma surface surf Lambert finalcolor:mycolor alpha
    65.  
    66.         struct Input
    67.         {
    68.             float2 uv_MainTex;
    69.         };
    70.  
    71.         fixed4 _TintColor;
    72.         void mycolor (Input IN, SurfaceOutput o,inout fixed4 color)
    73.         {
    74.             color *= _TintColor;
    75.         }
    76.  
    77.         sampler2D _MainTex;
    78.         float _CutOff;
    79.         void surf (Input IN, inout SurfaceOutput o)
    80.         {
    81.             float ca = tex2D(_MainTex, IN.uv_MainTex).a;
    82.             o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
    83.  
    84.             if (ca > _CutOff)
    85.                 o.Alpha = ca;
    86.             else
    87.                 o.Alpha = 0;
    88.         }
    89.  
    90.         ENDCG
    91.  
    92.     }
    93.     FallBack "Transparent/Diffuse"
    94. }
    But the problem is, even fully alpha areas (And I checked the texture plane and those are indeed with no transparency at all) seems a little transparent. And I can't figure out why. Does anyone know how to help me please? And If you have any optimization or performance advices on the code, please feel free to sugest.

    Thanks;
    Arthur
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    It sounds like you want an actual cutout shader then, not an alpha blend shader (which is what you're using).

    Instead of alpha in the #pragma surface line you want:
    alphatest:_Cutoff

    Then in the surf function just output your texture's alpha value, no need to have the if there.
     
  3. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    Tried it here... It indeed removed the unwanted transparency, although... the cutOut doesn't work anymore: the transparency of the texture image is not being recognized anymoro.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    There's a terminology issue here. "Cutout" is a hard edge transparency, either on or off. You want alpha blended transparency in addition to hiding areas of full transparency.

    https://docs.unity3d.com/Manual/SL-Blend.html

    You probably want to use a combination of alpha test and alpha blend then, for which you can recreate alpha test in the surf function.

    https://docs.unity3d.com/Manual/SL-SurfaceShaders.html

    Set the alpha in the #pragma surface line to:
    alpha:fade

    Then in your surface function use this instead of the if statement you had before:
    clip(ca - _CutOff);

    If you're using shadows you'll also want to add addshadow to the #pragma surface line.
     
    Unlimited_Energy likes this.