Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Odd Transparency Problem

Discussion in 'Shaders' started by jameskyle, Mar 16, 2014.

  1. jameskyle

    jameskyle

    Joined:
    May 7, 2013
    Posts:
    37
    This is probably a very simple problem but I'm having trouble finding information on how to fix it.

    I'm trying to make a ramp lit shader with variable transparency, rim lighting and, eventually, an outline. I haven't implemented the outline as I'm having trouble setting up the transparency. Even if it's set to 1 my objects still appear with slight transparency. It's a fairly simple shader so far so perhaps someone here can take a look at it and see if there's anything obviously wrong.

    Code (csharp):
    1. Shader "Ramp Rim Outline"
    2. {
    3.     Properties
    4.     {
    5.         _ColorTint ("Texture Tint", Color) = (1,1,1,1)
    6.         _MainTex ("Texture", 2D) = "white" {}
    7.         _AlphaTex ("Alpha Map", 2D) = "white" {}
    8.         _Ramp ("Shader Ramp", 2D) = "gray" {}
    9.         _BumpTex ("Normal Map", 2D) = "bump" {}
    10.         _RimColor ("Rim Colour", Color) = (1,1,1,1)
    11.         _RimPower ("Rim Power", Range(0.5, 8.0)) = 3.0
    12.     }
    13.    
    14.     SubShader
    15.     {
    16.         Tags
    17.         {
    18.             "Queue"="Transparent"
    19.             "RenderType"="Opaque"
    20.         }
    21.        
    22.         CGPROGRAM
    23.         #pragma surface surf Ramp alpha
    24.        
    25.        
    26.         struct Input {
    27.             float2 uv_MainTex;
    28.             float2 uv_AlphaTex;
    29.             float2 uv_BumpTex;
    30.             float3 viewDir;
    31.         };
    32.        
    33.         float4 _ColorTint;
    34.         sampler2D _MainTex;
    35.         sampler2D _AlphaTex;
    36.         sampler2D _Ramp;
    37.         sampler2D _BumpTex;
    38.         float4 _RimColor;
    39.         float _RimPower;       
    40.  
    41.         // Custom lighting model...
    42.         half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten)
    43.         {
    44.             half NdotL = dot (s.Normal, lightDir);
    45.             half diff = NdotL * 0.5 + 0.5;
    46.             half3 ramp = tex2D (_Ramp, float2(diff,diff)).rgb;
    47.             half4 c;
    48.            
    49.             c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
    50.             c.a = s.Alpha;
    51.             return c;
    52.         }
    53.      
    54.        
    55.                
    56.         void surf (Input IN, inout SurfaceOutput o)
    57.         {
    58.             o.Albedo    = tex2D(_MainTex, IN.uv_MainTex).rgb * _ColorTint.rgb;
    59.             o.Alpha     = tex2D(_AlphaTex, IN.uv_AlphaTex).a;
    60.             o.Normal    = UnpackNormal(tex2D(_BumpTex, IN.uv_BumpTex));
    61.             half rim = 1 - saturate(dot(normalize(IN.viewDir), o.Normal));
    62.             o.Emission  = _RimColor.rgb * pow(rim, _RimPower);
    63.         }
    64.        
    65.         ENDCG
    66.     }
    67.     FallBack "Diffuse"
    68. }
    69.  
    EDIT: A few images of the problem. These are from the more simple transparency shader I added a few posts down but the problem is the same in the code above - a slight transparency that I can't seem to get rid of.

    You can see the blocked parts of the donut, even at alpha = 1.
    $1.PNG

    The image is just a two-tone junk texture, but the problem is the same with other textures also.
    $2.PNG
     
    Last edited: Mar 17, 2014
  2. jameskyle

    jameskyle

    Joined:
    May 7, 2013
    Posts:
    37
    Experimenting, comparing this to my previous, working shaders I see the issue related to the use of the alpha tag in the #pragma section.

    Also, changing it from ramp to diffuse results in the same problem so I'm assuming it's nothing to do with the ramp.
     
  3. jameskyle

    jameskyle

    Joined:
    May 7, 2013
    Posts:
    37
    Code (csharp):
    1. Tags
    2.     {
    3.         "Queue"="Transparent"
    4.         "RenderType"="Transparent"
    5.     }
    6.    
    Changing RenderType from Opaque to Transparent did nothing. I can't see the issue. >_<
     
  4. jameskyle

    jameskyle

    Joined:
    May 7, 2013
    Posts:
    37
    Seeking to simplify this I've found I have the same problem with even very simple shaders. This has the same slight transparency problem as the one in my first post, despite having much less going on. I'd hoped that by removing all the extra stuff - normal maps, rim lighting and such - I'd have a shader that worked. Sadly it seems not.

    Code (csharp):
    1. Shader "Diffuse Colour Transparency Test"
    2. {
    3.     Properties
    4.     {
    5.         _ColorTint ("Texture Tint", Color) = (1,1,1,1)
    6.         _MainTex ("Texture", 2D) = "white" {}
    7.     }
    8.    
    9.     SubShader
    10.     {
    11.         Tags
    12.         {
    13.             "Queue"="Transparent"
    14.             "RenderType"="Transparent"
    15.         }
    16.                
    17.         CGPROGRAM
    18.         #pragma surface surf Lambert alpha
    19.        
    20.         // Custom lighting model...
    21.        
    22.         struct Input {
    23.             float2 uv_MainTex;
    24.         };
    25.        
    26.         float4 _ColorTint;
    27.         sampler2D _MainTex;
    28.                
    29.         void surf (Input IN, inout SurfaceOutput o)
    30.         {
    31.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _ColorTint;
    32.            
    33.             o.Albedo    = c.rgb;
    34.             o.Alpha     = c.a;
    35.         }
    36.        
    37.         ENDCG
    38.     }
    39.     FallBack "Diffuse"
    40. }
    41.  
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Transparent objects need to be drawn back-to-front for blending to appear correct. Although Unity sorts transparent objects by distance, it doesn't sort triangles or fragments, so there is no guarantee that your model will be drawn back-to-front.

    A common way of dealing with this issue is called Z-priming, which is when you draw an initial pass just to the Z buffer, and then draw your object. This prevents all but the front-most surfaces from being drawn. Here is an old shader that uses this technique, although the important part (The Colormask 0 pass) can be added to almost any shader for the same effect.
     
    anicecompany likes this.
  6. jameskyle

    jameskyle

    Joined:
    May 7, 2013
    Posts:
    37
    Brilliant! That did the trick. I'm quite sure I'd never have figured that out any time soon. Much thanks!