Search Unity

Simple Unlit Transparent shader with 2 UV sets

Discussion in 'Shaders' started by TWaanders, Jan 6, 2017.

  1. TWaanders

    TWaanders

    Joined:
    Mar 27, 2013
    Posts:
    46
    I have very little experience with shader programming and I could use some help with getting the following shader to work.

    What I'm trying to get is the following:

    - Unlit transparent shader using 2 textures, each for one UV set.
    - The second UV set is has a texture which determines the transparency (like an alpha texture).
    - The reason I'm not using the alpha channel of the first texture is that the alpha texture should use the 2nd UV set instead of the first.

    I managed to get the 2 textures loaded, each using a different UV set. The problem, however, is that I cannot figure out how to combine them so that the black color of the second texture becomes transparent.

    Texture input:

    First texture (UVset 1)

    Second texture (UVset 2)

    First texture + second texture (everything in BLACK should be transparent)...

    Here's the slightly modified shader code:
    Code (csharp):
    1. Shader "Kitten/Unlit/UnlitKitten"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Texture", 2D) = "white" {}
    6.     _AlphaTex("Alpha", 2D) = "white" {}
    7.     }
    8.         SubShader
    9.     {
    10.         Tags{ "RenderType" = "Transparent" }
    11.         LOD 100
    12.  
    13.         Pass
    14.     {
    15.         CGPROGRAM
    16. #pragma vertex vert
    17. #pragma fragment frag
    18.         // make fog work
    19. #pragma multi_compile_fog
    20.  
    21. #include "UnityCG.cginc"
    22.  
    23.     struct appdata
    24.     {
    25.         float4 vertex : POSITION;
    26.         float2 uv : TEXCOORD0;
    27.         float2 uv2 : TEXCOORD1;
    28.     };
    29.  
    30.     struct v2f
    31.     {
    32.         float2 uv : TEXCOORD0;
    33.         float2 uv2 : TEXCOORD1;
    34.         UNITY_FOG_COORDS(1)
    35.             float4 vertex : SV_POSITION;
    36.     };
    37.  
    38.     sampler2D _MainTex;
    39.     sampler2D _AlphaTex;
    40.     float4 _MainTex_ST;
    41.     float4 _AlphaTex_ST;
    42.  
    43.  
    44.     v2f vert(appdata v)
    45.     {
    46.         v2f o;
    47.         o.vertex = UnityObjectToClipPos(v.vertex);
    48.         o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    49.         o.uv2 = TRANSFORM_TEX(v.uv2, _AlphaTex);
    50.         UNITY_TRANSFER_FOG(o,o.vertex);
    51.         return o;
    52.     }
    53.  
    54.     fixed4 frag(v2f i) : SV_Target
    55.     {
    56.     // sample the texture
    57.     fixed4 col = tex2D(_MainTex, i.uv);
    58.     fixed4 alpha = tex2D(_AlphaTex, i.uv2);
    59.     fixed4 combined = col * alpha;
    60.     col.rgb = combined;
    61.  
    62.     return col;
    63.  
    64.  
    65.     }
    66.         ENDCG
    67.     }
    68.     }
    69. }
    70.  
     
    Last edited: Jan 6, 2017
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    6,994
    That's only part of what's needed to make a shader render as transparent, in some ways that's actually the least important part. You also need to set the Blend, ZWrite, and the Queue. Also your textures are both RGB textures with no alpha, and by default textures have 100% full alpha (opaque), and you never assign an alpha value. You in fact throw away the alpha channel of your alpha texture if it had alpha by using col.rgb = combined;

    Around where you have Tags you'll want this:
    Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    Blend SrcAlpha OneMinusSrcAlpha
    ZWrite Off


    And then in the shader code itself you want this:
    fixed4 col = tex2D(_MainTex, i.uv);
    fixed4 alpha = tex2D(_AlphaTex, i.uv2);
    col.a *= alpha.g;
    return col;


    That uses the green channel of your "alpha" texture as the alpha or transparency output by the shader.

    However once you do all of this you'll find your cat looks kind of funny if this shader is used on the entire body of the cat, and that's because of ZWrite Off. If you remove that line or set it to ZWrite On you'll also get a different funny result. I've written about this a few times here on the forum if you want to know why.
     
  3. TWaanders

    TWaanders

    Joined:
    Mar 27, 2013
    Posts:
    46
    Thanks for the help! That did exactly what I wanted. I assigned a non-transparent shader to the body, to counter the sorting issue. Works great.

    Again, thanks for helping me out here :)