Search Unity

How to combine 2 Shader into 1? Multiply Blend + Transparent Alpha Mask

Discussion in 'Shaders' started by black-io, Apr 11, 2017.

  1. black-io

    black-io

    Joined:
    Apr 10, 2014
    Posts:
    4
    Hello friend. I need help making a alpha mask shader with multiply blend to the background.
    I tired to combine them together by using PASS block, but not success. Would you please give me an idea how to make it?

    I'd really appreciate your help! :)
    Thank you very much!

    Transparent Alpha Mask Shader
    Code (CSharp):
    1. // Unlit alpha-blended shader.
    2. // - no lighting
    3. // - no lightmap support
    4. // - no per-material color
    5. Shader "Unlit/TransparentAlphaMask" {
    6. Properties {
    7.     _MainTex ("Base (RGB)", 2D) = "white" {}
    8.     _AlphaTex ("Alpha mask (R)", 2D) = "white" {}
    9. }
    10. SubShader {
    11.     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    12.     LOD 100
    13.     Blend SrcAlpha OneMinusSrcAlpha
    14.     Pass {
    15.         CGPROGRAM
    16.             #pragma vertex vert
    17.             #pragma fragment frag
    18.        
    19.             #include "UnityCG.cginc"
    20.        
    21.             struct appdata_t {
    22.                 float4 vertex : POSITION;
    23.                 float2 texcoord : TEXCOORD0;
    24.             };
    25.             struct v2f {
    26.                 float4 vertex : SV_POSITION;
    27.                 half2 texcoord : TEXCOORD0;
    28.             };
    29.             sampler2D _MainTex;
    30.             sampler2D _AlphaTex;
    31.        
    32.             float4 _MainTex_ST;
    33.        
    34.             v2f vert (appdata_t v)
    35.             {
    36.                 v2f o;
    37.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    38.                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
    39.                 return o;
    40.             }
    41.        
    42.             fixed4 frag (v2f i) : SV_Target
    43.             {
    44.                 fixed4 col = tex2D(_MainTex, i.texcoord);
    45.                 fixed4 col2 = tex2D(_AlphaTex, i.texcoord);
    46.            
    47.                 return fixed4(col.r, col.g, col.b, col2.r);
    48.             }
    49.         ENDCG
    50.     }
    51. }
    52. }
    Multiply Blend Shader
    Code (CSharp):
    1. Shader "_My/Multiply"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue"="Transparent"
    15.             "IgnoreProjector"="True"
    16.             "RenderType"="Transparent"
    17.             // "PreviewType"="Plane"
    18.             // "CanUseSpriteAtlas"="True"
    19.         }
    20.  
    21.         Pass
    22.         {
    23.             Cull Off
    24.             Lighting Off
    25.             ZWrite Off
    26.             Fog { Color (1,1,1,1) }
    27.             Blend Zero SrcColor
    28.             //AlphaTest Greater .01
    29.             ColorMask RGB
    30.             CGPROGRAM
    31.                 #pragma vertex vert
    32.                 #pragma fragment frag
    33.                 #pragma multi_compile DUMMY PIXELSNAP_ON
    34.                 #include "UnityCG.cginc"
    35.  
    36.                 struct appdata_t
    37.                 {
    38.                     float4 vertex   : POSITION;
    39.                     float4 color    : COLOR;
    40.                     float2 texcoord : TEXCOORD0;
    41.                 };
    42.  
    43.                 struct v2f
    44.                 {
    45.                     float4 vertex   : SV_POSITION;
    46.                     fixed4 color    : COLOR;
    47.                     half2 texcoord  : TEXCOORD0;
    48.                 };
    49.  
    50.                 fixed4 _Color;
    51.  
    52.                 v2f vert(appdata_t IN)
    53.                 {
    54.                     v2f OUT;
    55.                     OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    56.                     OUT.texcoord = IN.texcoord;
    57.                     OUT.color = IN.color * _Color;
    58.                     #ifdef PIXELSNAP_ON
    59.                     OUT.vertex = UnityPixelSnap (OUT.vertex);
    60.                     #endif
    61.  
    62.                     return OUT;
    63.                 }
    64.  
    65.                 sampler2D _MainTex;
    66.  
    67.                 fixed4 frag(v2f IN) : COLOR
    68.                 {
    69.                     half4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
    70.                     return lerp(half4(1,1,1,1), prev, prev.a);
    71.                 }
    72.             ENDCG
    73.         }
    74.  
    75.     }
    76. }
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    It should be fine to combine those by having two pass blocks. Do make sure the blend settings are inside the pass block for both passes. Since the multiply pass is in the background, this should be the first pass.
     
  3. black-io

    black-io

    Joined:
    Apr 10, 2014
    Posts:
    4
    Hello, thanks for reply. I tired again, but the result is unexpected... the multiply bend effect is applied to the cutout area only, result as follow:


    I want to make the cat image masked by the star shape and multiple to the sky layer.


    This is my combined shader. How to correct it?
    Code (CSharp):
    1. Shader "_My/AlphaMaskMultiply" {
    2. Properties {
    3.     _MainTex ("Photo PNG", 2D) = "white" {}
    4.     _AlphaTex ("Photo Mask", 2D) = "white" {}
    5.     _Color ("Tint Color", Color) = (1,1,1,1)
    6. }
    7.  
    8. SubShader {
    9.     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    10.     LOD 100
    11.  
    12.     ZWrite Off
    13.  
    14.     Pass
    15.     {
    16.         // Cull Off
    17.         // Lighting Off
    18.         // ZWrite Off
    19.         // Fog { Color (1,1,1,1) }
    20.         Blend Zero SrcColor
    21.         //AlphaTest Greater .01
    22.         // ColorMask RGB
    23.         CGPROGRAM
    24.             #pragma vertex vert
    25.             #pragma fragment frag
    26.             // #pragma multi_compile DUMMY PIXELSNAP_ON
    27.             // #include "UnityCG.cginc"
    28.  
    29.             struct appdata_t
    30.             {
    31.                 float4 vertex   : POSITION;
    32.                 float4 color    : COLOR;
    33.                 float2 texcoord : TEXCOORD0;
    34.             };
    35.  
    36.             struct v2f
    37.             {
    38.                 float4 vertex   : SV_POSITION;
    39.                 fixed4 color    : COLOR;
    40.                 half2 texcoord  : TEXCOORD0;
    41.             };
    42.  
    43.             fixed4 _Color;
    44.  
    45.             v2f vert(appdata_t IN)
    46.             {
    47.                 v2f OUT;
    48.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    49.                 OUT.texcoord = IN.texcoord;
    50.                 OUT.color = IN.color * _Color;
    51.                 #ifdef PIXELSNAP_ON
    52.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    53.                 #endif
    54.  
    55.                 return OUT;
    56.             }
    57.  
    58.             sampler2D _MainTex;
    59.  
    60.             fixed4 frag(v2f IN) : COLOR
    61.             {
    62.                 half4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
    63.                 return lerp(half4(1,1,1,1), prev, prev.a);
    64.             }
    65.         ENDCG
    66.  
    67.     }
    68.  
    69.     Pass {
    70.         Blend SrcAlpha OneMinusSrcAlpha
    71.         CGPROGRAM
    72.             #pragma vertex vert
    73.             #pragma fragment frag
    74.  
    75.             #include "UnityCG.cginc"
    76.  
    77.             struct appdata_t {
    78.                 float4 vertex : POSITION;
    79.                 float2 texcoord : TEXCOORD0;
    80.             };
    81.  
    82.             struct v2f {
    83.                 float4 vertex : SV_POSITION;
    84.                 half2 texcoord : TEXCOORD0;
    85.             };
    86.  
    87.             sampler2D _MainTex;
    88.             sampler2D _AlphaTex;
    89.  
    90.             float4 _MainTex_ST;
    91.  
    92.             v2f vert (appdata_t v)
    93.             {
    94.                 v2f o;
    95.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    96.                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
    97.                 return o;
    98.             }
    99.  
    100.             fixed4 frag (v2f i) : SV_Target
    101.             {
    102.                 fixed4 col = tex2D(_MainTex, i.texcoord);
    103.                 fixed4 col2 = tex2D(_AlphaTex, i.texcoord);
    104.                 return fixed4(col.r, col.g, col.b, col2.r);
    105.             }
    106.  
    107.         ENDCG
    108.     }
    109. }
    110.  
    111. }
     
  4. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Ah, that's actually even easier and can be done in one pass. Just take the multiply shader and adjust it like this:
    Code (csharp):
    1.  
    2. fixed4 frag(v2f IN) : COLOR
    3. {
    4.    fixed4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
    5.    fixed col2 = tex2D(_AlphaTex, i.texcoord).r;
    6.    //prev = lerp(fixed4(1,1,1,1), prev, prev.a); // I don't think this line is actually needed, but it is in your source
    7.    return lerp(fixed4(1,1,1,1), prev, col2);
    8. }
    9.  
    So remove the second pass and just merge the cutout into the first pass. (Instead of using alpha, you can just blend to white, since multiplying with white does nothing.)
     
    black-io likes this.
  5. black-io

    black-io

    Joined:
    Apr 10, 2014
    Posts:
    4
    I made it. Thank you all. :D

    Code (CSharp):
    1. Shader "_My/MultiplyAlphaMask" {
    2. Properties {
    3.     _MainTex ("Photo PNG", 2D) = "white" {}
    4.     _AlphaTex ("Photo Mask", 2D) = "white" {}
    5.     _Color ("Tint Color", Color) = (1,1,1,1)
    6. }
    7.  
    8. SubShader {
    9.     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"}
    10.     LOD 100
    11.  
    12.     ZWrite Off
    13.  
    14.     Pass
    15.     {
    16.         Cull Off
    17.         Lighting Off
    18.         ZWrite Off
    19.         // Fog { Color (1,1,1,1) }
    20.         Blend Zero SrcColor
    21.         CGPROGRAM
    22.             #pragma vertex vert
    23.             #pragma fragment frag
    24.             struct appdata_t
    25.             {
    26.                 float4 vertex   : POSITION;
    27.                 float4 color    : COLOR;
    28.                 float2 texcoord : TEXCOORD0;
    29.             };
    30.  
    31.             struct v2f
    32.             {
    33.                 float4 vertex   : SV_POSITION;
    34.                 fixed4 color    : COLOR;
    35.                 half2 texcoord  : TEXCOORD0;
    36.             };
    37.  
    38.             fixed4 _Color;
    39.  
    40.             v2f vert(appdata_t IN)
    41.             {
    42.                 v2f OUT;
    43.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    44.                 OUT.texcoord = IN.texcoord;
    45.                 OUT.color = IN.color * _Color;
    46.                 #ifdef PIXELSNAP_ON
    47.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    48.                 #endif
    49.  
    50.                 return OUT;
    51.             }
    52.  
    53.             sampler2D _MainTex;
    54.             sampler2D _AlphaTex;
    55.  
    56.             fixed4 frag(v2f IN) : COLOR
    57.             {
    58.                fixed4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
    59.                fixed col2 = tex2D(_AlphaTex, IN.texcoord).r;
    60.                return lerp(fixed4(1,1,1,1), prev, col2);
    61.             }
    62.         ENDCG
    63.  
    64.     }
    65. }
    66.  
    67. }