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

Mask shader that uses texture coordinates from .uv2

Discussion in 'Shaders' started by BenZed, Jan 18, 2015.

  1. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Hello everyone.

    I've got a request for a custom shader, if any of you are willing.

    I'm proficient with C#, but shader language is complete greek to me. I've done some searching to find the particular functionality that I'm looking for, but I haven't been able to figure out how to combine what I've found into a single shader.

    I suppose I COULD go and learn all about shaders and how to write them, but I thought I'd ask here first!

    I would like a single material, with two textures. I would like the material to use texture coordinates from two different sets of uvs. In this case, uv and uv2, in the filters mesh instance. Here is a shader I've found that can do that:

    Code (Shader):
    1. Shader "Custom/twotex" {
    2. Properties {
    3.     _MainTex ("Base (RGB)", 2D) = "white" {}
    4.     _AoTex ("AO (RGB)", 2D) = "white" {}
    5.  
    6. }
    7. SubShader {
    8.     Tags { "RenderType"="Opaque" }
    9.     LOD 200
    10.  
    11.     CGPROGRAM
    12.     #pragma surface surf Lambert alpha
    13.  
    14.     sampler2D _MainTex;
    15.     sampler2D _AoTex;
    16.  
    17.  
    18.     struct Input {
    19.         float2 uv_MainTex : TEXCOORD0;
    20.         float2 uv2_AoTex : TEXCOORD1;
    21.     };
    22.  
    23.     void surf (Input IN, inout SurfaceOutput o) {
    24.         half4 c = tex2D (_MainTex, IN.uv_MainTex.xy);
    25.         half4 ao = tex2D (_AoTex, IN.uv2_AoTex.xy);
    26.         o.Albedo = c.rgb * ao.rgb;
    27.         o.Alpha = c.a;
    28.     }
    29.     ENDCG
    30. }
    31. FallBack "Diffuse"
    32. }
    I realize that uv2 is intended to be used for light maps. This particular game takes place in space, there are no static meshes, and nothing that's going to be baked into lightmaps, so I'm happy to use their uv coordinates for this reason.

    Secondly, I would like the SECOND texture (uv2) to mask the first. Anything transparent in texture 2 should be transparent in texture 1.

    Here is a shader I've found that allows me to do that:


    Code (Shader):
    1. Shader "MaskedTexture"
    2. {
    3.    Properties
    4.    {
    5.       _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    6.       _Mask ("Culling Mask", 2D) = "white" {}
    7.       _Cutoff ("Alpha cutoff", Range (0,1)) = 0.1
    8.    }
    9.    SubShader
    10.    {
    11.       Tags {"Queue"="Transparent" }
    12.       Lighting Off
    13.       ZWrite Off
    14.       Blend SrcAlpha OneMinusSrcAlpha
    15.       AlphaTest GEqual [_Cutoff]
    16.       Pass
    17.       {
    18.          SetTexture [_Mask] {combine texture}
    19.          SetTexture [_MainTex] {combine texture, previous * texture}
    20.       }
    21.    }
    22. }
    What would the combined shader look like? Thanks in advance!



    EDIT:

    Thanks again to @jvo3dc, who helped solve this problem. Working shader:


    Code (Shader):
    1.    Shader "Transparent/UV2Mask" {
    2.  
    3.         Properties {
    4.             _MainTex ("Base (RGB)", 2D) = "white" {}
    5.             _MaskTex ("Mask (RGB)", 2D) = "white" {}
    6.  
    7.         }
    8.      
    9.         SubShader {
    10.             Tags {"Queue"="Transparent" }
    11.             LOD 200
    12.  
    13.             CGPROGRAM
    14.             #pragma surface surf Lambert alpha
    15.  
    16.             sampler2D _MainTex;
    17.             sampler2D _MaskTex;
    18.  
    19.  
    20.             struct Input {
    21.                 float2 uv_MainTex : TEXCOORD0;
    22.                 float2 uv2_MaskTex :   TEXCOORD1;
    23.             };
    24.  
    25.             void surf (Input IN, inout SurfaceOutput surface) {
    26.                 half4 col = tex2D (_MainTex, IN.uv_MainTex.xy);
    27.                 half4 mask = tex2D (_MaskTex, IN.uv2_MaskTex.xy);
    28.                 surface.Albedo = col.rgb;
    29.                 surface.Alpha = mask.a;
    30.             }
    31.             ENDCG
    32.         }
    33.         FallBack "Diffuse"
    34.     }
     
    Last edited: Jan 21, 2015
  2. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
  3. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Like the first shader, but then:
    Code (csharp):
    1.  
    2. o.Albedo = c.rgb;
    3. o.Alpha = c.a * ao.a;
    4.  
    instead of:
    Code (csharp):
    1.  
    2. o.Albedo = c.rgb * ao.rgb;
    3. o.Alpha = c.a;
    4.  
     
  4. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Thanks @jvo3dc , that comment was all it took to push me in the right direction. I had to do a little bit of fiddling to make it work, but I ultimatly ended up with this shader, which worked as intended!

    EDIT: See original post for working shader.
     
    Last edited: Jan 21, 2015
  5. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    That works, but this multiplication is unneeded:
    Code (csharp):
    1. surface.Albedo = col.rbg * mask.rgb;
    Can just be:
    Code (csharp):
    1. surface.Albedo = col.rbg;
     
  6. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Well, I'm using a luma alpha map. It doesnt make sense to me, but if i dont multiply the rbg, i can see black where transparency should be. Maybe something to do with the tags at the top of the shader? I dunno.
     
  7. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    That doesn't really make sense indeed. I did see you're missing the alpha tag in:
    Code (csharp):
    1. #pragma surface surf Lambert alpha
     
  8. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Yup, that alpha tag is what made the difference. Also, I think I was making changes to the mask image without applying them in the inspector. Thanks again!

    Original post updated with working shader.